openapi: 3.0.3
info:
  title: AeroFind API
  version: "1.0.5"
  description: |
    AeroFind baggage recovery and Property Irregularity Report (PIR) API.

    All endpoints currently dispatch through `POST /api.php` using an `action`
    field (form-encoded or JSON). This document is a v1 transitional spec; a
    future revision will move actions to RESTful paths under `/api/v2/`.
  contact:
    name: AeroFind
servers:
  - url: ..
    description: Same-origin (relative)

tags:
  - name: Reports
    description: Property Irregularity Reports (PIR)
  - name: Tasks
    description: Delivery and operational tasks
  - name: Users
    description: Staff user management
  - name: LostFound
    description: Lost & Found items
  - name: WorldTracer
    description: SITA WorldTracer bridge (Phase 1 — stub)
  - name: Config
    description: Runtime configuration

paths:
  /api.php:
    post:
      summary: Action dispatcher (legacy)
      description: |
        Routes all v1 API calls. The `action` field selects the operation.
        See the `Action` enum for supported values.
      tags: [Reports, Tasks, Users, LostFound, WorldTracer, Config]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ActionEnvelope'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/ActionEnvelope'
      responses:
        '200':
          description: Operation result. Shape depends on `action`.
          content:
            application/json:
              schema:
                type: object
        '400':
          description: Bad request (missing/invalid params).
        '403':
          description: Forbidden — RBAC permission denied.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ForbiddenError'

components:
  securitySchemes:
    sessionCookie:
      type: apiKey
      in: cookie
      name: PHPSESSID
    systemApiKey:
      type: apiKey
      in: header
      name: X-API-KEY

  schemas:
    ActionEnvelope:
      type: object
      required: [action]
      properties:
        action:
          $ref: '#/components/schemas/Action'
      additionalProperties: true

    Action:
      type: string
      enum:
        - submitReport
        - updateStatus
        - updateWT
        - deleteReport
        - generatePDF
        - getConfig
        - getAirlines
        - getStaffEmails
        - saveStaffEmails
        - testSMTP
        - getUsers
        - addUser
        - deleteUser
        - updateUserRole
        - getTasks
        - createTask
        - deleteTask
        - updateTaskStatus
        - addTaskMessage
        - getTaskMessages
        - addAirline
        - deleteAirline
        - setAirlineConfig
        - getWorldTracerConfig
        - setWorldTracerKey
        - testWorldTracerConnection
        - submitToWorldTracer
        - addLostItem
        - trackLostItem
        - trackBagReport
        - getLostItems
        - getPublicFoundItems
        - getFoundItems
        - addFoundItem
        - updateLostItemStatus
        - matchItems
        - unmatchItems
        - notifyPassenger
        - deleteLostItem

    Report:
      type: object
      properties:
        id: { type: integer }
        date: { type: string, format: date-time }
        bag_tags: { type: string }
        airline: { type: string }
        airline_code: { type: string }
        full_name: { type: string }
        email: { type: string, format: email }
        phone: { type: string }
        report_type: { type: string, enum: [DAMAGED, DELAYED, MISSING, PILFERED, FOUND] }
        status: { type: string, enum: [URGENT, "REVIEW REQUIRED", PENDING, CLOSED] }
        wt_ref: { type: string, description: "WorldTracer reference (5-char file ID)" }
        token: { type: string }
        short_token: { type: string }
        pod_token: { type: string }

    Task:
      type: object
      properties:
        id: { type: integer }
        report_id: { type: integer }
        assignee: { type: string }
        status: { type: string, enum: [OPEN, IN_PROGRESS, DONE, CANCELLED] }
        created_at: { type: string, format: date-time }

    User:
      type: object
      properties:
        id: { type: integer }
        username: { type: string }
        role:
          type: string
          enum: [admin, supervisor, staff, courier]
        created_at: { type: string, format: date-time }

    LostItem:
      type: object
      properties:
        id: { type: integer }
        category: { type: string }
        description: { type: string }
        color: { type: string }
        brand: { type: string }
        location_found: { type: string }
        status: { type: string }

    AuditLogEntry:
      type: object
      description: |
        Append-only audit log entry. The `chain_hash` field links rows; tampering
        with any historical row breaks the chain at that row.
      properties:
        id: { type: integer }
        ts: { type: string, format: date-time }
        actor: { type: string }
        actor_role: { type: string }
        event: { type: string, example: "pir.create" }
        payload: { type: string, description: "Canonical JSON payload" }
        ip: { type: string }
        prev_hash: { type: string }
        row_hmac: { type: string }
        chain_hash: { type: string }

    ForbiddenError:
      type: object
      properties:
        error:
          type: string
          example: forbidden
        permission:
          type: string
          example: pir.close

security:
  - sessionCookie: []
  - systemApiKey: []
