openapi: 3.0.0
info:
  title: Operation API
  # The version must be increased whenever the API is changed!
  # This version is also used to version the maven packages for model, clients and server.
  # In oder to let the operation provider service implement the latest version of the server API,
  # you have to adjust the version.api property in the pom file of the operation provider.
  version: '1.5'
  description: |
    This API can be used to display and track selections of Job Milestones in the Operation View. An Operation is 
    designed as a user-facing grouping of Milestones. They represent the progress on business processes relevant for the end-user.\
    As such, Process Managers and other technical job creators shall register an operation for every business process 
    that is required to be most accessible to users and select only the milestones for those operations 
    that reflect the higher level processes progress best.
servers:
  - url: http://localhost:8181
    description: Generated server url
tags:
  - name: Create Operation
  - name: Get Operation
  - name: Delete Operation
  - name: Update RemovalStrategy

paths:
  /api/v1/operations:
    post:
      tags:
        - Create Operation
      summary: Create an operation
      description: |
        This will create a new Operation Card in the frontend immediately. The operation will hold all milestones
        referenced with the given filter as soon as they are created as part of a job.\
        There is no restriction on how many operations a milestone can be part of. Hence, an operation creator
        does not need to consider other potential operation creators that might reference to a shared set of milestones.
      operationId: createOperation
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateOperation'
        required: true
      responses:
        201:
          description: The request was successful and an operation was created.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReadOperation"
        400:
          description: There was a problem validating the input.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        500:
          description: There was an internal server error.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
      security:
        - oauthToken:
            - FPOS_ADMIN
    get:
      tags:
        - Get Operation
      summary: Returns all operations
      description: >
        Returns all existing operations.
        Automatically and manually deleted operations are both not part of this interfaces response.
      operationId: getAllOperations
      responses:
        200:
          description: The request was successful and the list of operations is returned
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ReadOperation'
        500:
          description: There was an internal server error.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
      security:
        - oauthToken:
            - FPOS_ADMIN
    delete:
      deprecated: true
      tags:
        - Delete Operation
      summary: Deletes an existing operation
      description: >
        _Migration note:_ Please migrate to the delete endpoint with the
        operation id as part of the URL instead of the request body.
        
        
        Removes an operation by its identifier, especially useful for operations with a
        removal policy of never.
      operationId: deleteOperationByBody
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeleteOperation'
        required: true
      responses:
        204:
          description: The request was successful and the operation was deleted.
        404:
          description: The requested resource was not found.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        500:
          description: There was an internal server error.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
      security:
        - oauthToken:
            - FPOS_ADMIN
  /api/v1/operations/{operationId}:
    get:
      tags:
        - Get Operation
      summary: Returns a specific operation
      description: This returns the operation for the given ID
      operationId: getOperation
      parameters:
        - name: operationId
          in: path
          description: The id of the operation
          required: true
          schema:
            type: string
            format: uuid
      responses:
        200:
          description: The request was successful and the operation is returned.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ReadOperation'
        404:
          description: The requested resource was not found.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        500:
          description: There was an internal server error.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
      security:
        - oauthToken:
            - FPOS_ADMIN
    patch:
      deprecated: true
      tags:
        - Update RemovalStrategy
      summary: Update operation's removal strategy
      description: >
        This will update the existing Operation's removal strategy.
      operationId: updateOperationRemovalStrategy
      parameters:
        - name: operationId
          in: path
          description: The id of the operation
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateOperationRemovalStrategy'
        required: true
      responses:
        204:
          description: The request was successful and removalStrategy was updated for the given operation.
        400:
          description: There was a problem validating the input.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        500:
          description: There was an internal server error.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
      security:
        - oauthToken:
            - FPOS_ADMIN
    delete:
      tags:
        - Delete Operation
      summary: Deletes an existing operation
      description: >
        Removes the operation given as part of the URL, especially useful for operations with a removal policy of never.
      operationId: deleteOperation
      parameters:
        - name: operationId
          in: path
          description: The id of the operation
          required: true
          schema:
            type: string
            format: uuid
      responses:
        204:
          description: The request was successful and the operation was deleted.
        404:
          description: The requested resource was not found.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        500:
          description: There was an internal server error.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
      security:
        - oauthToken:
            - FPOS_ADMIN
  /api/v1/operations/{operationId}/removal-strategy:
    patch:
      tags:
        - Update RemovalStrategy
      summary: Update operation's removal strategy
      description: >
        This will update the existing Operation's removal strategy.
      operationId: updateOperationsRemovalStrategy
      parameters:
        - name: operationId
          in: path
          description: The id of the operation
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RemovalStrategy'
        required: true
      responses:
        204:
          description: The request was successful and removalStrategy was updated for the given operation.
        400:
          description: There was a problem validating the input.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
        500:
          description: There was an internal server error.
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/Problem'
      security:
        - oauthToken:
            - FPOS_ADMIN
components:
  schemas:
    Problem:
      type: object
      properties:
        type:
          type: string
          format: uri-reference
          enum: [ "https://synaos.com/fpos/problems/invalid-user-input" ]
          description: "A URI reference that identifies the problem type. In contrast\
            \ to RFC7807, it is not meant to be dereferenced."
        title:
          type: string
          description: "A short, human-readable summary of the problem type. It is\
            \ written in english and not localized."
        status:
          maximum: 600
          minimum: 100
          type: integer
          description: The HTTP status code generated by the origin server for this
            occurrence of the problem.
          format: int32
        detail:
          type: string
          description: A human-readable explanation specific to this occurrence of
            the problem. It is written in english and not localized.
        instance:
          type: string
          description: "A representation of the problem instance. Might be left blank\
            \ for some problems. In contrast to RFC7807, it is not a URI and not meant\
            \ to be dereferenced."
        extensions:
          type: object
          additionalProperties:
            type: object
            description: Extensions used for internal purposes. Do not rely on these
              being set and/or stable.
          description: Extensions used for internal purposes. Do not rely on these
            being set and/or stable.
          deprecated: true
        translatableExtensions:
          type: object
          additionalProperties:
            type: object
            description: Extensions used for internal purposes. Do not rely on these
              being set and/or stable.
          description: Extensions used for internal purposes. Do not rely on these
            being set and/or stable.
          deprecated: true
      description: Problem details as proposed in https://tools.ietf.org/html/rfc7807
    ReadOperation:
      description: |
        An operation is mainly a non-distinct selection of milestones. In order to represent it's accumulated progress,
        it can derive trackable properties from the selected milestones.
        The **id** and **name** are used to identify the milestone, both uniquely for technical clients and
        human-readable for the user as an entry in the list. The **icon** and **type** should be used to categorize
        operations making them easier to identify.\
        The content of an operation is configured with the **filter**. As long as the operation exists,
        any milestone that matches the filter is considered being part of the operation. Milestones are added to
        and removed from the operation dynamically whenever their matching condition changes. A milestone could be 
        associated to multiple different operations.\
        An operation also contains some top-level properties. The parameter **derivedProperties** defines for each of them if
        it is derived from a specific milestone or assumes another value.
      type: object
      properties:
        id:
          description: >
            A unique id of the operation. This property will not be visible to the user and exists only to 
            identify a specific operation.
          type: string
          format: uuid
        name:
          type: string
          description: >
            The name of the operation which is shown to the user. Not necessarily unique but should be 
            meaningful for the user.
        filter:
          $ref: '#/components/schemas/Filter'
        type:
          type: string
          description: >
            The type of the operation. Allows for filtering in the frontend. Defaults to Job in case of missing values.
            Unknown values are possible.
          x-extensible-enum:
            - Job
        icon:
          type: string
          description: >
            Select the icon which should be visible on the operation card. Defaults to JOB in case of 
            missing or unknown value.
          x-extensible-enum:
            - JOB
            - A_B_TRANSPORT
            - TOUR_TRANSPORT
            - PUTAWAY
            - STOCK_COUNTING
            - PICKING
            - CUSTOMER_ORDER
            - CHARGING
            - PARKING
            - MANUAL
        removalStrategy:
          $ref: '#/components/schemas/RemovalStrategy'
        derivedProperties:
          $ref: '#/components/schemas/DerivedProperties'
      required:
        - id
        - name
        - filter
        - type
        - icon
        - removalStrategy
    # --Here starts the shared part of the schema for the openAPI spec and the asyncAPI spec --
    # we plan to reference to the very same file in the future to provide a consistent
    # API user experience across the different provided channels to our API
    CreateOperation:
      description: |
        An operation is mainly a non-distinct selection of milestones. In order to represent it's accumulated progress,
        it can derive trackable properties from the selected milestones.
        The **id** and **name** are used to identify the milestone, both uniquely for technical clients and
        human-readable for the user as an entry in the list. The **icon** and **type** should be used to categorize
        operations making them easier to identify.\
        The content of an operation is configured with the **filter**. As long as the operation exists,
        any milestone that matches the filter is considered being part of the operation. Milestones are added to
        and removed from the operation dynamically whenever their matching condition changes. A milestone could be 
        associated to multiple different operations.\
        An operation also contains some top-level properties. The parameter **derivedProperties** defines for each of them if
        it is derived from a specific milestone or assumes another value.
      type: object
      properties:
        id:
          description: >
            A unique id of the operation. This property will not be visible to the user and exists only to 
            identify a specific operation.
          type: string
          format: uuid
        name:
          type: string
          description: >
            The name of the operation which is shown to the user. Not necessarily unique but should be 
            meaningful for the user.
        filter:
          $ref: '#/components/schemas/Filter'
        type:
          type: string
          description: >
            The type of the operation. Allows for filtering in the frontend. Unknown values are possible.
          default: Job
          x-extensible-enum:
            - Job
        icon:
          type: string
          description: >
            Select the icon which should be visible on the operation card. For unknown or unspecified icons,
            the icon "JOB" is displayed.
          default: JOB
          x-extensible-enum:
            - JOB
            - A_B_TRANSPORT
            - TOUR_TRANSPORT
            - PUTAWAY
            - STOCK_COUNTING
            - PICKING
            - CUSTOMER_ORDER
            - CHARGING
            - PARKING
            - MANUAL
        removalStrategy:
          $ref: '#/components/schemas/RemovalStrategy'
        derivedProperties:
          $ref: '#/components/schemas/DerivedProperties'
      required:
        - id
        - name
        - filter

    DeleteOperation:
      type: object
      properties:
        id:
          description: >
            A unique id of the operation. This property will not be visible to the user and exists only to
            identify a specific operation.
          type: string
          format: uuid
      required:
        - id

    Filter:
      type: object
      description: >
        A filter matches a milestone if there is a correlation with exactly the same **kind** and **id**
      properties:
        id:
          type: string
        kind:
          type: string
      required:
        - id
        - kind

    DerivedProperties:
      type: object
      description: |
        Operations have optional toplevel properties containing the most relevant values for the operation.
        For each property it can be defined how and if the value is derived from milestones associated with
        the operation.\
        For all properties the default is set to pull the value from the last milestone.
      properties:
        demandTime:
          $ref: '#/components/schemas/ValueSelector'
        forecast:
          $ref: '#/components/schemas/ValueSelector'
        locations:
          $ref: '#/components/schemas/ValueSelector'
        transportResource:
          $ref: '#/components/schemas/ValueSelector'
        items:
          $ref: '#/components/schemas/ValueSelector'

    ValueSelector:
      type: object
      description: |
        The object contains multiple sources for property values in a specific order. The first property that does not
        evaluate to null will be selected. The order of the properties is given by
        **[milestoneByFilter, milestoneByOrder, constant, empty].**\
        While **milestoneByFilter** and **milestoneByOrder** can be used to reference specific milestones of the operation,
        **constant** can be used to set values independent of the milestones and **empty** can be used to overwrite default values
        with an empty result.
      properties:
        milestoneByFilter:
          $ref: '#/components/schemas/Filter'
        milestoneByOrder:
          type: string
          description: >
            Address the milestone that determines the value according to its position in the operation.
          enum:
            - FIRST
            - LAST
        constant:
          type: string
        empty:
          type: boolean
          description: >
            Will show the property as empty when all the above selectors dont provide a result. Will
            prevent the default behavior from being used.

    UpdateOperationRemovalStrategy:
      type: object
      properties:
        id:
          description: >
            For the use of RestAPI, this field is ignored but for AsyncAPI, it should be set to the Operation id.
          type: string
          format: uuid
        newRemovalStrategy:
          $ref: '#/components/schemas/RemovalStrategy'
      required:
        - newRemovalStrategy
    RemovalStrategy:
      type: string
      description: >
        Per default an operation will be removed when all the containing milestones are finished. When another
        behaviour is wanted use a different removal strategy.
      default: REMOVE_WHEN_FINISHED
      x-extensible-enum:
        - REMOVE_WHEN_FINISHED
        - REMOVE_NEVER
  securitySchemes:
    oauthToken:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: "https://example.com/token"
          scopes:
            FPOS_ADMIN: admin role