openapi: 3.1.0
info:
  # Do not change the title, if the title changes, the import paths will be broken
  title: Api
  version: 0.1.0
  description: ITS Logy AI Logistics Platform API
servers:
  - url: /api
    description: Base API path
tags:
  - name: health
    description: Health operations
  - name: profiles
    description: User profiles
  - name: orders
    description: Shipment orders
  - name: bids
    description: Bidding system
  - name: wallets
    description: Multi-wallet & escrow
  - name: cargo
    description: AI cargo inspection
  - name: pricing
    description: AI dynamic pricing
  - name: epod
    description: Electronic proof of delivery
  - name: disputes
    description: Dispute management
  - name: invoices
    description: ZATCA e-invoicing
  - name: contracts
    description: Smart contracts
  - name: compliance
    description: WASL & BAYAN compliance
  - name: analytics
    description: Analytics & forecasting
  - name: insights
    description: AI-powered Smart Insights

paths:
  /healthz:
    get:
      operationId: healthCheck
      tags: [health]
      summary: Health check
      responses:
        "200":
          description: Healthy
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HealthStatus"

  /profiles:
    get:
      operationId: listProfiles
      tags: [profiles]
      summary: List profiles
      parameters:
        - name: role
          in: query
          schema:
            type: string
            enum: [shipper, broker, driver]
      responses:
        "200":
          description: List of profiles
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Profile"
    post:
      operationId: createProfile
      tags: [profiles]
      summary: Create or update profile
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateProfileBody"
      responses:
        "201":
          description: Created profile
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Profile"

  /profiles/me:
    get:
      operationId: getMyProfile
      tags: [profiles]
      summary: Get current user profile
      responses:
        "200":
          description: My profile
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Profile"
        "404":
          description: Profile not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /profiles/{profileId}:
    get:
      operationId: getProfile
      tags: [profiles]
      summary: Get profile by ID
      parameters:
        - name: profileId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Profile
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Profile"
        "404":
          description: Not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /profiles/{profileId}/trust-score:
    patch:
      operationId: updateTrustScore
      tags: [profiles]
      summary: Update trust score for a profile (admin only)
      parameters:
        - name: profileId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [trustScore]
              properties:
                trustScore:
                  type: number
                  minimum: 0
                  maximum: 5
      responses:
        "200":
          description: Updated profile
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Profile"
        "400":
          description: Invalid trust score value
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "403":
          description: Forbidden — admin only
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"
        "404":
          description: Profile not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /orders:
    get:
      operationId: listOrders
      tags: [orders]
      summary: List orders
      parameters:
        - name: status
          in: query
          schema:
            type: string
            enum: [pending, bidding, assigned, in_transit, delivered, cancelled]
        - name: role
          in: query
          schema:
            type: string
            enum: [shipper, broker, driver]
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
      responses:
        "200":
          description: List of orders
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Order"
    post:
      operationId: createOrder
      tags: [orders]
      summary: Create shipment order
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateOrderBody"
      responses:
        "201":
          description: Created order
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Order"

  /orders/{orderId}:
    get:
      operationId: getOrder
      tags: [orders]
      summary: Get order by ID
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Order details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Order"
        "404":
          description: Not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /orders/{orderId}/status:
    patch:
      operationId: updateOrderStatus
      tags: [orders]
      summary: Update order status
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateOrderStatusBody"
      responses:
        "200":
          description: Updated order
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Order"

  /orders/{orderId}/bids:
    get:
      operationId: listBids
      tags: [bids]
      summary: List bids for an order
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: List of bids
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Bid"
    post:
      operationId: createBid
      tags: [bids]
      summary: Submit a bid on an order
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateBidBody"
      responses:
        "201":
          description: Created bid
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Bid"

  /bids/{bidId}:
    patch:
      operationId: updateBid
      tags: [bids]
      summary: Accept or reject a bid
      parameters:
        - name: bidId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateBidBody"
      responses:
        "200":
          description: Updated bid
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Bid"

  /wallets/me:
    get:
      operationId: getMyWallet
      tags: [wallets]
      summary: Get current user wallet
      responses:
        "200":
          description: Wallet details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Wallet"

  /wallets/deposit:
    post:
      operationId: depositFunds
      tags: [wallets]
      summary: Deposit funds to wallet
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DepositBody"
      responses:
        "200":
          description: Updated wallet
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Wallet"

  /wallets/transactions:
    get:
      operationId: listTransactions
      tags: [wallets]
      summary: List wallet transactions
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
      responses:
        "200":
          description: List of transactions
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Transaction"

  /orders/{orderId}/escrow-hold:
    post:
      operationId: escrowHold
      tags: [wallets]
      summary: Hold funds in escrow for order
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Escrow held
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Wallet"

  /orders/{orderId}/escrow-release:
    post:
      operationId: escrowRelease
      tags: [wallets]
      summary: Release escrow on order completion
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Escrow released
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Wallet"

  /cargo-inspections:
    post:
      operationId: createCargoInspection
      tags: [cargo]
      summary: Analyze cargo image with AI
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CargoInspectionBody"
      responses:
        "201":
          description: Inspection result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CargoInspection"

  /orders/{orderId}/inspection:
    get:
      operationId: getCargoInspection
      tags: [cargo]
      summary: Get cargo inspection for order
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Inspection record
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CargoInspection"
        "404":
          description: Not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /pricing/calculate:
    post:
      operationId: calculatePrice
      tags: [pricing]
      summary: Calculate dynamic shipment price
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PricingRequestBody"
      responses:
        "200":
          description: Pricing result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PricingResult"

  /epod:
    post:
      operationId: createEpod
      tags: [epod]
      summary: Submit electronic proof of delivery
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateEpodBody"
      responses:
        "201":
          description: e-POD created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EpodRecord"

  /orders/{orderId}/epod:
    get:
      operationId: getEpod
      tags: [epod]
      summary: Get e-POD for order
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: e-POD record
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EpodRecord"
        "404":
          description: Not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /disputes:
    get:
      operationId: listDisputes
      tags: [disputes]
      summary: List disputes
      parameters:
        - name: status
          in: query
          schema:
            type: string
            enum: [open, investigating, resolved]
      responses:
        "200":
          description: List of disputes
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Dispute"
    post:
      operationId: createDispute
      tags: [disputes]
      summary: Open a dispute
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateDisputeBody"
      responses:
        "201":
          description: Dispute created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Dispute"

  /disputes/{disputeId}:
    patch:
      operationId: updateDispute
      tags: [disputes]
      summary: Update dispute status/resolution
      parameters:
        - name: disputeId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateDisputeBody"
      responses:
        "200":
          description: Updated dispute
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Dispute"

  /invoices/generate:
    post:
      operationId: generateInvoice
      tags: [invoices]
      summary: Generate ZATCA-compliant e-invoice
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GenerateInvoiceBody"
      responses:
        "201":
          description: Generated invoice
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Invoice"

  /invoices/{invoiceId}:
    get:
      operationId: getInvoice
      tags: [invoices]
      summary: Get invoice by ID
      parameters:
        - name: invoiceId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Invoice record
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Invoice"

  /invoices:
    get:
      operationId: listInvoices
      tags: [invoices]
      summary: List invoices
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 20
      responses:
        "200":
          description: List of invoices
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Invoice"

  /contracts/generate:
    post:
      operationId: generateContract
      tags: [contracts]
      summary: Generate smart contract TOS
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/GenerateContractBody"
      responses:
        "201":
          description: Generated contract
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SmartContract"

  /contracts/{contractId}/sign:
    post:
      operationId: signContract
      tags: [contracts]
      summary: Sign smart contract
      parameters:
        - name: contractId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SignContractBody"
      responses:
        "200":
          description: Signed contract
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SmartContract"

  /orders/{orderId}/contract:
    get:
      operationId: getContract
      tags: [contracts]
      summary: Get contract for order
      parameters:
        - name: orderId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Contract
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SmartContract"
        "404":
          description: Not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /compliance/wasl/verify:
    post:
      operationId: waslVerify
      tags: [compliance]
      summary: Verify WASL truck operating card (TGA placeholder)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WaslVerifyBody"
      responses:
        "200":
          description: WASL verification result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WaslVerifyResult"

  /compliance/bayan/waybill:
    post:
      operationId: bayanWaybill
      tags: [compliance]
      summary: Issue unified bill of lading via BAYAN (TGA placeholder)
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/BayanWaybillBody"
      responses:
        "200":
          description: BAYAN waybill result
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BayanWaybillResult"

  /analytics/dashboard:
    get:
      operationId: getDashboardAnalytics
      tags: [analytics]
      summary: Get dashboard summary analytics
      responses:
        "200":
          description: Dashboard analytics
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DashboardAnalytics"

  /analytics/congestion:
    get:
      operationId: getCongestionForecast
      tags: [analytics]
      summary: Get port/site congestion forecasts
      responses:
        "200":
          description: Congestion forecast data
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/CongestionForecast"

  /analytics/drivers:
    get:
      operationId: getDriverLeaderboard
      tags: [analytics]
      summary: Get driver performance leaderboard
      parameters:
        - name: limit
          in: query
          schema:
            type: integer
            default: 10
      responses:
        "200":
          description: Driver leaderboard
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/DriverStats"

  /analytics/driver/{driverId}:
    get:
      operationId: getDriverAnalytics
      tags: [analytics]
      summary: Get analytics for a specific driver
      parameters:
        - name: driverId
          in: path
          required: true
          schema:
            type: integer
      responses:
        "200":
          description: Driver analytics
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DriverStats"
        "404":
          description: Driver not found
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

  /insights/smart:
    get:
      operationId: getSmartInsights
      tags: [insights]
      summary: Get AI-powered smart insights from logistics data
      description: Analyzes shipment data and returns AI-generated strategic recommendations, top routes, average costs, and truck occupancy. Results are cached for 1 hour.
      responses:
        "200":
          description: Smart insights data
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SmartInsights"
        "500":
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ErrorResponse"

components:
  schemas:
    HealthStatus:
      type: object
      properties:
        status:
          type: string
      required:
        - status

    ErrorResponse:
      type: object
      properties:
        error:
          type: string
      required:
        - error

    Profile:
      type: object
      properties:
        id:
          type: integer
        userId:
          type: string
        role:
          type: string
          enum: [shipper, broker, driver]
        name:
          type: string
        phone:
          type: string
        companyName:
          type: string
        nationalId:
          type: string
        waslCardNumber:
          type: string
        trustScore:
          type: number
        createdAt:
          type: string
      required:
        - id
        - userId
        - role
        - name

    CreateProfileBody:
      type: object
      properties:
        role:
          type: string
          enum: [shipper, broker, driver]
        name:
          type: string
        phone:
          type: string
        companyName:
          type: string
        nationalId:
          type: string
        waslCardNumber:
          type: string
      required:
        - role
        - name

    Order:
      type: object
      properties:
        id:
          type: integer
        shipperId:
          type: integer
        brokerId:
          type: integer
        driverId:
          type: integer
        status:
          type: string
          enum: [pending, bidding, assigned, in_transit, delivered, cancelled]
        origin:
          type: string
        destination:
          type: string
        cargoType:
          type: string
        truckType:
          type: string
          enum: [flatbed, refrigerated, tanker, container, curtainsider, tipper]
        weight:
          type: number
        volume:
          type: number
        distance:
          type: number
        price:
          type: number
        projectCostCenter:
          type: string
        waybillNumber:
          type: string
        shipper:
          $ref: "#/components/schemas/Profile"
        broker:
          $ref: "#/components/schemas/Profile"
        driver:
          $ref: "#/components/schemas/Profile"
        bidsCount:
          type: integer
        createdAt:
          type: string
        deliveredAt:
          type: string
      required:
        - id
        - status
        - origin
        - destination
        - cargoType
        - truckType

    CreateOrderBody:
      type: object
      properties:
        origin:
          type: string
        destination:
          type: string
        cargoType:
          type: string
        truckType:
          type: string
          enum: [flatbed, refrigerated, tanker, container, curtainsider, tipper]
        weight:
          type: number
        volume:
          type: number
        distance:
          type: number
        price:
          type: number
        projectCostCenter:
          type: string
      required:
        - origin
        - destination
        - cargoType
        - truckType

    UpdateOrderStatusBody:
      type: object
      properties:
        status:
          type: string
          enum: [pending, bidding, assigned, in_transit, delivered, cancelled]
        driverId:
          type: integer
        brokerId:
          type: integer
      required:
        - status

    Bid:
      type: object
      properties:
        id:
          type: integer
        orderId:
          type: integer
        bidderId:
          type: integer
        bidderRole:
          type: string
          enum: [broker, driver]
        amount:
          type: number
        notes:
          type: string
        status:
          type: string
          enum: [pending, accepted, rejected]
        bidder:
          $ref: "#/components/schemas/Profile"
        createdAt:
          type: string
      required:
        - id
        - orderId
        - bidderId
        - amount
        - status

    CreateBidBody:
      type: object
      properties:
        amount:
          type: number
        notes:
          type: string
      required:
        - amount

    UpdateBidBody:
      type: object
      properties:
        status:
          type: string
          enum: [accepted, rejected]
      required:
        - status

    Wallet:
      type: object
      properties:
        id:
          type: integer
        profileId:
          type: integer
        balance:
          type: number
        escrowHeld:
          type: number
        currency:
          type: string
        updatedAt:
          type: string
      required:
        - id
        - profileId
        - balance
        - escrowHeld
        - currency

    DepositBody:
      type: object
      properties:
        amount:
          type: number
      required:
        - amount

    Transaction:
      type: object
      properties:
        id:
          type: integer
        walletId:
          type: integer
        orderId:
          type: integer
        type:
          type: string
          enum: [credit, debit, escrow_hold, escrow_release]
        amount:
          type: number
        reference:
          type: string
        createdAt:
          type: string
      required:
        - id
        - walletId
        - type
        - amount

    CargoInspection:
      type: object
      properties:
        id:
          type: integer
        orderId:
          type: integer
        imageUrl:
          type: string
        detectedDamages:
          type: array
          items:
            type: string
        suggestedTruckType:
          type: string
        confidence:
          type: number
        timestamp:
          type: string
      required:
        - id
        - imageUrl
        - suggestedTruckType

    CargoInspectionBody:
      type: object
      properties:
        orderId:
          type: integer
        imageUrl:
          type: string
        cargoType:
          type: string
      required:
        - imageUrl
        - cargoType

    PricingRequestBody:
      type: object
      properties:
        origin:
          type: string
        destination:
          type: string
        distance:
          type: number
        truckType:
          type: string
          enum: [flatbed, refrigerated, tanker, container, curtainsider, tipper]
        weight:
          type: number
        cargoType:
          type: string
      required:
        - distance
        - truckType
        - weight

    PricingResult:
      type: object
      properties:
        basePrice:
          type: number
        fuelSurcharge:
          type: number
        demandMultiplier:
          type: number
        totalPrice:
          type: number
        breakdown:
          type: object
          properties:
            distanceCost:
              type: number
            truckTypePremium:
              type: number
            weightCost:
              type: number
            fuelCost:
              type: number
            demandFactor:
              type: number
          required:
            - distanceCost
            - truckTypePremium
            - weightCost
            - fuelCost
            - demandFactor
        currency:
          type: string
      required:
        - basePrice
        - fuelSurcharge
        - demandMultiplier
        - totalPrice
        - breakdown
        - currency

    EpodRecord:
      type: object
      properties:
        id:
          type: integer
        orderId:
          type: integer
        gpsLat:
          type: number
        gpsLon:
          type: number
        signature:
          type: string
        photoUrl:
          type: string
        completedAt:
          type: string
      required:
        - id
        - orderId
        - completedAt

    CreateEpodBody:
      type: object
      properties:
        orderId:
          type: integer
        gpsLat:
          type: number
        gpsLon:
          type: number
        signature:
          type: string
        photoUrl:
          type: string
      required:
        - orderId
        - gpsLat
        - gpsLon
        - signature

    Dispute:
      type: object
      properties:
        id:
          type: integer
        orderId:
          type: integer
        raisedBy:
          type: integer
        type:
          type: string
          enum: [delay, damage, other]
        description:
          type: string
        status:
          type: string
          enum: [open, investigating, resolved]
        resolution:
          type: string
        order:
          $ref: "#/components/schemas/Order"
        raisedByProfile:
          $ref: "#/components/schemas/Profile"
        createdAt:
          type: string
      required:
        - id
        - orderId
        - type
        - description
        - status

    CreateDisputeBody:
      type: object
      properties:
        orderId:
          type: integer
        type:
          type: string
          enum: [delay, damage, other]
        description:
          type: string
      required:
        - orderId
        - type
        - description

    UpdateDisputeBody:
      type: object
      properties:
        status:
          type: string
          enum: [investigating, resolved]
        resolution:
          type: string

    Invoice:
      type: object
      properties:
        id:
          type: integer
        orderId:
          type: integer
        xmlContent:
          type: string
        pdfUrl:
          type: string
        zatcaStatus:
          type: string
          enum: [generated, submitted, cleared]
        issuedAt:
          type: string
        order:
          $ref: "#/components/schemas/Order"
      required:
        - id
        - orderId
        - zatcaStatus

    GenerateInvoiceBody:
      type: object
      properties:
        orderId:
          type: integer
      required:
        - orderId

    SmartContract:
      type: object
      properties:
        id:
          type: integer
        orderId:
          type: integer
        content:
          type: string
        signedByShipper:
          type: boolean
        signedByDriver:
          type: boolean
        createdAt:
          type: string
        order:
          $ref: "#/components/schemas/Order"
      required:
        - id
        - orderId
        - content
        - signedByShipper
        - signedByDriver

    GenerateContractBody:
      type: object
      properties:
        orderId:
          type: integer
      required:
        - orderId

    SignContractBody:
      type: object
      properties:
        role:
          type: string
          enum: [shipper, driver]
      required:
        - role

    WaslVerifyBody:
      type: object
      properties:
        driverId:
          type: integer
        waslCardNumber:
          type: string
      required:
        - waslCardNumber

    WaslVerifyResult:
      type: object
      properties:
        verified:
          type: boolean
        waslCardNumber:
          type: string
        status:
          type: string
        message:
          type: string
      required:
        - verified
        - status

    BayanWaybillBody:
      type: object
      properties:
        orderId:
          type: integer
      required:
        - orderId

    BayanWaybillResult:
      type: object
      properties:
        waybillNumber:
          type: string
        status:
          type: string
        message:
          type: string
        issuedAt:
          type: string
      required:
        - waybillNumber
        - status

    DashboardAnalytics:
      type: object
      properties:
        totalOrders:
          type: integer
        activeOrders:
          type: integer
        completedOrders:
          type: integer
        totalRevenue:
          type: number
        pendingBids:
          type: integer
        activeDrivers:
          type: integer
        openDisputes:
          type: integer
        recentOrders:
          type: array
          items:
            $ref: "#/components/schemas/Order"
        ordersByStatus:
          type: object
          additionalProperties:
            type: integer
        revenueByMonth:
          type: array
          items:
            type: object
            properties:
              month:
                type: string
              revenue:
                type: number
            required:
              - month
              - revenue
      required:
        - totalOrders
        - activeOrders
        - completedOrders
        - totalRevenue
        - pendingBids
        - activeDrivers
        - openDisputes

    CongestionForecast:
      type: object
      properties:
        site:
          type: string
        location:
          type: string
        currentLevel:
          type: string
          enum: [low, moderate, high, critical]
        forecast:
          type: array
          items:
            type: object
            properties:
              time:
                type: string
              level:
                type: string
                enum: [low, moderate, high, critical]
              recommendation:
                type: string
            required:
              - time
              - level
              - recommendation
        suggestedTimes:
          type: array
          items:
            type: string
        lastUpdated:
          type: string
      required:
        - site
        - location
        - currentLevel
        - forecast

    DriverStats:
      type: object
      properties:
        profileId:
          type: integer
        name:
          type: string
        trustScore:
          type: number
        completedDeliveries:
          type: integer
        onTimeRate:
          type: number
        averageRating:
          type: number
        totalEarnings:
          type: number
      required:
        - profileId
        - name
        - trustScore
        - completedDeliveries
        - onTimeRate

    RouteInsight:
      type: object
      properties:
        route:
          type: string
        count:
          type: integer
        avgCost:
          type: number
      required:
        - route
        - count
        - avgCost

    CityDemand:
      type: object
      properties:
        city:
          type: string
        count:
          type: integer
        percentage:
          type: number
      required:
        - city
        - count
        - percentage

    TruckOccupancy:
      type: object
      properties:
        truckType:
          type: string
        total:
          type: integer
        active:
          type: integer
        occupancyRate:
          type: number
      required:
        - truckType
        - total
        - active
        - occupancyRate

    SmartInsights:
      type: object
      properties:
        topCities:
          type: array
          items:
            $ref: "#/components/schemas/CityDemand"
        topRoutes:
          type: array
          items:
            $ref: "#/components/schemas/RouteInsight"
        truckOccupancy:
          type: array
          items:
            $ref: "#/components/schemas/TruckOccupancy"
        aiAdvice:
          type: string
        aiAdviceAr:
          type: string
        generatedAt:
          type: string
        cachedUntil:
          type: string
        totalOrdersAnalyzed:
          type: integer
      required:
        - topCities
        - topRoutes
        - truckOccupancy
        - aiAdvice
        - aiAdviceAr
        - generatedAt
        - cachedUntil
        - totalOrdersAnalyzed
