openapi: 3.0.3
info:
  title: NovaTrek Location Services API
  description: |
    Manages physical locations across the NovaTrek network including base camps,
    outposts, rental shops, ranger stations, and headquarters facilities.
    Provides capacity tracking and operating hours management.
  version: 1.2.0
  contact:
    name: NovaTrek Platform Engineering
    email: platform-eng@novatrek.example.com

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

security:
  - bearerAuth: []

paths:
  /locations:
    get:
      operationId: listLocations
      summary: List all locations
      description: Returns a paginated list of NovaTrek locations with optional filtering by type, region, or status.
      parameters:
        - name: type
          in: query
          schema:
            $ref: '#/components/schemas/LocationType'
        - name: region_id
          in: query
          schema:
            type: string
            format: uuid
        - name: status
          in: query
          schema:
            $ref: '#/components/schemas/LocationStatus'
        - $ref: '#/components/parameters/PageSize'
        - $ref: '#/components/parameters/PageToken'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                type: object
                properties:
                  locations:
                    type: array
                    items:
                      $ref: '#/components/schemas/Location'
                  next_page_token:
                    type: string
                  total_count:
                    type: integer
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalError'
    post:
      operationId: createLocation
      summary: Create a new location
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateLocationRequest'
      responses:
        '201':
          description: Location created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Location'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '409':
          $ref: '#/components/responses/Conflict'
        '500':
          $ref: '#/components/responses/InternalError'

  /locations/{location_id}:
    get:
      operationId: getLocation
      summary: Get location details
      parameters:
        - $ref: '#/components/parameters/LocationId'
      responses:
        '200':
          description: Successful response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Location'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'
    patch:
      operationId: updateLocation
      summary: Update location details
      parameters:
        - $ref: '#/components/parameters/LocationId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateLocationRequest'
      responses:
        '200':
          description: Location updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Location'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'

  /locations/{location_id}/capacity:
    get:
      operationId: getLocationCapacity
      summary: Get current capacity utilization
      parameters:
        - $ref: '#/components/parameters/LocationId'
        - name: date
          in: query
          schema:
            type: string
            format: date
      responses:
        '200':
          description: Capacity information
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LocationCapacity'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalError'

  /locations/{location_id}/operating-hours:
    get:
      operationId: getOperatingHours
      summary: Get operating hours for a location
      parameters:
        - $ref: '#/components/parameters/LocationId'
      responses:
        '200':
          description: Operating hours
          content:
            application/json:
              schema:
                type: object
                properties:
                  location_id:
                    type: string
                    format: uuid
                  schedules:
                    type: array
                    items:
                      $ref: '#/components/schemas/OperatingHours'
        '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:
    LocationId:
      name: location_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:
    LocationType:
      type: string
      enum: [BASE_CAMP, OUTPOST, RENTAL_SHOP, RANGER_STATION, HEADQUARTERS]

    LocationStatus:
      type: string
      enum: [ACTIVE, SEASONAL_CLOSURE, MAINTENANCE, DECOMMISSIONED]

    Location:
      type: object
      required: [id, name, type, address, coordinates, region_id, status]
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          example: "Summit Ridge Base Camp"
        type:
          $ref: '#/components/schemas/LocationType'
        address:
          $ref: '#/components/schemas/Address'
        coordinates:
          $ref: '#/components/schemas/Coordinates'
        region_id:
          type: string
          format: uuid
        capacity:
          type: integer
          minimum: 0
        status:
          $ref: '#/components/schemas/LocationStatus'
        operating_hours:
          type: array
          items:
            $ref: '#/components/schemas/OperatingHours'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time

    Address:
      type: object
      properties:
        street:
          type: string
        city:
          type: string
        state:
          type: string
        postal_code:
          type: string
        country:
          type: string

    Coordinates:
      type: object
      required: [latitude, longitude]
      properties:
        latitude:
          type: number
          format: double
          minimum: -90
          maximum: 90
        longitude:
          type: number
          format: double
          minimum: -180
          maximum: 180
        elevation_meters:
          type: number
          format: double

    OperatingHours:
      type: object
      required: [day_of_week, open_time, close_time]
      properties:
        day_of_week:
          type: string
          enum: [MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY]
        open_time:
          type: string
          pattern: '^\d{2}:\d{2}$'
          example: "07:00"
        close_time:
          type: string
          pattern: '^\d{2}:\d{2}$'
          example: "19:00"
        seasonal_override:
          type: boolean
          default: false

    LocationCapacity:
      type: object
      required: [location_id, max_capacity, current_occupancy]
      properties:
        location_id:
          type: string
          format: uuid
        max_capacity:
          type: integer
        current_occupancy:
          type: integer
        available_spots:
          type: integer
        utilization_percent:
          type: number
          format: double
        as_of:
          type: string
          format: date-time

    CreateLocationRequest:
      type: object
      required: [name, type, address, coordinates, region_id]
      properties:
        name:
          type: string
        type:
          $ref: '#/components/schemas/LocationType'
        address:
          $ref: '#/components/schemas/Address'
        coordinates:
          $ref: '#/components/schemas/Coordinates'
        region_id:
          type: string
          format: uuid
        capacity:
          type: integer
          minimum: 0
        operating_hours:
          type: array
          items:
            $ref: '#/components/schemas/OperatingHours'

    UpdateLocationRequest:
      type: object
      properties:
        name:
          type: string
        status:
          $ref: '#/components/schemas/LocationStatus'
        capacity:
          type: integer
          minimum: 0
        operating_hours:
          type: array
          items:
            $ref: '#/components/schemas/OperatingHours'

    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'
