openapi: 3.0.1
info:
  title: Milwaukee Tool State Machines API
  description: >-
    Milwaukee Tool States Language (MTSL) is a
    [JSON](https://tools.ietf.org/html/rfc8259)-based language used to describe
    [state machines](https://en.wikipedia.org/wiki/Finite-state_machine)
    declaratively. Typically, these state machines involve performing some
    interaction with a compatible Milwaukee Tool product. The state machines
    thus defined may be executed by various software clients collectively
    referred to as "interpreters". See the Milwaukee Tool State Machines
    Language Specification for full details. 


    The API defined here allows interpreters a standardized interface for
    accessing and updating MTSL State Machine objects.
  contact:
    email: andrew.moore@milwaukeetool.com
  version: 1.0.0
externalDocs:
  description: MTSL Specification
  url: http://quicklink.milwaukeetool.com/mtsl-spec
servers:
  - url: https://quicklink-api.milwaukeetool.com/v1
  - url: https://quicklink-api-test.milwaukeetool.com/v1
tags:
  - name: state-machine
    description: Access MTSL state-machine objects
    externalDocs:
      description: Learn more
      url: http://quicklink.milwaukeetool.com/mtsl-spec
  - name: product
    description: Manage MSTL-related metadata for products
  - name: chart
    description: Generate charts to visualize a state machine's execution definitions
paths:
  /chart/state-machine:
    get:
      tags:
        - chart
      summary: Generate a chart for an existing state machine
      parameters:
        - name: uuid
          in: query
          description: UUID of the state machine for which to generate a chart
          required: true
          schema:
            type: string
      responses:
        '200':
          description: >-
            Successful operation. The result string represents the chart in
            MermaidJS markdown syntax.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChartResponse'
  /chart:
    post:
      tags:
        - chart
      summary: Generate a chart for an adhoc execution definition
      requestBody:
        description: Execution definition for which to generate a chart
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExecutionDefinition'
        required: true
      responses:
        '200':
          description: >-
            Successful operation. The result string represents the chart in
            MermaidJS markdown syntax.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChartResponse'
  /product/functional-groups:
    get:
      tags:
        - product
      summary: Get the list of functional groups a product is a part of
      parameters:
        - name: productId
          in: query
          description: ProductId for which to find relevant functional groups
          required: false
          schema:
            type: number
            format: int
      responses:
        '200':
          description: >-
            Successful operation. Note: the strings in this array are not
            returned in any particular order.
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
                example:
                  - Baseline
                  - OneKey
                  - Hydraulic
    put:
      tags:
        - product
      summary: Update the list of functional groups a product is a part of
      requestBody:
        description: Product object to be updated or created
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Product'
        required: true
      responses:
        '200':
          description: >-
            Successful operation. Note: the strings in this array are not
            returned in any particular order.
          content:
            application/json:
              schema:
                type: object
                example:
                  result: Success
  /state-machines/functional-group-names:
    get:
      tags:
        - state-machine
      summary: Get the list of functional groups a State Machine may be a part of
      responses:
        '200':
          description: >-
            Successful operation. Note: the strings in this array are not
            returned in any particular order.
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
                  example: Baseline
  /state-machines:
    get:
      tags:
        - state-machine
      summary: >-
        Get a collection of existing state machines relevant to a product or
        user
      parameters:
        - name: productId
          in: query
          description: ProductId for which to find relevant state machines
          required: false
          schema:
            type: number
            format: int
        - name: userId
          in: query
          description: UserId for which to find relevant state machines (email of user)
          required: false
          schema:
            type: string
        - name: intendedUsageLocation
          in: query
          description: >-
            Only include results matching this UsageLocation (Service,
            Engineering, Rework, RGA, ManufacturingProgrammingStation, Audit, or
            Regulatory)
          required: false
          schema:
            type: string
        - name: functionalGroup
          in: query
          description: Only include results matching this functional functionalGroup
          required: false
          schema:
            type: string
      responses:
        '200':
          description: >-
            Successful operation. Note: the objects in this array are not
            returned in any particular order.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/StateMachine'
        '400':
          description: Invalid query string params
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: No state machines not found matching query string params
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ErrorResponse'
  /state-machine:
    get:
      tags:
        - state-machine
      summary: Get a single existing state machine
      parameters:
        - name: ID
          in: query
          description: ID of state machine to return
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StateMachine'
        '400':
          description: Invalid ID supplied
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: State machine not found
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ErrorResponse'
    put:
      tags:
        - state-machine
      summary: Update an existing state machine
      requestBody:
        description: State machine object to be updated
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StateMachine'
        required: true
      responses:
        '200':
          description: >-
            On success, the successfully updated state machine object is
            returned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StateMachine'
        '400':
          description: >-
            Invalid input. Ensure body of POST request is syntactically correct.
            See MTSL Specification for more information.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: >-
            The State Machine does not exist. Use POST to create new State
            Machines.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ErrorResponse'
    post:
      tags:
        - state-machine
      summary: Create a new state machine
      requestBody:
        description: State Machine object to be saved
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StateMachine'
        required: true
      responses:
        '400':
          description: >-
            Invalid input. Ensure body of POST request is syntactically correct.
            See MTSL Specification for more information.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ErrorResponse'
  /state-machine/execution-definition/validate:
    post:
      tags:
        - state-machine
      summary: Determine if execution definition is valid MTSL without saving
      requestBody:
        description: Execution Definition object to be validated
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExecutionDefinition'
        required: true
      responses:
        '200':
          description: The endpoint will always return '200 OK'
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ExecutionDefinitionValidationResponse'
  /state-machine/versions:
    get:
      tags:
        - state-machine
      summary: Get all versions of an existing state machine
      parameters:
        - name: uuid
          in: query
          description: UUID of the state machine for which to retrieve all versions
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/StateMachine'
        '400':
          description: Invalid UUID supplied or UUID not provided
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: State machine not found
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    StateMachine:
      required:
        - ID
        - Name
        - Status
      type: object
      properties:
        CreatedAt:
          type: string
          example: '2022-05-26T14:36:21Z'
        UpdatedAt:
          type: string
          example: '2022-05-26T14:36:21Z'
        ID:
          type: string
          format: UUID
          example: 5267c1fc-89e4-4204-90e3-c2c94b612f25
        Name:
          type: string
          example: My really cool state machine
        Description:
          type: string
          example: This state machine does a bunch of stuff
        Status:
          type: string
          example: Active
          enum:
            - Draft
            - ValidationRequested
            - Active
            - Inactive
        OwningUserId:
          type: string
        OwningProductId:
          type: number
        OwningFunctionalGroup:
          type: string
        Tags:
          type: array
          items:
            type: string
            example: ReallyCool
        IsPublic:
          type: boolean
          example: false
        IntendedUsage:
          $ref: '#/components/schemas/IntendedUsage'
        ExecutionDefinition:
          $ref: '#/components/schemas/ExecutionDefinition'
    ExecutionDefinition:
      required:
        - states
        - startAt
      type: object
      properties:
        StartAt:
          type: string
          example: Hello World
        Comment:
          type: string
          example: >-
            In this example, the state machine contains a single state named
            "Hello World". Because "Hello World" is a Task State, the
            interpreter tries to execute it.
        MTSLLanguageVersion:
          type: string
          default: '1.0'
        TimeoutSeconds:
          type: number
          default: 30
        States:
          $ref: '#/components/schemas/States'
    IntendedUsage:
      type: object
      properties:
        Location:
          type: string
          example: Service
          enum:
            - Service
            - Engineering
            - Rework
            - RGA
            - ManufacturingProgrammingStation
            - Audit
            - Regulatory
        TriggerType:
          type: string
          example: Manual
          enum:
            - Manual
            - Automatic
        Priority:
          type: number
          default: 500
    States:
      type: object
      description: >-
        The collection of State objects which describe the State Machine's
        behavior. See MTSL Specification for full details about the structure of
        this object.
      properties:
        SomeStateName1:
          $ref: '#/components/schemas/State'
        SomeStateName2:
          $ref: '#/components/schemas/State'
        SomeStateNameX:
          $ref: '#/components/schemas/State'
    State:
      description: >-
        A State describes a <u>task</u> (unit of work) or <u>specifies flow
        control</u> (e.g. Choice, Wait, etc). See MTSL Specification for full
        details about the structure of this object.
      required:
        - name
        - stateType
      type: object
      properties:
        Name:
          type: string
          example: State A
        StateType:
          type: string
          example: Task
          enum:
            - Task
            - Choice
            - Map
            - Wait
            - Pass
            - Succeed
            - Fail
        Resource:
          type: string
          example: Product::SendCommand::OpenLinkCommand
        InputPath:
          type: string
          description: >-
            a JSONPath, which is applied to a State's raw input to select some
            or all of it
        Parameters:
          type: object
          description: >-
            a Payload Template which is a JSON object, whose input is the result
            of applying the InputPath to the raw input. If the "parameters"
            field is provided, its payload, after the extraction and embedding,
            becomes the effective input. Note: object structure depends on
            taskType. See MTSL Specification for more information.
        ResultSelector:
          type: object
          description: >-
            a Payload Template, whose input is the result, and whose payload
            replaces and becomes the effective result at the time of execution.
            See MTSL Specification for more information.
        ResultPath:
          type: string
          description: >-
            a JSONPath, which specifies the raw input's combination with or
            replacement by the state's result at the time of execution. See MTSL
            Specification for more information.
        OutputPath:
          type: string
          description: >-
            a JSONPath, which is applied to the state's output after the
            application of ResultPath, producing the effective output which
            serves as the raw input for the next state. See MTSL Specification
            for more information.
        TimeoutSeconds:
          type: number
          default: 30
        Next:
          type: string
          description: The next state to execute (or undefined)
        End:
          type: boolean
          default: true
          description: True if this is the last State (else undefined)
    ErrorResponse:
      type: object
      description: Response object in case of error
      required:
        - code
        - message
      properties:
        code:
          type: number
          example: 0
        message:
          type: string
          example: A message describing what went wrong
        data:
          type: object
          description: Optionally some object with some data.
    ExecutionDefinitionValidationResponse:
      type: object
      description: Response object when validating an Execution Definition
      properties:
        isValid:
          type: boolean
          example: false
        errors:
          type: array
          items:
            type: string
            example: >-
              MISSING_TRANSITION_TARGET: Missing 'StartAt'|'Next'|'Default'
              target: Test
    Product:
      type: object
      description: Object that holds MTSL-related metadata about a Product
      properties:
        ProductId:
          type: number
          example: 1
        FunctionalGroups:
          type: array
          items:
            type: string
          example:
            - Baseline
            - OneKey
    ChartResponse:
      type: object
      properties:
        result:
          type: string
          example: |
            graph TD
            NodeStart[Start] --> Node0(Task 1)
            Node0 --> Node1(Choice 1)
            Node0 --> |on error|Node7(Show Error)
            Node1 --> Node6(Succeed 1)
            Node1 --> Node2(Wait 1)
            Node2 --> Node3(Passthrough)
            Node3 --> Node4(Choice 2)
            Node4 --> Node8(Show Success)
            Node4 --> Node5(Fail 1)
            Node5 --> End[End]
            Node6 --> End[End]
            Node7 --> End[End]
            Node8 --> End[End]
