openapi: 3.1.2
info:
  title: Space-Market
  version: 4.0.0
  summary: An API ment for communication in a simple market system.
  description: A API inspired by the [Space-Market](https://github.com/Space-Market/API) API. Its ment for communication of a simple market system.
  license:
    name: MIT License
    identifier: MIT
    url: https://spdx.org/licenses/MIT.html
servers:
  - url: http://example.space-market.server/api/v4
security: []
tags:
  - name: auth
    description: These endpoints define how clients can authenticate to the server to create and change protected items.
  - name: info
    description: These show informations about the server
  - name: products
    description: These define how the products can be used
  - name: users
    description: Defines how the user is defined and can be used
  - name: images
    description: |
      Define how a image is created and can be obtained.

      Due to human error, the server should not expect the client to delete the image, when it is not used anymore.
      The server should implerment a garbage collection system for that.
  - name: barcodes
    description: |
      Defines how a barcode is crreated and can be used to find different objects.
  - name: denominations
    description: Defines what amounts users can depoist.
  - name: transactions
    description: Defines how transactions are stored.
paths:
  /server:
    get:
      tags:
        - info
      summary: Server Information
      description: This returns preferences and additional information for the frontend.
      responses:
        '200':
          description: Returns information and preferences of the server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/server-info'
        default:
          $ref: '#/components/responses/GenericError'
  /products:
    get:
      tags:
        - products
      summary: Returns all products
      responses:
        '200':
          description: Returns the data for all products
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Product'
        default:
          $ref: '#/components/responses/GenericError'
    post:
      tags:
        - products
      summary: Creates a product
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProductCreate'
      security:
        - RootAccess: []
      responses:
        '200':
          description: Created the product and returns the details for the product
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Product'
                  - example:
                      name: Mio Mio Cola
        '400':
          description: The inputs used were incorrect.
          content:
            application/json:
              schema:
                type: object
                properties:
                  verificationsFailed:
                    type: object
                    properties:
                      field:
                        type: string
                      failedVerification:
                        type: string
                        enum:
                          - IMAGE_DOES_NOT_EXIST
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        default:
          $ref: '#/components/responses/GenericError'
  /products/{id}:
    parameters:
      - name: id
        in: path
        schema:
          type: string
          format: uuid
    get:
      tags:
        - products
      summary: Returns details about a product
      responses:
        '200':
          description: Returns the details for the product
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Product'
        '404':
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
    patch:
      tags:
        - products
      summary: Updates a product
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProductUpdate'
      security:
        - RootAccess: []
      responses:
        '200':
          description: Updated the product and returns the details for the updated product
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Product'
                  - example:
                      name: Mio Mio Mate with pep
        '400':
          description: The inputs used were incorrect.
          content:
            application/json:
              schema:
                type: object
                properties:
                  verificationsFailed:
                    type: object
                    properties:
                      field:
                        type: string
                      failedVerification:
                        type: string
                        enum:
                          - IMAGE_DOES_NOT_EXIST
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
    delete:
      tags:
        - products
      summary: Deletes a product by ID
      security:
        - RootAccess: []
      responses:
        '200':
          $ref: '#/components/responses/Success'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
  /users:
    get:
      tags:
        - users
      summary: Get all users
      description: This endpoint returns all users
      responses:
        '200':
          description: Returns details of all users
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/User'
        default:
          $ref: '#/components/responses/GenericError'
    post:
      tags:
        - users
      summary: Create user
      description: This endpoint creates a new user
      requestBody:
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/UserDetails'
                - type: object
                  required:
                    - username
                    - balance
                    - active
                    - store_changes
      responses:
        '200':
          description: Created the user and returns details of that user
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/User'
                  - example:
                      name: Mio Mio Cola
        '400':
          $ref: '#/components/responses/InputError'
        default:
          $ref: '#/components/responses/GenericError'
  /users/{id}:
    parameters:
      - name: id
        in: path
        schema:
          type: string
          format: uuid
    get:
      tags:
        - users
      summary: Returns details about the user
      responses:
        '200':
          description: Returns details about the user
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/User'
        '404':
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
    patch:
      tags:
        - users
      summary: Updates a user
      requestBody:
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/UserDetails'
                - example:
                    username: you
      responses:
        '200':
          description: Updated the user and returns the updated user.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/User'
                  - example:
                      username: you
        '400':
          $ref: '#/components/responses/InputError'
        '404':
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
    delete:
      tags:
        - users
      summary: Deletes a user by ID
      security:
        - RootAccess: []
      responses:
        '200':
          $ref: '#/components/responses/Success'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
  /users/{id}/deposit:
    parameters:
      - name: id
        in: path
        schema:
          type: string
          format: uuid
    post:
      tags:
        - users
      summary: Deposits funds to a user
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                amount:
                  type: number
                  format: int32
      responses:
        '200':
          description: The generated transaction for the purchase
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transaction'
        '404':
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
  /users/{id}/purchase:
    parameters:
      - name: id
        in: path
        schema:
          type: string
          format: uuid
    post:
      tags:
        - users
      summary: Purchase a product (or use up balance) for user
      requestBody:
        content:
          application/json:
            schema:
              type: object
              description: Using this will buy a product.
              properties:
                product_id:
                  type: string
                  format: uuid
      responses:
        '200':
          description: The generated transaction for the purchase
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transaction'
        '400':
          description: The product id is incorrect.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    const: false
                  reason:
                    type: string
                    const: INVALID_PRODUCT_ID
        '402':
          $ref: '#/components/responses/InsufficiantFundsError'
        '404':
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
  /auth:
    get:
      tags:
        - auth
      summary: Authentication Information
      description: This returns information how the API can be used to authenticate for additional permissions.
      responses:
        '200':
          description: Returns the authentication method the server expects. If "NONE" is returned, the "Authentication" header should always be ignored by the server, even if the frontend sends it.
          content:
            application/json:
              schema:
                type: object
                properties:
                  method:
                    type: string
                    enum:
                      - NONE
                      - PASSPHRASE
        default:
          $ref: '#/components/responses/GenericError'
    post:
      tags:
        - auth
      summary: Create authentication token
      description: This creates a authentication token, that can be used to modify specific data.
      requestBody:
        content:
          application/json:
            schema:
              oneOf:
                - type: object
                  properties:
                    passphrase:
                      type: string
      responses:
        '200':
          description: Token was created and the returned token should be used to gain RootAccess
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenReturn'
        '401':
          description: The passphrase or credentials are invalid!
        default:
          $ref: '#/components/responses/GenericError'
    delete:
      tags:
        - auth
      summary: Delete authentication token
      description: This invalidates the token, which is used as Bearer for the API. This should also invalidate the refresh token.
      security:
        - RootAccess: []
      responses:
        '200':
          $ref: '#/components/responses/Success'
        '401':
          description: Token was not found
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    const: false
        default:
          $ref: '#/components/responses/GenericError'
  /auth/update:
    post:
      tags:
        - auth
      summary: Refresh token
      description: This creates a new token, with a refresh token as authentication. The refresh token should be used as Bearer.
      security:
        - UpdateAccess: []
      responses:
        '200':
          description: Token was refreshed and can be used
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TokenReturn'
        '401':
          description: Refresh Token is invalid
        default:
          $ref: '#/components/responses/GenericError'
  /images:
    get:
      tags:
        - images
      summary: Returns the capabilities and guidelines for images
      description: This endpoint informs the UI, what kind of images are allowed by the server.
      responses:
        '200':
          description: Returns guidelines for uploading images
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ImageInfo'
        default:
          $ref: '#/components/responses/GenericError'
    post:
      tags:
        - images
      summary: Create a new image
      description: Creates a new image with the provided information.
      requestBody:
        content:
          multipart/form-data:
            schema:
              properties:
                file:
                  type: array
                  items: {}
      responses:
        '200':
          description: The image got uploaded and stored and the returned object is the detailed image
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Image'
        '413':
          description: The image is too large
          content:
            application/json:
              schema:
                type: object
                properties:
                  maximum_size:
                    type: number
                    format: int32
                    description: Maximum size of a image. in bytes
                    default: 5242880
        '415':
          description: The image does not comply with accepted Mime Types
          content:
            application/json:
              schema:
                type: object
                properties:
                  accepted_mime_types:
                    type: array
                    items:
                      type: string
                    default:
                      - image/png
                      - image/jpeg
                      - image/gif
                      - image/svg+xml
        default:
          $ref: '#/components/responses/GenericError'
  /images/{id}:
    parameters:
      - name: id
        in: path
        schema:
          type: string
          format: uuid
    get:
      tags:
        - images
      summary: Returns image metadata
      description: This endpoint offers metadata about the specified image
      responses:
        '200':
          description: Returns the image metadata
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Image'
        '404':
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
    delete:
      tags:
        - images
      summary: Deletes the image
      description: This will delete the image from the server, removing both the database entry and the file from the server.
      responses:
        '200':
          $ref: '#/components/responses/Success'
        '400':
          description: The image is still in use and should not be deleted.
          content:
            application/json:
              schema:
                type: object
                properties:
                  success:
                    type: boolean
                    const: false
                  reason:
                    type: string
                    const: IN_USE
        '404':
          description: The ID used does not exist. If this is called after a update to a object that removes or changes the image, this may mean the server already removed the requested image.
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
  /images/{id}/raw:
    parameters:
      - name: id
        in: path
        schema:
          type: string
          format: uuid
    get:
      tags:
        - images
      summary: Image as a raw data stream
      description: This endpoint sends the image as a raw image stream.
      responses:
        '200':
          description: Should contain the image. Due to different server implermentation and capabilities, the content and mime type is not further specified
        '404':
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
  /barcodes:
    get:
      tags:
        - barcodes
      summary: Find barcode by type and barcode or id
      description: Returns details for the barcode requested.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BarcodeSearch'
      responses:
        '200':
          description: Returns objects with stored data for the barcode assoicated with the barcode or id
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Barcode'
        '404':
          description: No barcode was found for the defined type and barcode string
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
    post:
      tags:
        - barcodes
      summary: Creates a barcode for an object
      description: This endpoint allows to create a barcode, which points to a object
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BarcodeDetails'
      responses:
        '200':
          description: Creates a barcode object, that is automatically linked to a object.
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Barcode'
        '400':
          description: The inputs used were incorrect.
          content:
            application/json:
              schema:
                type: object
                properties:
                  verificationsFailed:
                    type: array
                    items:
                      type: object
                      properties:
                        field:
                          type: string
                        failedVerification:
                          type: string
                          enum:
                            - ALREADY_EXISTS
                            - OBJECT_DOES_NOT_EXIST
        default:
          $ref: '#/components/responses/GenericError'
  /barcodes/{id}:
    parameters:
      - name: id
        in: path
        schema:
          type: string
          format: uuid
    get:
      tags:
        - barcodes
      summary: Get Barcode Details
      description: This endpoint returns the stored data for this barcode
      responses:
        '200':
          description: Returns a object with stored data for the barcode
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Barcode'
        '404':
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
    patch:
      tags:
        - barcodes
      summary: Updates a barcode
      responses:
        '200':
          description: The change was accepted and returns the changed barcode
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Barcode'
        '400':
          $ref: '#/components/responses/InputError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
    delete:
      tags:
        - barcodes
      summary: Deletes a barcode by ID
      responses:
        '200':
          $ref: '#/components/responses/Success'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/InvalidIdError'
        default:
          $ref: '#/components/responses/GenericError'
  /denominations:
    get:
      tags:
        - denominations
      summary: Get all denominations
      description: This endpoint returns all denominations. The denominations are expected to be defined by the server.
      responses:
        '200':
          description: Returns all denominations defined.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Denomination'
        default:
          $ref: '#/components/responses/GenericError'
  /transactions:
    get:
      tags:
        - transactions
      summary: List all transactions
      description: This endpoint returns all transactions, with optional filtering
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                user_id:
                  description: The user id to filter for.
                  type: string
                  format: uuid
      responses:
        '200':
          description: Lists all transactions that were found.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Transaction'
        default:
          $ref: '#/components/responses/GenericError'
    post:
      tags:
        - transactions
      summary: Create a new transactions
      description: Creates a new transaction with the provided information. This is primarily used for migration.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TransactionDetails'
      responses:
        '200':
          description: The image got uploaded and stored and the returned object is the detailed image
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transaction'
        default:
          $ref: '#/components/responses/GenericError'
  /transactions/{id}:
    parameters:
      - name: id
        in: path
        schema:
          type: string
          format: uuid
    get:
      tags:
        - transactions
      summary: Get transaction details from id
      description: Get transaction details from the provided id
      responses:
        '200':
          description: The transaction details
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Transaction'
        '404':
          description: The transaction doesn't exist
        default:
          $ref: '#/components/responses/GenericError'
    delete:
      tags:
        - transactions
      summary: Remove transaction details from id
      description: Remove the transaction details from the id
      responses:
        '200':
          description: The transaction was successfully deleted.
        '404':
          description: The transaction doesn't exist
        default:
          $ref: '#/components/responses/GenericError'
components:
  securitySchemes:
    RootAccess:
      type: http
      description: This key should be used to modify specific properties. Use /auth/ to create the token.
      scheme: bearer
    UpdateAccess:
      type: http
      description: This key should be used to create a new token, when the previous was invalidated due to time
      scheme: bearer
  responses:
    GenericError:
      description: The API was called incorrectly or a server side error happend. This is intentionally undefined, since generic errors are usually handled by the webserver from the API.
    UnauthorizedError:
      description: The Bearer token is invalid or missing!
    InvalidIdError:
      description: The ID used does not exist.
      content:
        application/json:
          schema:
            type: object
            properties:
              success:
                type: boolean
                const: false
              reason:
                type: string
                const: INVALID_ID
    Success:
      description: The request was performed successfully
      content:
        application/json:
          schema:
            type: object
            properties:
              success:
                type: boolean
                const: true
    InputError:
      description: The inputs used were incorrect.
      content:
        application/json:
          schema:
            type: object
            properties:
              verificationsFailed:
                type: object
                properties:
                  field:
                    type: string
                  failedVerification:
                    type: string
                    enum:
                      - MISSING_REQUIRED_VALUE
                      - IMAGE_DOES_NOT_EXIST
                      - NAME_ALREADY_USED
                      - ALREADY_EXISTS
                      - INVALID_TYPE
                      - OBJECT_DOES_NOT_EXIST
            example:
              verificationsFailed:
                - field: image
                  failedVerification: IMAGE_DOES_NOT_EXIST
                - field: name
                  failedVerification: MISSING_REQUIRED_VALUE
                - field: name
                  failedVerification: NAME_ALREADY_USED
    InsufficiantFundsError:
      description: The user has not enough funds to use this endpoint
      content:
        application/json:
          schema:
            type: object
            properties:
              success:
                type: boolean
                const: false
              reason:
                type: string
                const: INSUFFICIANT_FUNDS
  schemas:
    server-info:
      type: object
      properties:
        version:
          type: string
          description: Defines a version string the client may use to display to the user. Due to undefined format, clients should not attempt to parse it.
          example: Matender v0.0.1-beta
        credit_limit:
          type: number
          format: int32
          description: Defines the credit limit for users. This should be enforced by the server.
          default: 2000
        currency:
          type: object
          description: Contains information for the currency
          properties:
            symbol:
              type: string
              example: €
            symbol_location:
              type: string
              description: Gives the frontend a hit, where the symbol should be placed
              example: AFTER_AMOUNT
              enum:
                - BEFORE_AMOUNT
                - AFTER_AMOUNT
        energy_unit:
          type: string
          description: Defines what energy format, a energy defintion should be.
          default: kcal
        mass_unit:
          type: string
          description: Defines what unit should be used for labels.
          default: g
    ItemAttributes:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: The internal ID that should be used to point to this specific item.
        created_at:
          type: string
          format: date-time
          description: The time and date, when the item was created.
      required:
        - id
    UpdateableItemAttributes:
      type: object
      allOf:
        - $ref: '#/components/schemas/ItemAttributes'
        - type: object
          properties:
            updated_at:
              type: string
              format: date-time
              description: The time and date, when the item was last modified.
    DrinkLabel:
      type: object
      description: The label of the drink. Usually contains additional information like size or caffeine.
      properties:
        type:
          type: string
          const: DRINK
        bottle_size:
          type: number
          format: float
          description: size in litres
        caffeine:
          type: number
          format: int32
          description: mg of caffeine per 100ml/unit
        energy:
          type: number
          format: int32
          description: energy per 100ml
        alcohol:
          type: number
          format: float
          description: vol % alcohol
      example:
        bottle_size: 0.5
        caffeine: 20
        energy: 102
        alcohol: 0
    FoodLabel:
      type: object
      description: The label for the food.
      properties:
        type:
          type: string
          const: FOOD
        vegetarian:
          type: boolean
        vegan:
          type: boolean
        energy:
          type: number
          format: int32
          description: The energy for the food per 100g. The unit is defined by the server under "/server" from the property "energy".
        fat:
          type: number
          format: int32
          description: The fat amount for the food per 100g. The unit is defined by the server under "/server" from the property "mass_unit"
        carbohydrate:
          type: number
          format: int32
          description: The carbohydrate amount for the food per 100g. The unit is defined by the server under "/server" from the property "mass_unit".
        sugar:
          type: number
          format: int32
          description: The sugar amount for the food per 100g. The unit is defined by the server under "/server" from the property "mass_unit".
        protein:
          type: number
          format: int32
          description: The protein amount for the food per 100g. The unit is defined by the server under "/server" from the property "mass_unit".
        salt:
          type: number
          format: int32
          description: The salt amount for the food per 100g. The unit is defined by the server under "/server" from the property "mass_unit".
    ActionLabel:
      type: object
      description: The label for a action. This is ment for stuff like printing.
      properties:
        type:
          type: string
          const: ACTION
        description:
          type: string
          description: A closer description, what the action actually is and for what the user is paying for.
    ProductLabel:
      description: The label of the product. Usually contains additional information like size or caffeine.
      discriminator:
        propertyName: type
      properties:
        type:
          type: string
      oneOf:
        - $ref: '#/components/schemas/DrinkLabel'
        - $ref: '#/components/schemas/FoodLabel'
        - $ref: '#/components/schemas/ActionLabel'
    ProductDetails:
      type: object
      properties:
        name:
          type: string
        price:
          type: number
          format: int32
          description: Price in the smallest format of the currency (f.E. cents)
        active:
          type: boolean
          description: If active is false, its considered to be not avaliable. This should not prevent people to buy it, however. Frontend may use this value to add a dialog to notify users of the fact, its not avaliable.
        image_id:
          type: string
          format: uuid
        label:
          $ref: '#/components/schemas/ProductLabel'
    ProductDetailsExample:
      example:
        name: Mio Mio Mate
        price: 170
        active: true
        image_id: b25afde4-07a4-45a3-a99d-bad3a7780cbb
        label:
          bottle_size: 0.5
          caffeine: 20
          energy: 102
          alcohol: 0
    Product:
      type: object
      allOf:
        - $ref: '#/components/schemas/UpdateableItemAttributes'
        - $ref: '#/components/schemas/ProductDetails'
        - $ref: '#/components/schemas/ProductDetailsExample'
        - required:
            - name
            - price
            - active
    ProductCreate:
      type: object
      description: Defines what values can be used to create the product. Missing values should be set to the default values by the server.
      allOf:
        - $ref: '#/components/schemas/ProductDetails'
        - required:
            - name
            - price
            - active
            - label
          example:
            name: Mio Mio Cola
    ProductUpdate:
      type: object
      description: Defines what values can be used to create the product. Missing values should not be overridden by the server
      allOf:
        - $ref: '#/components/schemas/ProductDetails'
        - example:
            name: Mio Mio Mate with pep
    UserDetailsProperties:
      type: object
      properties:
        balance:
          description: The balance of the user in cents
          type: number
          format: int32
        active:
          type: boolean
        track_transactions:
          description: |
            If set to true, transactions should contain the users id as related user id.
            Setting it to false, the server should remove the user id from related transactions.
          type: boolean
        avatar_id:
          description: The avatar image for the user.
          type: string
          format: uuid
    UserDetails:
      type: object
      properties:
        username:
          type: string
      allOf:
        - $ref: '#/components/schemas/UserDetailsProperties'
    User:
      allOf:
        - $ref: '#/components/schemas/UpdateableItemAttributes'
        - $ref: '#/components/schemas/UserDetails'
        - type: object
          required:
            - username
            - balance
            - active
            - track_transactions
    TransactionDetails:
      type: object
      properties:
        timestamp:
          type: string
          format: date-time
          description: The timestamp when the transaction happend
        type:
          type: string
          enum:
            - PURCHASE
            - DEPOSIT
        amount:
          type: number
          format: int32
        related_user_id:
          type: string
          format: uuid
        related_product_id:
          type: string
          format: uuid
      required:
        - timestamp
        - type
        - amount
    Transaction:
      allOf:
        - type: object
          properties:
            id:
              type: string
              format: uuid
          required:
            - id
        - $ref: '#/components/schemas/TransactionDetails'
    TokenReturn:
      type: object
      properties:
        token:
          description: the token to be used
          type: string
        token_valid_until:
          description: the time the token will be invalid. the duration is not specified by the api and may be different across server implermentations
          format: datetime
          type: string
        refresh_token:
          description: the token to be used, when the previous token has become invalid.
          type: string
        refresh_token_valid_until:
          description: the time the refresh_token will be invalid. the duration is not specified by the api and may be different across server implermentations
          format: datetime
          type: string
    ImageInfo:
      type: object
      description: This object defines, what images the server accept.
      properties:
        accepted_mime_types:
          type: array
          items:
            type: string
          default:
            - image/png
            - image/jpeg
            - image/gif
            - image/svg+xml
        maximum_size:
          type: number
          format: int32
          description: Maximum size of a image. in bytes
          default: 5242880
    Image:
      allOf:
        - $ref: '#/components/schemas/ItemAttributes'
        - type: object
          properties:
            filename:
              type: string
              description: The name of the file. This most likely will not be the same name, the file got upload with. Do not use it to check if the frontend needs to upload a new image. Use hash instead.
              example: 44d3e5d4-60a9-4a16-a20b-1b68c2662e1a.png
            hash:
              type: string
              description: The hash for the file, which should be generated using sha256. This can be used by the frontend to check if they need to upload a new image.
              example: dd593e6cbf80204e5a68bc64c50a4156a3da7569650f61d7cfe6437428a805d4
            filesize:
              type: number
              format: int32
              description: The size of the file in bytes
              example: 1048576
            mime_type:
              type: string
              description: The mime type of the file
              example: image/png
      required:
        - filename
        - hash
        - filesize
        - mime_type
    BarcodeSearch:
      type: object
      properties:
        type:
          type: string
          enum:
            - PRODUCT
            - USER
      oneOf:
        - type: object
          properties:
            barcode:
              type: string
        - type: object
          properties:
            id:
              type: string
              format: uuid
      required:
        - type
        - barcode
        - id
    BarcodeDetails:
      type: object
      properties:
        barcode:
          type: string
        type:
          type: string
          enum:
            - PRODUCT
            - USER
        linked_object:
          type: string
          format: uuid
      required:
        - barcode
        - type
        - linked_object
    Barcode:
      allOf:
        - $ref: '#/components/schemas/UpdateableItemAttributes'
        - $ref: '#/components/schemas/BarcodeDetails'
    Denomination:
      type: object
      properties:
        amount:
          type: number
          format: int32
        image_url:
          description: |
            The URI that should be used when a frontend wants to use an image for the amount. 

            While it can be any URI renderable by a web-browser, its recommended to only use server-located uri to prevent issues.
          type: string
          format: uri
      required:
        - amount
        - image_url
