# Proposed contract, version 1: endpoints, errors, paging, idempotency, security and the capability of every
# operation. Resource schemas were initialized from the data model (docs/06-data) and are kept aligned with it; input
# schemas (*Input, *Request) and views are specific to this contract. Status: proposal for review, not confirmed design.
# Conventions: docs/05-interfaces/choosing-an-interface.md. Vendor extensions: x-moonitoring-audience (who calls),
# x-moonitoring-capability (the capability checked), x-moonitoring-entitlement (the entitlement feature checked),
# x-moonitoring-requirements (the requirements of 1.requisiti-raffinati.txt the operation serves).
openapi: 3.1.0
info:
  title: Farm Submissions API
  version: 1.0.0
  description: 'Submissions to official bodies, such as milk recording: the farm asks for a submission over a period
    in a format, reviews the generated file, sends it and records the recipient''s answer. Disputed facts are sent
    with their winning value and keep their data issue open; a later change marks the submission outdated.'
servers:
- url: https://farm.moonitoring.com/submissions/v1
  description: Prod
- url: https://stage-farm.moonitoring.com/submissions/v1
  description: Stage, through IAP
security:
- bearer: []
tags:
- name: Submissions
  description: What was sent to whom
- name: Formats
  description: The formats we can generate
paths:
  /formats:
    get:
      summary: List submission formats
      operationId: listSubmissionFormats
      tags:
      - Formats
      parameters:
      - name: nation
        in: query
        required: false
        schema:
          type: string
          format: uuid
        description: Only formats of this nation.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/SubmissionFormat'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
      x-moonitoring-audience: any
      x-moonitoring-capability: null
      x-moonitoring-requirements:
      - '60.3'
      - '60.4'
  /organizations/{organization_id}/submissions:
    get:
      summary: List a farm's submissions
      operationId: listSubmissions
      tags:
      - Submissions
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Farm.
      - name: recipient
        in: query
        required: false
        schema:
          type: string
      - name: status
        in: query
        required: false
        schema:
          type: string
          enum:
          - draft
          - sent
          - accepted
          - partially_accepted
          - rejected
        description: Only this status.
      - name: outdated
        in: query
        required: false
        schema:
          type: boolean
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Cursor
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/Limit
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                type: object
                description: One page of items.
                properties:
                  items:
                    type: array
                    items:
                      $ref: '#/components/schemas/OfficialSubmission'
                  next_cursor:
                    type: string
                    description: Where the next page starts; absent on the last page.
                required:
                - items
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - farm.official_submissions.submit
      - farm.canonical_data.read_all
      x-moonitoring-requirements:
      - '60'
      - '1002.14'
    post:
      summary: Prepare a submission
      operationId: createSubmission
      description: Returns the draft; generation may take a moment, the status says when the payload is ready.
      tags:
      - Submissions
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: The Farm.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubmissionRequest'
      responses:
        '202':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OfficialSubmission'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: farm.official_submissions.submit
      x-moonitoring-requirements:
      - '60'
      - '60.5'
      - '60.10'
      - '60.11'
      - '43'
      - '1002.14'
  /submissions/{submission_id}:
    get:
      summary: Read a submission
      operationId: getSubmission
      tags:
      - Submissions
      parameters:
      - name: submission_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OfficialSubmission'
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - farm.official_submissions.submit
      - farm.canonical_data.read_all
      x-moonitoring-requirements:
      - '60'
  /submissions/{submission_id}/payload-url:
    post:
      summary: Download the file
      operationId: getSubmissionPayloadUrl
      tags:
      - Submissions
      parameters:
      - name: submission_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SignedUrl
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: any
      x-moonitoring-capability:
      - farm.official_submissions.submit
      - farm.canonical_data.read_all
      x-moonitoring-requirements:
      - '60.6'
      - '60.7'
  /submissions/{submission_id}/send:
    post:
      summary: Send a submission
      operationId: sendSubmission
      description: Delivers the file to the recipient's channel and records who sent it and when. Publishes `official_submission.sent.v1`.
      tags:
      - Submissions
      parameters:
      - name: submission_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OfficialSubmission'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
      x-moonitoring-audience: organization
      x-moonitoring-capability: farm.official_submissions.submit
      x-moonitoring-requirements:
      - '60.8'
      - '60.14'
      - '60.15'
      - '1002.14'
  /submissions/{submission_id}/response:
    post:
      summary: Record the recipient's answer
      operationId: recordSubmissionResponse
      tags:
      - Submissions
      parameters:
      - name: submission_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SubmissionResponseInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubmissionResponseRecorded'
        '400':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/BadRequest
        '401':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Unauthorized
        '403':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Forbidden
        '404':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/NotFound
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: organization
      x-moonitoring-capability: farm.official_submissions.submit
      x-moonitoring-requirements:
      - '60.8'
      - '60.9'
      - '1002.14'
components:
  schemas:
    OfficialSubmission:
      description: 'Records data sent to an official body, such as milk recording or a registry: the exact file,
        its format, what it included and the recipient''s answer.'
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        farm:
          type: string
          format: uuid
          description: ID of the Organization that is a Farm.
        recipient:
          type: string
          description: The receiving body, e.g. `it.aia`, `nl.crv`.
        format:
          type: string
          description: Format and version, e.g. `aia_pres_2024`. National formats are export mappings, like parsers
            in reverse.
        coverage:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/Period
        payload_path:
          type: string
          description: The exact file sent, in the bucket, immutable.
        payload_hash:
          type: string
        status:
          type: string
          enum:
          - draft
          - sent
          - accepted
          - partially_accepted
          - rejected
        response_path:
          type: string
          description: The answer of the recipient, in the bucket.
        included_events:
          type: array
          items:
            type: string
            format: uuid
          description: ID of the ResolvedEvent.
        included_observations:
          type: array
          items:
            type: string
            format: uuid
          description: ID of the CanonicalObservation.
        outdated:
          type: boolean
          default: false
          description: Set when something it included changes or is cancelled at the source after sending; a DataIssue
            (kind `submission_outdated`) asks for a correction.
        supersedes:
          type: string
          format: uuid
          description: ID of the OfficialSubmission.
        submitted_by:
          type: string
          format: uuid
          description: ID of the User.
        submitted_at:
          type: string
          format: date-time
        created_at:
          type: string
          format: date-time
      required:
      - id
      - farm
      - recipient
      - format
      - coverage
      - payload_path
      - payload_hash
      - status
      - outdated
      - created_at
    SubmissionFormat:
      type: object
      description: A format we can generate for a recipient, as an export mapping.
      properties:
        recipient:
          type: string
          description: e.g. it.aia.
        format:
          type: string
          description: e.g. aia_pres_2024.
        name:
          type: string
        nation:
          type: string
          format: uuid
        description:
          type: string
      required:
      - recipient
      - format
    SubmissionRequest:
      type: object
      description: Generates a draft submission from the resolved events, observations and periods of the period,
        read at the watermark.
      properties:
        recipient:
          type: string
        format:
          type: string
        coverage:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/Period
        supersedes:
          type: string
          format: uuid
      required:
      - recipient
      - format
      - coverage
    SubmissionResponseInput:
      type: object
      description: Records the answer of the recipient; the response file is uploaded through the returned URL.
      properties:
        status:
          type: string
          enum:
          - accepted
          - partially_accepted
          - rejected
        note:
          type: string
      required:
      - status
    SubmissionResponseRecorded:
      type: object
      description: The submission and, when a response file is expected, where to upload it.
      properties:
        submission:
          $ref: '#/components/schemas/OfficialSubmission'
        upload:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SignedUrl
      required:
      - submission
  securitySchemes:
    bearer:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: 'The short-lived token signed by `access`: an Organization user token, a staff token or a client
        token, as the operation''s audience says.'
