openapi: 3.0.3
info:
  title: NovaTrek Transport Logistics API
  description: |
    Manages shuttle buses, van pickups, and transport coordination between NovaTrek
    locations and trailheads. Handles route planning, vehicle fleet management, and
    guest transport request fulfillment.
  version: 1.4.0
  contact:
    name: NovaTrek Platform Engineering
    email: platform-eng@novatrek.example.com

servers:
  - url: https://api.novatrek.example.com/transport/v1
    description: Production
  - url: https://api-staging.novatrek.example.com/transport/v1
    description: Staging

security:
  - bearerAuth: []

paths:
  /routes:
    get:
      operationId: listRoutes
      summary: List transport routes
      description: Returns available transport routes with optional filtering by origin, destination, or active status.
      parameters:
        - name: origin_location_id
          in: query
          description: Filter by origin location (cross-ref svc-location-services)
          schema:
            type: string
            format: uuid
        - name: destination_location_id
          in: query
          description: Filter by destination location (cross-ref svc-location-services)
          schema:
            type: string
            format: uuid
        - name: active_only
          in: query
          schema:
            type: boolean
            default: true
        - $ref: '#/components/parameters/PageSize'
        - $ref: '#/components/parameters/PageToken'
      responses:
        '200':
          description: List of transport routes
          content:
            application/json:
              schema:
                type: object
                properties:
                  routes:
                    type: array
                    items:
                      $ref: '#/components/schemas/TransportRoute'
                  next_page_token:
                    type: string
                  total_count:
                    type: integer
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createRoute
      summary: Create a new transport route
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateRouteRequest'
      responses:
        '201':
          description: Route created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransportRoute'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'

  /routes/{route_id}/schedule:
    get:
      operationId: getRouteSchedule
      summary: Get schedule for a transport route
      description: Returns the daily schedule of departures for a given route, optionally filtered by date range.
      parameters:
        - $ref: '#/components/parameters/RouteId'
        - name: date_from
          in: query
          schema:
            type: string
            format: date
        - name: date_to
          in: query
          schema:
            type: string
            format: date
      responses:
        '200':
          description: Route schedule
          content:
            application/json:
              schema:
                type: object
                properties:
                  route_id:
                    type: string
                    format: uuid
                  departures:
                    type: array
                    items:
                      $ref: '#/components/schemas/ScheduledDeparture'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'

  /transport-requests:
    post:
      operationId: createTransportRequest
      summary: Request transport for a reservation
      description: |
        Creates a transport request linked to an existing reservation
        (cross-ref svc-reservations). The system assigns an available vehicle
        based on capacity and proximity.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateTransportRequestBody'
      responses:
        '201':
          description: Transport request created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransportRequest'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          description: No vehicles available for requested time
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '500':
          $ref: '#/components/responses/InternalError'

  /transport-requests/{request_id}:
    get:
      operationId: getTransportRequest
      summary: Get transport request details
      parameters:
        - $ref: '#/components/parameters/RequestId'
      responses:
        '200':
          description: Transport request details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TransportRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'

  /vehicles:
    get:
      operationId: listVehicles
      summary: List fleet vehicles
      parameters:
        - name: type
          in: query
          schema:
            $ref: '#/components/schemas/VehicleType'
        - name: status
          in: query
          schema:
            $ref: '#/components/schemas/VehicleStatus'
        - name: assigned_location_id
          in: query
          description: Filter by home base location (cross-ref svc-location-services)
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/PageSize'
        - $ref: '#/components/parameters/PageToken'
      responses:
        '200':
          description: List of vehicles
          content:
            application/json:
              schema:
                type: object
                properties:
                  vehicles:
                    type: array
                    items:
                      $ref: '#/components/schemas/Vehicle'
                  next_page_token:
                    type: string
                  total_count:
                    type: integer
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'

  /vehicles/{vehicle_id}:
    patch:
      operationId: updateVehicle
      summary: Update vehicle information
      parameters:
        - $ref: '#/components/parameters/VehicleId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateVehicleRequest'
      responses:
        '200':
          description: Vehicle updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Vehicle'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

  parameters:
    RouteId:
      name: route_id
      in: path
      required: true
      schema:
        type: string
        format: uuid
    RequestId:
      name: request_id
      in: path
      required: true
      schema:
        type: string
        format: uuid
    VehicleId:
      name: vehicle_id
      in: path
      required: true
      schema:
        type: string
        format: uuid
    PageSize:
      name: page_size
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 25
    PageToken:
      name: page_token
      in: query
      schema:
        type: string

  schemas:
    VehicleType:
      type: string
      enum: [SHUTTLE_BUS, VAN, SUV, ATV]

    VehicleStatus:
      type: string
      enum: [AVAILABLE, IN_TRANSIT, MAINTENANCE, RETIRED]

    TransportRequestStatus:
      type: string
      enum: [PENDING, CONFIRMED, IN_PROGRESS, COMPLETED, CANCELLED]

    TransportRoute:
      type: object
      required: [id, origin_location_id, destination_location_id, distance_km, duration_minutes]
      properties:
        id:
          type: string
          format: uuid
        origin_location_id:
          type: string
          format: uuid
          description: References svc-location-services Location.id
        destination_location_id:
          type: string
          format: uuid
          description: References svc-location-services Location.id
        route_name:
          type: string
          example: "Summit Ridge to Elk Valley Trailhead"
        distance_km:
          type: number
          format: double
          minimum: 0
        duration_minutes:
          type: integer
          minimum: 1
        terrain_difficulty:
          type: string
          enum: [PAVED, GRAVEL, OFF_ROAD, MIXED]
        active:
          type: boolean
          default: true
        created_at:
          type: string
          format: date-time

    ScheduledDeparture:
      type: object
      properties:
        departure_time:
          type: string
          format: date-time
        arrival_time:
          type: string
          format: date-time
        vehicle_id:
          type: string
          format: uuid
        seats_available:
          type: integer
        status:
          type: string
          enum: [SCHEDULED, BOARDING, DEPARTED, ARRIVED, CANCELLED]

    TransportRequest:
      type: object
      required: [id, reservation_id, pickup_location_id, dropoff_location_id, scheduled_time, status]
      properties:
        id:
          type: string
          format: uuid
        reservation_id:
          type: string
          format: uuid
          description: References svc-reservations Reservation.id
        pickup_location_id:
          type: string
          format: uuid
          description: References svc-location-services Location.id
        dropoff_location_id:
          type: string
          format: uuid
          description: References svc-location-services Location.id
        scheduled_time:
          type: string
          format: date-time
        vehicle_id:
          type: string
          format: uuid
          nullable: true
        passenger_count:
          type: integer
          minimum: 1
        status:
          $ref: '#/components/schemas/TransportRequestStatus'
        special_requirements:
          type: string
          example: "Wheelchair accessible vehicle needed"
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    Vehicle:
      type: object
      required: [id, type, capacity, license_plate, status]
      properties:
        id:
          type: string
          format: uuid
        type:
          $ref: '#/components/schemas/VehicleType'
        capacity:
          type: integer
          minimum: 1
          description: Maximum passenger capacity
        license_plate:
          type: string
          example: "NVT-4821"
        status:
          $ref: '#/components/schemas/VehicleStatus'
        assigned_location_id:
          type: string
          format: uuid
          description: Home base location (references svc-location-services)
        mileage:
          type: integer
        last_maintenance_date:
          type: string
          format: date
        next_maintenance_date:
          type: string
          format: date

    CreateRouteRequest:
      type: object
      required: [origin_location_id, destination_location_id, distance_km, duration_minutes]
      properties:
        origin_location_id:
          type: string
          format: uuid
        destination_location_id:
          type: string
          format: uuid
        route_name:
          type: string
        distance_km:
          type: number
          format: double
          minimum: 0
        duration_minutes:
          type: integer
          minimum: 1
        terrain_difficulty:
          type: string
          enum: [PAVED, GRAVEL, OFF_ROAD, MIXED]

    CreateTransportRequestBody:
      type: object
      required: [reservation_id, pickup_location_id, dropoff_location_id, scheduled_time, passenger_count]
      properties:
        reservation_id:
          type: string
          format: uuid
        pickup_location_id:
          type: string
          format: uuid
        dropoff_location_id:
          type: string
          format: uuid
        scheduled_time:
          type: string
          format: date-time
        passenger_count:
          type: integer
          minimum: 1
        special_requirements:
          type: string

    UpdateVehicleRequest:
      type: object
      properties:
        status:
          $ref: '#/components/schemas/VehicleStatus'
        assigned_location_id:
          type: string
          format: uuid
        mileage:
          type: integer
        next_maintenance_date:
          type: string
          format: date

    Error:
      type: object
      required: [code, message]
      properties:
        code:
          type: string
        message:
          type: string
        details:
          type: array
          items:
            type: object
            properties:
              field:
                type: string
              reason:
                type: string

  responses:
    BadRequest:
      description: Invalid request parameters
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Missing or invalid authentication
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    NotFound:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Conflict:
      description: Resource conflict
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    InternalError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
