openapi: 3.1.0
info:
  title: Food Express API
  description: >
    API for managing the FoodExpress restaurants, orders, and customers.
  version: 1.0.0

servers:
  - url: http://localhost:4004/api/v1
    description: Local development servers
  - url: https://{stage}.foodexpress.com/api/v1
    description: Stage server
    variables:
      stage:
        description: Stage
        enum:
          - dev
          - test
        default: dev
  - url: https://foodexpress.com/api/v1
    description: Production server

tags:
  - name: Restaurants
  - name: Orders
  - name: Customers

paths:
  /restaurants:
    get:
      tags: [Restaurants]
      summary: List restaurants
      description: Retrieve a paginated list of restaurants.
      security: []
      parameters:
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
        - $ref: "#/components/parameters/AcceptLanguage"
      responses:
        "200":
          description: A paginated list of restaurants
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Restaurant"
                  pagination:
                    $ref: "#/components/schemas/Pagination"

  /restaurants/{id}/menu:
    get:
      tags: [Restaurants]
      summary: Get restaurant menu
      security: []
      parameters:
        - $ref: "#/components/parameters/RestaurantId"
        - $ref: "#/components/parameters/AcceptLanguage"
      responses:
        "200":
          description: "Menu for the restaurant"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Menu"
        "404":
          description: Restaurant not found

  /restaurants/{id}/orders:
    get:
      tags: [Orders, Restaurants]
      summary: List orders for a restaurant
      description: Retrieve a paginated list of orders for a specific restaurant.
      parameters:
        - $ref: "#/components/parameters/RestaurantId"
        - $ref: "#/components/parameters/Limit"
        - $ref: "#/components/parameters/Offset"
      responses:
        "200":
          description: A paginated list of orders
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Order"
                  pagination:
                    $ref: "#/components/schemas/Pagination"

  /orders:
    post:
      tags: [Orders]
      summary: Create a new order
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateOrderRequest"
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      responses:
        "201":
          description: Order created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Order"
        "400":
          description: Invalid request

  /orders/{orderId}:
    get:
      tags: [Orders]
      summary: Get order by ID
      parameters:
        - $ref: "#/components/parameters/OrderId"
      responses:
        "200":
          description: Order details
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Order"
        "404":
          description: Order not found

  /orders/{orderId}/status:
    patch:
      tags: [Orders]
      summary: Update order status
      description: Update the status of an existing order.
      parameters:
        - $ref: "#/components/parameters/OrderId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateOrderStatusRequest"
      responses:
        "200":
          description: Order status updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Order"
        "409":
          description: Invalid status transition

  /customers:
    post:
      tags: [Customers]
      summary: Create a customer
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateCustomerRequest"
            examples:
              Customer:
                $ref: "#/components/examples/CustomerRequest"
      parameters:
        - $ref: "#/components/parameters/IdempotencyKey"
      responses:
        "201":
          description: Customer created
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Customer"
  /customers/me:
    get:
      tags: [Customers]
      summary: Get current customer
      description: Returns the authenticated customer's profile
      responses:
        "200":
          $ref: "#/components/responses/CustomerDetails"

  /customers/{id}:
    get:
      tags: [Customers]
      summary: Get customer by ID
      parameters:
        - $ref: "#/components/parameters/CustomerId"
      responses:
        "200":
          $ref: "#/components/responses/CustomerDetails"
        "404":
          description: Customer not found

    patch:
      tags: [Customers]
      summary: Update customer details
      parameters:
        - $ref: "#/components/parameters/CustomerId"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/UpdateCustomerRequest"
            examples:
              Customer:
                $ref: "#/components/examples/CustomerRequest"
      responses:
        "200":
          description: Customer updated
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Customer"

    delete:
      tags: [Customers]
      summary: Delete customer
      parameters:
        - $ref: "#/components/parameters/CustomerId"
      responses:
        "204":
          description: Customer deleted

components:
  parameters:
    RestaurantId:
      name: id
      in: path
      required: true
      schema:
        type: string
        example: "09ede9cb-0031-4469-9144-dec6b564f1c0"

    OrderId:
      name: orderId
      in: path
      required: true
      schema:
        type: string
        example: "e17aca0c-c956-4a0d-afec-b117a9926e2c"

    CustomerId:
      name: id
      in: path
      required: true
      schema:
        type: string
        example: "18e1d8a2-e7ca-458f-a997-2cc80754105f"

    Limit:
      name: limit
      in: query
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 20
        examples: [20]

    Offset:
      name: offset
      in: query
      schema:
        type: integer
        minimum: 0
        default: 0
        examples: [0]

    IdempotencyKey:
      in: header
      name: Idempotency-Key
      required: false
      description: Unique key to prevent duplicate orders
      schema:
        type: string

    AcceptLanguage:
      in: header
      name: Accept-Language
      required: false
      description: Preferred language for localized strings.
      schema:
        type: string
        example: "de-DE"

  schemas:
    Restaurant:
      type: object
      properties:
        id:
          type: string
          examples: ["465db18f-6fc0-48e1-804a-156d0df29392"]
        name:
          type: string
          examples: ["Thai Food"]
        address:
          type: string
          examples: ["Hauptstraße 9, 68259 Mannheim"]

    Menu:
      type: array
      items:
        $ref: "#/components/schemas/MenuItem"

    MenuItem:
      type: object
      properties:
        id:
          type: string
          examples: ["9f062baf-236b-44fe-8d30-88cecb02c26b"]
        name:
          type: string
          examples: ["Cheeseburger"]
        price:
          type: number
          examples: [3.99]

    Order:
      type: object
      properties:
        id:
          type: string
          examples: ["28c0bc0d-9d17-4b74-9885-84a4cd7c761e"]
        restaurantId:
          type: string
          examples: ["73591883-8aa4-4a2d-a411-abf42220a824"]
        customerId:
          type: string
          examples: ["706f645d-a420-4984-a913-c9a6e0c677f2"]
        status:
          $ref: "#/components/schemas/OrderStatus"
        items:
          type: array
          items:
            $ref: "#/components/schemas/OrderItem"
        totalAmount:
          type: number
          examples: [29.95]

    OrderItem:
      type: object
      properties:
        menuItemId:
          type: string
          examples: ["359d9b4a-c8a2-4457-a04a-fecddadad64f"]
        quantity:
          type: integer
          minimum: 1
          examples: [1]

    OrderStatus:
      type: string
      enum:
        - CREATED
        - CONFIRMED
        - PREPARING
        - READY
        - DELIVERED
        - CANCELLED
      examples: ["CREATED"]

    CreateOrderRequest:
      type: object
      required: [restaurantId, customerId, items]
      properties:
        restaurantId:
          type: string
          examples: ["435cb941-3483-4e80-acc1-6454f1f948b5"]
        customerId:
          type: string
          examples: ["433569a1-d4d8-4073-ab1a-d26339c747c3"]
        items:
          type: array
          items:
            $ref: "#/components/schemas/OrderItem"

    UpdateOrderStatusRequest:
      type: object
      required: [status]
      properties:
        status:
          $ref: "#/components/schemas/OrderStatus"

    Customer:
      type: object
      properties:
        id:
          type: string
          examples: ["1a7830a6-8e0f-43b2-a0e0-4479cb0acf7d"]
        name:
          type: string
          examples: ["Max Mustermann"]
        email:
          type: string
          examples: ["max.mustermann@gmail.com"]

    CreateCustomerRequest:
      type: object
      required: [name, email]
      properties:
        name:
          type: string
        email:
          type: string

    UpdateCustomerRequest:
      type: object
      properties:
        name:
          type: string
        email:
          type: string

    Pagination:
      type: object
      properties:
        limit:
          type: integer
          examples: [20]
        offset:
          type: integer
          examples: [0]
        total:
          type: integer
          examples: [35]

  responses:
    CustomerDetails:
      description: "Customer details"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Customer"

  examples:
    CustomerRequest:
      value:
        name: "Max Mustermann"
        email: "max.mustermann@gmail.com"

  securitySchemes:
    BasicAuth:
      type: http
      scheme: basic

    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-API-Key

security:
  - BasicAuth: []
