swagger: "2.0"

info:
  version: "2.0.0"
  title: "Annotator DB Backend"
  description: "The API that the Annotator DB Backend Service offers."
  contact:
    name: "Infra"
    email: "infrateam@zoox.com"
    url: "https://git.zooxlabs.com/zooxco/driving/tree/master/infra/annotator_db"

basePath: "/api/v2"

consumes:
  - "application/json"
produces:
  - "application/json"


TaskIdSchema: &TASK_ID_SCHEMA
  name: "task_id"
  description: "String uniquely identifying a Task related to this request."
  in: "query"
  type: "string"
  required: true

paths:
  /qna:
    delete:
      summary: "Delete a QuestionAnswer."
      tags:
        - "questionanswer"
      operationId: "qnaDelete"
      parameters:
        - <<: *TASK_ID_SCHEMA
        - name: "qna_id"
          description: "The ID of the QuestionAnswer to delete."
          in: "query"
          required: true
          type: "string"
      responses:
        "204":
          description: "The QuestionAnswer has successfully been deleted."
        # Standard error responses.
        "404":
          description: "Could not find a resource requested by the client."
          schema:
            $ref: "#/definitions/Error"
        "500":
          description: "Server error."
          schema:
            $ref: "#/definitions/Error"
        default:
          description: "Unknown error."
          schema:
            $ref: "#/definitions/Error"

    get:
      summary: "Retreive many QuestionAnswers."
      tags:
        - "questionanswer"
      operationId: "qnaGet"
      parameters:
        - <<: *TASK_ID_SCHEMA
        - name: "state_filter"
          description: "String representation of ::vision::annotator::QuestionState to filter by."
          in: "query"
          required: true
          type: "string"
        - name: "run_id"
          description: "Run ID to filter by."
          in: "query"
          required: false
          type: "string"
        - name: "tags"
          description: "Comma-separated list of (up to 10) tags to filter by. Either both or neither `tags` and `tags_filter_mode must be specified."
          in: "query"
          required: false
          type: "string"
        - name: "tags_filter_mode"
          description: "The tag filtering mode. Either 'AND' or 'OR'. Either both or neither `tags` and `tags_filter_mode must be specified."
          in: "query"
          required: false
          type: "string"
        - name: "start_timestamp"
          description: "Start timestamp to filter by (inclusive). Nanoseconds since epoch."
          in: "query"
          required: false
          type: "integer"
          format: "int64"
        - name: "end_timestamp"
          description: "End timestamp to filter by (inclusive). Nanoseconds since epoch."
          in: "query"
          required: false
          type: "integer"
          format: "int64"
        - $ref: "#/parameters/Offset"
        - $ref: "#/parameters/Limit"
      responses:
        "200":
          description: "Paginated list of base64 encoded ::vision::annotator:QuestionAnswers."
          schema:
            $ref: "#/definitions/PaginatedQnas"
        # Standard error responses.
        "400":
          description: "Invalid argument."
          schema:
            $ref: "#/definitions/Error"
        "404":
          description: "Could not find a resource requested by the client."
          schema:
            $ref: "#/definitions/Error"
        "500":
          description: "Server error."
          schema:
            $ref: "#/definitions/Error"
        default:
          description: "Unknown error."
          schema:
            $ref: "#/definitions/Error"

    put:
      description: "Creates a QuestionAnswer in a Task."
      tags:
        - "questionanswer"
      operationId: "qnaPut"
      parameters:
        - <<: *TASK_ID_SCHEMA
        - name: "qnaPutRequestBody"
          in: "body"
          description: "QuestionAnswer to create and Task ID to create it in."
          required: true
          schema:
            $ref: "#/definitions/Qna"
      responses:
        "204":
          description: "Task has been successfully put."
        # Standard error responses.
        "400":
          description: "Invalid argument."
          schema:
            $ref: "#/definitions/Error"
        "404":
          description: "Could not find a resource requested by the client."
          schema:
            $ref: "#/definitions/Error"
        "409":
          description: "Resoure already exists."
          schema:
            $ref: "#/definitions/Error"
        "500":
          description: "Server error."
          schema:
            $ref: "#/definitions/Error"
        default:
          description: "Unknown error."
          schema:
            $ref: "#/definitions/Error"

  /qna/{id}:
    get:
      description: "Retrieves a QuestionAnswer by ID."
      tags:
        - "questionanswer"
      operationId: "qnaGetById"
      parameters:
        - <<: *TASK_ID_SCHEMA
        - name: "id"
          description: "QuestionAnswer ID."
          in: "path"
          required: true
          type: "string"
      responses:
        "200":
          description: "Base64 encoded ::vision::annotator::QuestionAnswer retrieved from DB."
          schema:
            $ref: "#/definitions/Qna"
        # Standard error responses.
        "400":
          description: "Invalid argument."
          schema:
            $ref: "#/definitions/Error"
        "404":
          description: "Could not find a resource requested by the client."
          schema:
            $ref: "#/definitions/Error"
        "500":
          description: "Server error."
          schema:
            $ref: "#/definitions/Error"
        default:
          description: "Unknown error."
          schema:
            $ref: "#/definitions/Error"

  /qna-versions/{id}:
    get:
      description: "Retrieves all versions (including the latest and deleted) QuestionAnswer by ID, in ascending order."
      tags:
        - "questionanswer"
      operationId: "qnaVersionsGetById"
      parameters:
        - <<: *TASK_ID_SCHEMA
        - name: "id"
          description: "QuestionAnswer ID."
          in: "path"
          required: true
          type: "string"
      responses:
        "200":
          description: "Paginated list of base64 encoded ::vision::annotator:QuestionAnswers."
          schema:
            $ref: "#/definitions/PaginatedQnas"
        # Standard error responses.
        "400":
          description: "Invalid argument."
          schema:
            $ref: "#/definitions/Error"
        "404":
          description: "Could not find a resource requested by the client."
          schema:
            $ref: "#/definitions/Error"
        "500":
          description: "Server error."
          schema:
            $ref: "#/definitions/Error"
        default:
          description: "Unknown error."
          schema:
            $ref: "#/definitions/Error"

  /qnaCmpXchg:
    put:
      description: "Atomically compare and exchange old_qna with new_qna."
      tags:
        - "questionanswer"
      operationId: "qnaCmpXchg"
      parameters:
        - <<: *TASK_ID_SCHEMA
        - name: "qnaCmpXchgBody"
          in: "body"
          description: "Old QuestionAnswer (to replace) and new QuestionAnswer (to replaced with)."
          required: true
          schema:
            $ref: "#/definitions/QnaCmpXchgRequest"
      responses:
        "204":
          description: "Task has been successfully cmpXchg'd."
        # Standard error responses.
        "400":
          description: "Invalid argument."
          schema:
            $ref: "#/definitions/Error"
        "404":
          description: "Could not find a resource requested by the client."
          schema:
            $ref: "#/definitions/Error"
        "409":
          description: "Resoure already exists."
          schema:
            $ref: "#/definitions/Error"
        "500":
          description: "Server error."
          schema:
            $ref: "#/definitions/Error"
        default:
          description: "Unknown error."
          schema:
            $ref: "#/definitions/Error"

  /task:
    get:
      description: "Get the AnnotatorOptions of a Task from the DB."
      tags:
        - "task"
      operationId: "taskGet"
      parameters:
        - <<: *TASK_ID_SCHEMA
          required: false
        - $ref: "#/parameters/Offset"
        - $ref: "#/parameters/Limit"
      responses:
        "200":
          description: "Tasks have been successfully retrieved."
          schema:
            $ref: "#/definitions/PaginatedTasks"
        # Standard error responses.
        "404":
          description: "Could not find a resource requested by the client."
          schema:
            $ref: "#/definitions/Error"
        "500":
          description: "Server error."
          schema:
            $ref: "#/definitions/Error"
        default:
          description: "Unknown error."
          schema:
            $ref: "#/definitions/Error"

    put:
      description: "Insert (overwriting it it already exists) a Task into the DB."
      tags:
        - "task"
      operationId: "taskPut"
      parameters:
        - <<: *TASK_ID_SCHEMA
        - name: "run_id_required"
          description: "Boolean determining whether a Run ID is required for all QNAs in this Task."
          in: "query"
          required: true
          type: "boolean"
          default: false
        - name: "tag_filtering_enabled"
          description: "Whether or not to support filtering QNAs by their tags in this Task."
          in: "query"
          required: true
          type: "boolean"
          default: false
        - name: "timestamp_required"
          description: "Boolean determining whether a timestamp is required for all QNAs in this Task."
          in: "query"
          required: true
          type: "boolean"
          default: false
        - name: "taskPutRequestBody"
          in: "body"
          description: "AnnotatorOptions to put in the DB."
          required: true
          schema:
            $ref: "#/definitions/AnnotatorOptions"
      responses:
        "204":
          description: "Task has been successfully upserted."
        # Standard error responses.
        "400":
          description: "Invalid argument."
          schema:
            $ref: "#/definitions/Error"
        "404":
          description: "Could not find a resource requested by the client."
          schema:
            $ref: "#/definitions/Error"
        "500":
          description: "Server error."
          schema:
            $ref: "#/definitions/Error"
        default:
          description: "Unknown error."
          schema:
            $ref: "#/definitions/Error"

  /task/{task_id}/run-ids:
    get:
      description: "Get list of run-ids in this Task."
      tags:
        - "task"
      operationId: "taskRunIdsGetByTaskId"
      parameters:
        - <<: *TASK_ID_SCHEMA
          in: "path"
        - $ref: "#/parameters/Offset"
        - $ref: "#/parameters/Limit"
      responses:
        "200":
          description: "Tasks have been successfully retrieved."
          schema:
            $ref: "#/definitions/PaginatedRunIds"
        # Standard error responses.
        "404":
          description: "Could not find a resource requested by the client."
          schema:
            $ref: "#/definitions/Error"
        "500":
          description: "Server error."
          schema:
            $ref: "#/definitions/Error"
        default:
          description: "Unknown error."
          schema:
            $ref: "#/definitions/Error"

definitions:
  AnnotatorOptions:
    required:
    - "data"
    properties:
      data:
        description: "Base64 encoded ::vision::annotator::AnnotatorOptions."
        type: "string"

  Error:
    required:
    - "code"
    - "message"
    properties:
      code:
        type: "integer"
        format: "int32"
      message:
        type: "string"

  PaginatedQnas:
    required:
    - "results"
    - "metadata"
    properties:
      results:
        type: "array"
        items:
          $ref: "#/definitions/Qna"
      metadata:
        $ref: "#/definitions/PaginatedListMetadata"

  PaginatedRunIds:
    required:
    - "results"
    - "metadata"
    properties:
      results:
        type: "array"
        items:
          type: "string"
      metadata:
        $ref: "#/definitions/PaginatedListMetadata"

  PaginatedTasks:
    required:
    - "results"
    - "metadata"
    properties:
      results:
        type: "array"
        items:
          $ref: "#/definitions/Task"
      metadata:
        $ref: "#/definitions/PaginatedListMetadata"

  PaginatedListMetadata:
    required:
    - "total"
    properties:
      total:
        description: "Total number of resources available."
        type: "integer"
        format: "int64"

  Qna:
    required:
    - "data"
    properties:
      data:
        description: "Base64 encoded ::vision::annotator::QuestionAnswer."
        type: "string"

  QnaCmpXchgRequest:
    required:
    - "old_qna"
    - "new_qna"
    properties:
      old_qna:
        $ref: "#/definitions/Qna"
      new_qna:
        $ref: "#/definitions/Qna"

  Task:
    required:
      - "name"
      - "annotatorOptions"
    properties:
      name:
        type: "string"
      annotatorOptions:
        $ref: "#/definitions/AnnotatorOptions"

parameters:
  Limit:
    name: "limit"
    description: "The max number of results to return in a single page."
    in: "query"
    required: false
    type: "integer"
    format: "int64"

  Offset:
    name: "offset"
    description: "The offset into paginated results to start from."
    in: "query"
    required: false
    type: "integer"
    format: "int64"

