openapi: 3.0.3
info:
  title: Inventoryscentric API
  version: 1.0.0
  description: |
    Multi-hotel inventory & purchasing. Per-hotel API keys scope all data to one tenant.
servers:
  - url: /api/v1
security:
  - ApiKeyAuth: []
  - BearerAuth: []
components:
  securitySchemes:
    ApiKeyAuth:
      type: apiKey
      in: header
      name: X-Api-Key
    BearerAuth:
      type: http
      scheme: bearer
  schemas:
    Product:
      type: object
      properties:
        code: { type: string }
        description: { type: string }
        product_group: { type: string }
        base_unit: { type: string }
        avg_cost: { type: number }
    SalePost:
      type: object
      required: [outlet_code, sale_date, lines]
      properties:
        external_id: { type: string }
        outlet_code: { type: string, description: Warehouse/outlet code }
        sale_date: { type: string, format: date }
        lines:
          type: array
          items:
            type: object
            required: [product_code, qty]
            properties:
              product_code: { type: string }
              qty: { type: number }
              unit_price: { type: number }
paths:
  /products:
    get:
      summary: List products
      parameters:
        - in: query
          name: q
          schema: { type: string }
        - in: query
          name: group
          schema: { type: string }
      responses:
        '200': { description: OK }
    post:
      summary: Create product
      responses:
        '201': { description: Created }
  /products/{code}:
    get:
      summary: Get product with stock levels
      parameters:
        - in: path
          name: code
          required: true
          schema: { type: string }
      responses:
        '200': { description: OK }
  /suppliers:
    get:
      summary: List suppliers
      responses:
        '200': { description: OK }
  /warehouses:
    get:
      summary: List warehouses
      responses:
        '200': { description: OK }
  /stock:
    get:
      summary: Stock on hand lines
      responses:
        '200': { description: OK }
  /stock/summary:
    get:
      summary: Tenant stock summary
      responses:
        '200': { description: OK }
  /purchase-orders:
    get:
      summary: List purchase orders
      responses:
        '200': { description: OK }
    post:
      summary: Create purchase order
      responses:
        '201': { description: Created }
  /receipts:
    get:
      summary: List goods receipts
      responses:
        '200': { description: OK }
    post:
      summary: Receive stock (increments SOH)
      responses:
        '201': { description: Created }
  /issues:
    get:
      summary: List issues/transfers
      responses:
        '200': { description: OK }
    post:
      summary: Issue stock from store to bar/outlet
      responses:
        '201': { description: Created }
  /stock-counts:
    get:
      summary: List stock counts
      responses:
        '200': { description: OK }
    post:
      summary: Open a stock count (bar expected = opening + issues - sales)
      responses:
        '201': { description: Created }
  /stock-counts/{number}/lines:
    patch:
      summary: Update counted quantities
      parameters:
        - in: path
          name: number
          required: true
          schema: { type: string }
      responses:
        '200': { description: OK }
  /stock-counts/{number}/post:
    post:
      summary: Post count and apply variance adjustments
      parameters:
        - in: path
          name: number
          required: true
          schema: { type: string }
      responses:
        '200': { description: OK }
  /sales:
    get:
      summary: List sales posts
      responses:
        '200': { description: OK }
    post:
      summary: PMS posts sales; decrements outlet stock
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SalePost'
      responses:
        '201': { description: Created }
