---
openapi: "3.0.0"
info:
  version: 1.0.0
  title: Boxes API
  description: Home inventory system
  termsOfService: https://phrye.com
  contact:
    name: Kevin Lyda
    email: kevin@lyda.ie
    url: https://git.lyda.ie/kevin/boxes/
  license:
    name: MIT
servers:
  - url: https://localhost:8080/
paths:

  /api/location/{lid}:
    get:
      summary: Location
      description: Get a location.
      operationId: GetLocation
      parameters:
        - $ref: '#/components/parameters/LID'
      responses:
        '200':
          $ref: '#/components/responses/Location'
        '403':
          $ref: '#/components/responses/Error'
        '404':
          $ref: '#/components/responses/Error'
    post:
      summary: Location
      description: Create a location.
      operationId: CreateLocation
      parameters:
        - $ref: '#/components/parameters/LID'
      requestBody:
        description: New location.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Location"
      responses:
        '200':
          $ref: '#/components/responses/Location'
        '403':
          $ref: '#/components/responses/Error'
        '406':
          $ref: '#/components/responses/Error'
        '507':
          $ref: '#/components/responses/Error'
    patch:
      summary: Location
      description: Update a location.
      operationId: UpdateLocation
      parameters:
        - $ref: '#/components/parameters/LID'
      requestBody:
        description: Updated location.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Location"
      responses:
        '200':
          $ref: '#/components/responses/Location'
        '403':
          $ref: '#/components/responses/Error'
        '404':
          $ref: '#/components/responses/Error'
        '406':
          $ref: '#/components/responses/Error'
        '507':
          $ref: '#/components/responses/Error'
    delete:
      summary: Location
      description: Delete a location.
      operationId: DeleteLocation
      parameters:
        - $ref: '#/components/parameters/LID'
      responses:
        '200':
          $ref: '#/components/responses/Location'
        '403':
          $ref: '#/components/responses/Error'
        '404':
          $ref: '#/components/responses/Error'

  /api/locations:
    get:
      summary: Locations
      description: Get a list of locations.
      operationId: GetLocations
      parameters:
        - $ref: '#/components/parameters/FilterQ'
      responses:
        '200':
          $ref: '#/components/responses/Locations'
        '403':
          $ref: '#/components/responses/Error'
        '500':
          $ref: '#/components/responses/Error'

  /api/box/{bid}:
    get:
      summary: Get a box
      description: |
        This gets a box based on the box id.  Contents are stored in boxes
        and boxes are stored in locations.
      operationId: GetBox
      parameters:
        - $ref: '#/components/parameters/BID'
      responses:
        '200':
          $ref: '#/components/responses/Box'
        '403':
          $ref: '#/components/responses/Error'
        '404':
          $ref: '#/components/responses/Error'
    post:
      summary: Create a box
      description: Creates a new box.
      operationId: CreateBox
      parameters:
        - $ref: '#/components/parameters/BID'
      requestBody:
        description: New box.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Box"
      responses:
        '200':
          $ref: '#/components/responses/Box'
        '403':
          $ref: '#/components/responses/Error'
        '406':
          $ref: '#/components/responses/Error'
        '507':
          $ref: '#/components/responses/Error'
    patch:
      summary: Update a box
      description: Updates an existing box.
      operationId: UpdateBox
      parameters:
        - $ref: '#/components/parameters/BID'
      requestBody:
        description: Updated box.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Box"
      responses:
        '200':
          $ref: '#/components/responses/Box'
        '403':
          $ref: '#/components/responses/Error'
        '404':
          $ref: '#/components/responses/Error'
        '406':
          $ref: '#/components/responses/Error'
        '507':
          $ref: '#/components/responses/Error'
    delete:
      summary: Box
      description: Delete a box.
      operationId: DeleteBox
      parameters:
        - $ref: '#/components/parameters/BID'
      responses:
        '200':
          $ref: '#/components/responses/Box'
        '403':
          $ref: '#/components/responses/Error'
        '404':
          $ref: '#/components/responses/Error'

  /api/boxes:
    get:
      summary: Boxes
      description: Get a list of boxes.
      operationId: GetBoxes
      parameters:
        - $ref: '#/components/parameters/LocationID'
        - $ref: '#/components/parameters/FilterQ'
      responses:
        '200':
          $ref: '#/components/responses/Boxes'
        '403':
          $ref: '#/components/responses/Error'
        '500':
          $ref: '#/components/responses/Error'

  /api/content/{cid}:
    get:
      summary: Content
      description: Get a content.
      operationId: GetContent
      parameters:
        - $ref: '#/components/parameters/CID'
      responses:
        '200':
          $ref: '#/components/responses/Content'
        '403':
          $ref: '#/components/responses/Error'
        '404':
          $ref: '#/components/responses/Error'
    post:
      summary: Content
      description: Create a content.
      operationId: CreateContent
      parameters:
        - $ref: '#/components/parameters/CID'
      requestBody:
        description: New content.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Content"
      responses:
        '200':
          $ref: '#/components/responses/Content'
        '403':
          $ref: '#/components/responses/Error'
        '406':
          $ref: '#/components/responses/Error'
        '507':
          $ref: '#/components/responses/Error'
    patch:
      summary: Content
      description: Update a content.
      operationId: UpdateContent
      parameters:
        - $ref: '#/components/parameters/CID'
      requestBody:
        description: Updated content.
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/Content"
      responses:
        '200':
          $ref: '#/components/responses/Content'
        '403':
          $ref: '#/components/responses/Error'
        '404':
          $ref: '#/components/responses/Error'
        '406':
          $ref: '#/components/responses/Error'
        '507':
          $ref: '#/components/responses/Error'
    delete:
      summary: Content
      description: Delete content.
      operationId: DeleteContent
      parameters:
        - $ref: '#/components/parameters/CID'
      responses:
        '200':
          $ref: '#/components/responses/Content'
        '403':
          $ref: '#/components/responses/Error'
        '404':
          $ref: '#/components/responses/Error'

  /api/contents:
    get:
      summary: Contents
      description: Get a list of contents.
      operationId: GetContents
      parameters:
        - $ref: '#/components/parameters/LocationID'
        - $ref: '#/components/parameters/BoxID'
        - $ref: '#/components/parameters/FilterQ'
        - $ref: '#/components/parameters/TagsQ'
      responses:
        '200':
          $ref: '#/components/responses/Contents'
        '403':
          $ref: '#/components/responses/Error'
        '500':
          $ref: '#/components/responses/Error'

components:

  parameters:
    CID:
      name: cid
      in: path
      description: The content ID being queried.
      schema:
        type: string
        pattern: '^[A-Za-z0-9_-$]+$'

    BID:
      name: bid
      in: path
      description: The box ID being queried.
      schema:
        type: string
        pattern: '^[A-Za-z0-9_-$]+$'

    BoxID:
      name: box
      in: query
      description: The box ID being queried.
      schema:
        type: string
        pattern: '^[A-Za-z0-9_-$]+$'

    LID:
      name: lid
      in: path
      description: The location ID being queried.
      schema:
        type: string
        pattern: '^[A-Za-z0-9_-$]+$'

    LocationID:
      name: location
      in: query
      description: The location ID being queried.
      schema:
        type: string

    FilterQ:
      name: filter
      in: query
      description: A filter to search the description.
      schema:
        type: string

    TagsQ:
      name: tags
      in: query
      description: A filter to search the description.
      style: form
      explode: false
      schema:
        type: array
        items:
          type: string

  responses:
    Content:
      description: Content.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Content'

    Contents:
      description: List of contents.
      content:
        application/json:
          schema:
            type: array
            items:
              $ref: '#/components/schemas/Content'

    Box:
      description: A box.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Box'

    Boxes:
      description: List of boxes.
      content:
        application/json:
          schema:
            type: array
            items:
              $ref: '#/components/schemas/Box'

    Location:
      description: A location.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Location'

    Locations:
      description: List of locations.
      content:
        application/json:
          schema:
            type: array
            items:
              $ref: '#/components/schemas/Location'

    Error:
      description: Error message.
      content:
        application/json:
          schema:
            type: object
            required: [code, message]
            properties:
              code:
                type: integer
              message:
                type: string

  schemas:
    Content:
      type: object
      required: [id, box, description]
      properties:
        id:
          type: string
          pattern: '^[A-Za-z0-9_-$]+$'
        box:
          type: string
        description:
          type: string
        tags:
          type: array
          items:
            type: string

    Box:
      type: object
      required: [id, location, description]
      properties:
        id:
          type: string
          pattern: '^[A-Za-z0-9_-$]+$'
        location:
          type: string
        description:
          type: string

    Location:
      type: object
      required: [id, description]
      properties:
        id:
          type: string
          pattern: '^[A-Za-z0-9_-$]+$'
        description:
          type: string