# 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 Animals API
  version: 1.0.0
  description: 'The animal registry: animals with their identifiers, breed and profile evidence, groups and memberships,
    ownership and transfers, and the catalogs of species and breeds. Organization users work on the animals their
    Organization owns or manages; staff maintain the catalogs and the bull catalog.'
servers:
- url: https://farm.moonitoring.com/animals/v1
  description: Prod
- url: https://stage-farm.moonitoring.com/animals/v1
  description: Stage, through IAP
security:
- bearer: []
tags:
- name: Animals
  description: The registry
- name: Identifiers
  description: External identifiers of an animal
- name: Ownership
  description: Who owns and manages an animal
- name: Groups
  description: Herds and their members
- name: Catalogs
  description: Species and breeds
paths:
  /organizations/{organization_id}/animals:
    get:
      summary: List an Organization's animals
      operationId: listAnimals
      description: Animals the Organization owns or manages, or may act on through a delegation. A merged animal
        is returned only with `include_merged`; readers follow the survivor.
      tags:
      - Animals
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: 'The farm: the token''s active Organization, or a farm that delegated to it.'
      - name: identifier
        in: query
        required: false
        schema:
          type: string
        description: Any external identifier, as typed; normalized before the search.
      - name: group
        in: query
        required: false
        schema:
          type: string
          format: uuid
        description: Only members of this group now.
      - name: animal_type
        in: query
        required: false
        schema:
          type: string
          format: uuid
        description: Only this species.
      - name: include_merged
        in: query
        required: false
        schema:
          type: boolean
      - name: include_exited
        in: query
        required: false
        schema:
          type: boolean
        description: Also animals whose latest resolved exit is in the past.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/AsOfSeq
      - $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/AnimalView'
                  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.animals.read
      - farm.canonical_data.read_all
      x-moonitoring-requirements:
      - '10'
      - '15'
      - '16'
      - '1002.2'
      - '1006.23'
    post:
      summary: Register an animal
      operationId: registerAnimal
      description: An Organization registers an animal it manages. Staff with `farm.reference_data.manage` register
        catalog animals without ownership, such as bulls, with the Moonitoring Organization in the path. Identical
        scheme-qualified identifiers link to the known animal instead of creating a duplicate.
      tags:
      - Animals
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: 'The farm: the token''s active Organization, or a farm that delegated to it.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnimalRegistration'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnimalView'
        '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: any
      x-moonitoring-capability:
      - farm.animals.update
      - farm.reference_data.manage
      x-moonitoring-requirements:
      - '10'
      - '15'
      - '16'
      - '65'
      - 32.*.4
      - '1002.3'
      - '1006.17'
  /animals/{animal_id}:
    get:
      summary: Read an animal
      operationId: getAnimal
      tags:
      - Animals
      parameters:
      - name: animal_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/AsOfSeq
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnimalView'
        '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.animals.read
      - farm.canonical_data.read_all
      x-moonitoring-requirements:
      - '10'
      - '1002.2'
  /animals/{animal_id}/profile-evidence:
    get:
      summary: List an animal's profile evidence
      operationId: listAnimalProfileEvidence
      description: What each feed says about sex, birth date, breed and parents; the animal's values are chosen
        from it.
      tags:
      - Animals
      parameters:
      - name: animal_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/AsOfSeq
      - $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/AnimalProfileEvidence'
                  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.animals.read
      - farm.canonical_data.read_all
      x-moonitoring-requirements:
      - '65'
      - '10.13'
    post:
      summary: State profile attributes
      operationId: addAnimalProfileEvidence
      tags:
      - Animals
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: animal_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnimalProfileEvidenceInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnimalProfileEvidence'
        '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.animals.update
      x-moonitoring-requirements:
      - '65'
      - 32.*.4
      - '1002.3'
  /animals/{animal_id}/breeds:
    get:
      summary: List an animal's breed composition
      operationId: listAnimalBreeds
      tags:
      - Animals
      parameters:
      - name: animal_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/AsOfSeq
      - $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/BreedMembership'
                  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.animals.read
      - farm.canonical_data.read_all
      x-moonitoring-requirements:
      - '22'
      - '10.6'
  /animals/{animal_id}/history:
    get:
      summary: Read an animal's registry history
      operationId: listAnimalHistory
      description: Every image of the animal row with the write numbers it was valid between, including merges and
        unmerges.
      tags:
      - Animals
      parameters:
      - name: animal_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - $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/Animal'
                  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.animals.read
      - farm.canonical_data.read_all
      x-moonitoring-requirements:
      - '10.10'
      - '1024'
  /animals/{animal_id}/identifiers:
    get:
      summary: List an animal's identifiers
      operationId: listAnimalIdentifiers
      tags:
      - Identifiers
      parameters:
      - name: animal_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: include_invalidated
        in: query
        required: false
        schema:
          type: boolean
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/AsOfSeq
      - $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/ExternalIdentifier'
                  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.animals.read
      - farm.canonical_data.read_all
      x-moonitoring-requirements:
      - '15'
      - '1003'
    post:
      summary: Attach an identifier
      operationId: addAnimalIdentifier
      description: A value that is not a valid official identifier is kept as an integration or unknown identifier,
        never dropped; a low DataIssue is raised.
      tags:
      - Identifiers
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: animal_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExternalIdentifierInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalIdentifier'
        '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: any
      x-moonitoring-capability:
      - farm.animals.update
      - farm.reference_data.manage
      x-moonitoring-requirements:
      - '15'
      - '15.7'
      - '1002.3'
      - '1006.17'
  /identifiers/{identifier_id}/invalidate:
    post:
      summary: Invalidate an identifier
      operationId: invalidateIdentifier
      description: Closes its validity; a replacement of the same type may point to it as previous.
      tags:
      - Identifiers
      parameters:
      - name: identifier_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClosePeriodRequest'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExternalIdentifier'
        '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: any
      x-moonitoring-capability:
      - farm.animals.update
      - farm.reference_data.manage
      x-moonitoring-requirements:
      - '15.5'
      - '15.6'
      - '1002.3'
  /animals/{animal_id}/ownerships:
    get:
      summary: List an animal's ownership periods
      operationId: listAnimalOwnerships
      tags:
      - Ownership
      parameters:
      - name: animal_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/AsOfSeq
      - $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/Ownership'
                  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.animals.read
      - farm.canonical_data.read_all
      x-moonitoring-requirements:
      - '16'
      - 16.*.1
  /animals/{animal_id}/transfers:
    post:
      summary: Transfer an animal
      operationId: transferAnimal
      description: 'Publishes `ownership.transferred.v1`. `farm.ownerships.transfer` is an admin capability: a person''s
        sign-in must be at most five minutes old, otherwise 403 with the problem type reauthentication-required.'
      tags:
      - Ownership
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: animal_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OwnershipTransferRequest'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Ownership'
        '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.ownerships.transfer
      x-moonitoring-requirements:
      - '16'
      - 16.*.1
      - '1002.10'
  /animal-groups/{group_id}/transfers:
    post:
      summary: Transfer a group
      operationId: transferAnimalGroup
      description: '`farm.ownerships.transfer` is an admin capability: a person''s sign-in must be at most five minutes old,
        otherwise 403 with the problem type reauthentication-required.'
      tags:
      - Ownership
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/OwnershipTransferRequest'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Ownership'
        '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.ownerships.transfer
      x-moonitoring-requirements:
      - '16'
      - 16.*.2
      - '1002.10'
  /organizations/{organization_id}/animal-groups:
    get:
      summary: List an Organization's groups
      operationId: listAnimalGroups
      tags:
      - Groups
      parameters:
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: 'The farm: the token''s active Organization, or a farm that delegated to it.'
      - name: status
        in: query
        required: false
        schema:
          type: string
          enum:
          - active
          - archived
        description: Only this status.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/AsOfSeq
      - $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/AnimalGroup'
                  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.animal_groups.read
      - farm.canonical_data.read_all
      x-moonitoring-requirements:
      - '12'
      - 12.*.1
      - '1002.4'
    post:
      summary: Create a group
      operationId: createAnimalGroup
      tags:
      - Groups
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: organization_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
        description: 'The farm: the token''s active Organization, or a farm that delegated to it.'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnimalGroupInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnimalGroup'
        '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.animal_groups.manage
      x-moonitoring-requirements:
      - '12'
      - '1002.15'
  /animal-groups/{group_id}:
    get:
      summary: Read a group
      operationId: getAnimalGroup
      tags:
      - Groups
      parameters:
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/AsOfSeq
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnimalGroup'
        '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.animal_groups.read
      - farm.canonical_data.read_all
      x-moonitoring-requirements:
      - '12'
    patch:
      summary: Update a group
      operationId: updateAnimalGroup
      tags:
      - Groups
      parameters:
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnimalGroupInput'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnimalGroup'
        '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.animal_groups.manage
      x-moonitoring-requirements:
      - '12.3'
      - '12.4'
      - '12.6'
      - '1002.15'
  /animal-groups/{group_id}/archive:
    post:
      summary: Archive a group
      operationId: archiveAnimalGroup
      description: Archiving preserves history.
      tags:
      - Groups
      parameters:
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnimalGroup'
        '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.animal_groups.manage
      x-moonitoring-requirements:
      - '12.5'
      - '1002.15'
  /animal-groups/{group_id}/members:
    get:
      summary: List a group's members
      operationId: listGroupMembers
      tags:
      - Groups
      parameters:
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      - name: at
        in: query
        required: false
        schema:
          type: string
          format: date-time
        description: Members at this time; default now.
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/AsOfSeq
      - $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/AnimalGroupMembership'
                  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.animal_groups.read
      - farm.canonical_data.read_all
      x-moonitoring-requirements:
      - '13'
      - '1002.4'
    post:
      summary: Add an animal to a group
      operationId: addGroupMember
      tags:
      - Groups
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      - name: group_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GroupMemberRequest'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnimalGroupMembership'
        '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.animal_groups.manage_members
      x-moonitoring-requirements:
      - '13'
      - '1002.5'
  /group-memberships/{membership_id}/close:
    post:
      summary: Remove an animal from a group
      operationId: closeGroupMembership
      description: Closing the period ends the membership without losing the history.
      tags:
      - Groups
      parameters:
      - name: membership_id
        in: path
        required: true
        schema:
          type: string
          format: uuid
      requestBody:
        required: false
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ClosePeriodRequest'
      responses:
        '200':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnimalGroupMembership'
        '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.animal_groups.manage_members
      x-moonitoring-requirements:
      - '13.4'
      - '1002.5'
  /animal-types:
    get:
      summary: List species
      operationId: listAnimalTypes
      tags:
      - Catalogs
      parameters:
      - $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/AnimalType'
                  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:
      - '11'
    post:
      summary: Create a species
      operationId: createAnimalType
      tags:
      - Catalogs
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnimalTypeInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnimalType'
        '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
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: farm.reference_data.manage
      x-moonitoring-requirements:
      - '11'
      - '1006.17'
  /breed-types:
    get:
      summary: List breeds
      operationId: listBreedTypes
      tags:
      - Catalogs
      parameters:
      - name: animal_type
        in: query
        required: false
        schema:
          type: string
          format: uuid
        description: Only breeds of this species.
      - $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/AnimalBreedType'
                  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:
      - '14'
    post:
      summary: Create a breed
      operationId: createBreedType
      tags:
      - Catalogs
      parameters:
      - $ref: ../../../../common/v1/schemas.yaml#/components/parameters/IdempotencyKey
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AnimalBreedTypeInput'
      responses:
        '201':
          description: The result.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AnimalBreedType'
        '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
        '409':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/Conflict
        '422':
          $ref: ../../../../common/v1/schemas.yaml#/components/responses/UnprocessableEntity
      x-moonitoring-audience: staff
      x-moonitoring-capability: farm.reference_data.manage
      x-moonitoring-requirements:
      - '14'
      - '1006.17'
components:
  schemas:
    Animal:
      description: The record of one individual animal. Its internal id stays the same when the animal moves between
        Organizations. Sources can disagree about its sex, birth date, breeds and parents, so these values are chosen
        by versioned rules from what every source said (profile evidence); its identifiers come from external identifiers.
        When two records turn out to be the same animal they are linked, never moved or deleted.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        identifiers:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/IdentifiersValues
        animal_type:
          type: string
          format: uuid
          description: ID of the AnimalType.
        sex:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/AnimalSexEnum
          description: Resolved from AnimalProfileEvidence, like `Animal.breed_memberships`, `Animal.birth_date`,
            `Animal.sire` and `Animal.dam`; see `Animal.profile_status`.
        breed_memberships:
          type: array
          items:
            type: string
            format: uuid
          description: 'ID of the BreedMembership. The sum of the known `breed_value` of an animal is between 0
            and 1. The remainder is split among the memberships with unknown `breed_value`; with none, it is of
            unknown breed. No memberships: breed unknown.'
        birth:
          type: string
          format: uuid
          description: Unique. ID of the Offspring. Current resolved projection to one evidence row; other birth
            evidence remains admissible. Empty when the parturition is unknown.
        birth_date:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/EventTime
          description: Known even when the parturition is not, e.g. for purchased or imported animals. Vital status
            derives from non-cancelled resolved death evidence, not the latest farm exit. Sale, destination to slaughter
            and confirmed death are distinct; disputed evidence remains explicitly disputed.
        status:
          type: string
          enum:
          - active
          - merged
          default: active
          description: '`merged`: this record was found to be the same animal as another one (see AnimalLink); readers
            follow the survivor. Rows are never moved or deleted, so a merge can be reverted.'
        system_version:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SystemVersion
          description: 'History of this row: every change keeps the previous version with the write numbers it was
            valid between (SystemVersion), so the animal can be read as it was at any past write. A merge or unmerge
            is such a change.'
        sire:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/ParentReference
          description: 'The father: a registered Animal (e.g. a bull of our catalog) or only the identifier or name
            the source gave. Chosen among the sources'' statements in AnimalProfileEvidence.'
        dam:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/ParentReference
          description: The mother; same rules as sire. Known even without a recorded parturition, e.g. for purchased
            animals (from the official registry).
        profile_status:
          type: string
          enum:
          - corroborated
          - single_source
          - conflict_resolved
          - unresolved
          default: single_source
          description: How sex, birth date, breed and parents were chosen among the sources. `conflict_resolved`
            and unresolved carry a DataIssue (kind `profile_conflict`); each source's statement stays in AnimalProfileEvidence.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - identifiers
      - animal_type
      - status
      - system_version
      - profile_status
      - created_at
      - updated_at
    AnimalType:
      description: Catalog of species, such as bovine. Everything that differs between species (observation types,
        body sites, period types, breeds) is linked to an animal type, so the rest of the model works for any species.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        name:
          type: string
        code:
          type: string
          description: Unique.
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - name
      - code
      - created_at
      - updated_at
    AnimalBreedType:
      description: Catalog of the breeds of each species. Breeds describe the composition of animals and the semen
        of services known only by breed.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        animal_type:
          type: string
          format: uuid
          description: ID of the AnimalType.
        name:
          type: string
          description: '`(animal_type, name)` is unique.'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - animal_type
      - name
      - created_at
      - updated_at
    BreedMembership:
      description: The share of one breed in one animal, as decided from the sources. A purebred animal has one
        membership; a crossbreed has several, whose known fractions add up to at most 1. What each source stated
        stays in profile evidence.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        animal:
          type: string
          format: uuid
          description: ID of the Animal.
        breed_type:
          type: string
          format: uuid
          description: ID of the AnimalBreedType. Must belong to the animal's `animal_type` (see Animal). `(animal,
            breed_type)` is unique.
        breed_value:
          oneOf:
          - type: number
          - type: string
            const: unknown
          description: 'Fraction of the animal belonging to this breed, greater than 0 and at most 1. `unknown`:
            the animal belongs to this breed and the fraction is assumed equal to (1 - sum of the known fractions)
            / (number of unknown fractions) of the same animal. With unknown fractions, the sum of the known ones
            must be less than 1.'
        system_version:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SystemVersion
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - animal
      - breed_type
      - breed_value
      - system_version
      - created_at
      - updated_at
    AnimalProfileEvidence:
      description: 'What one source says about an animal: its sex, birth date, breeds and parents. Like events,
        it is evidence: kept as received, one row per source record, never overwritten, so disagreements between
        sources, or between two cards of the same source, stay visible. The values on Animal are chosen from it
        by versioned rules.'
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        animal:
          type: string
          format: uuid
          description: ID of the Animal.
        sex:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/AnimalSexEnum
        birth_date:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/EventTime
        breeds:
          type: array
          items:
            $ref: ../../../../common/v1/schemas.yaml#/components/schemas/BreedShare
        sire:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/ParentReference
        dam:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/ParentReference
        source_producer:
          type: string
          format: uuid
          description: ID of the SourceProducerEntity.
        source_feed:
          type: string
          format: uuid
          description: ID of the SourceFeed.
        raw_metadata:
          type: string
          format: uuid
          description: ID of the RawMetadata. Required; see lineage.
        raw_locator:
          type: string
        source_record_key:
          type: string
          description: e.g. the card id in the management software. (`source_feed`, `source_record_key`) is the
            logical identity.
        recorded_at:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/EventTime
        content_hash:
          type: string
        status:
          type: string
          enum:
          - final
          - corrected
          - cancelled
          default: final
        revision:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/RecordRevision
        farm:
          type: string
          format: uuid
          description: ID of the Organization that is a Farm. The farm of the feed that delivered the record (=
            `source_feed.farm`), copied here as the key of partitioning, row-level access and erasure; it never
            changes on a revision. See STORAGE.
        created_at:
          type: string
          format: date-time
      required:
      - id
      - animal
      - source_producer
      - source_feed
      - source_record_key
      - content_hash
      - status
      - revision
      - farm
      - created_at
    AnimalGroup:
      description: A set of animals managed together. A herd tracks its members individually; a batch is counted
        as a whole, for species without individual identity. A group keeps its identity when its composition changes,
        and archiving keeps its history.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        identifiers:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/IdentifiersValues
        name:
          type: string
        description:
          type: string
        status:
          type: string
          enum:
          - active
          - archived
        identification_mode:
          type: string
          enum:
          - individual
          - collective
          - both
          description: '`individual`: members are Animals (AnimalGroupMembership). collective: the group is counted,
            not its members (e.g. a poultry flock); its head count comes from GroupMovementEvent. both: some members
            are also identified individually.'
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        type:
          type: string
          enum:
          - Herd
          - Batch
          description: Which kind of AnimalGroup this is (enum, disjoint).
      required:
      - id
      - identifiers
      - name
      - status
      - identification_mode
      - created_at
      - updated_at
    Herd:
      allOf:
      - $ref: '#/components/schemas/AnimalGroup'
      description: A AnimalGroup whose type is Herd.
    Batch:
      allOf:
      - $ref: '#/components/schemas/AnimalGroup'
      - type: object
        properties:
          animal_type:
            type: string
            format: uuid
            description: 'ID of the AnimalType. Required: a collective batch has no Animal rows that carry the species.'
          cycle:
            allOf:
            - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/ObservedPeriod
            description: From placement to depletion (end open while the batch is on the farm).
        required:
        - animal_type
        - cycle
      description: Future work. A AnimalGroup whose type is Batch.
    AnimalGroupMembership:
      description: Places one animal in one group for a period. Closing the period ends the membership without losing
        history, so the composition of a group can be rebuilt for any date.
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        animal:
          type: string
          format: uuid
          description: ID of the Animal.
        animal_group:
          type: string
          format: uuid
          description: ID of the AnimalGroup.
        period:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/Period
          description: Closing the period ends the membership without losing the history.
        source_producer:
          type: string
          format: uuid
          description: ID of the SourceProducerEntity.
        received_at:
          type: string
          format: date-time
          description: Applies to imported evidence.
        system_version:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SystemVersion
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
      - id
      - animal
      - animal_group
      - period
      - system_version
      - created_at
      - updated_at
    ExternalIdentifier:
      description: 'An identifier given to an animal or group outside our system: an official national ID, a farm
        number, an id from management software, an alias such as a bull''s artificial insemination (AI) code, or
        a value we cannot classify. Values are brought to a standard form by versioned rules and carry a validity
        period, because farms and software reuse numbers.'
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        value:
          type: string
          description: 'The external identifier, normalized (see `ExternalIdentifier.normalization_rule`). The value
            as sent stays in the raw file. Official identifiers follow a versioned issuing scheme per nation (`NationalIdentifier.identification_scheme`),
            not one universal format. Strip prefixes/separators or pad zeros only under documented rules for that
            scheme, never by similarity. e.g. EU bovine scheme (Reg. 2017/949): ISO alpha-2 country + 12 digits;
            the numeric country code 380 is rewritten to IT, so 380020990691356 = IT020990691356.'
        organization:
          type: string
          format: uuid
          description: ID of the Organization. Empty for global identifiers (official IDs, bull AI codes and aliases),
            which are the same for every Organization.
        namespace:
          type: string
          description: 'Chosen by our system. Local identifiers: (organization, namespace, value, type) unique only
            over overlapping validity periods.'
        period:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/Period
          description: '`valid_from`: when the third party issued the identifier; `valid_until`: when it was invalidated.'
        previous_same_type_identifier:
          type: string
          format: uuid
          description: Unique. ID of the ExternalIdentifier. Must have the same subtype, Organization and namespace.
        normalization_rule:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/CodedValue
          description: 'Versioned rule; identifies the complete ordered transformation, not just the last operation.
            How the sent value became the stored value. A value that is not a valid official ID is not dropped:
            it is kept as an IntegrationIdentifier or UnknownIdentifier of the feed, so the animal stays identifiable
            there, and a low DataIssue is raised. Only values that identify nothing (empty, "0") are skipped (`invalid_identifier`).
            Farm numbers and software ids (FarmIdentifier, IntegrationIdentifier) are reused by farms: their period
            is required to resolve them.'
        system_version:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SystemVersion
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        type:
          type: string
          enum:
          - NationalIdentifier
          - FarmIdentifier
          - IntegrationIdentifier
          - UnknownIdentifier
          - AliasIdentifier
          - ElectronicIdentifier
          description: Which kind of ExternalIdentifier this is (enum, disjoint + complete).
      required:
      - id
      - value
      - namespace
      - period
      - normalization_rule
      - system_version
      - created_at
      - updated_at
      - type
    NationalIdentifier:
      allOf:
      - $ref: '#/components/schemas/ExternalIdentifier'
      - type: object
        properties:
          nation:
            type: string
            format: uuid
            description: ID of the Nation.
          identification_scheme:
            allOf:
            - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/CodedValue
            description: 'The nation''s scheme fixes the length and the normalisation: a fixed-length scheme (Italy,
              12 digits) rejects other lengths; a variable-length scheme (Germany 10, France 10, Belgium 9, Netherlands
              9–10) is stored left-padded with zeros to 12 digits, the ISO 11784 national-code width, so every source
              compares equal. The country must be an ISO 3166-1 code with a registered scheme; anything else is
              an UnknownIdentifier.'
        required:
        - nation
        - identification_scheme
      description: A ExternalIdentifier whose type is NationalIdentifier.
    FarmIdentifier:
      allOf:
      - $ref: '#/components/schemas/ExternalIdentifier'
      - type: object
        properties:
          farm:
            type: string
            format: uuid
            description: ID of the Organization that is a Farm.
        required:
        - farm
      description: A ExternalIdentifier whose type is FarmIdentifier.
    IntegrationIdentifier:
      allOf:
      - $ref: '#/components/schemas/ExternalIdentifier'
      - type: object
        properties:
          source_channel:
            type: string
            format: uuid
            description: ID of the SourceChannel. Integration identifiers are assigned by the channel (e.g. the
              management software), not by an origin.
        required:
        - source_channel
      description: A ExternalIdentifier whose type is IntegrationIdentifier.
    UnknownIdentifier:
      allOf:
      - $ref: '#/components/schemas/ExternalIdentifier'
      - type: object
        properties:
          unknown_note:
            type: string
      description: A ExternalIdentifier whose type is UnknownIdentifier.
    AliasIdentifier:
      allOf:
      - $ref: '#/components/schemas/ExternalIdentifier'
      - type: object
        properties:
          scheme:
            type: string
            enum:
            - ai_code
            - naab_code
            - interbull_id
            - herdbook_number
            - herdbook_name
            - short_name
            - other
            description: '`interbull_id`: breed + country + sex + 12 digits (e.g. HOLUSAM000123456789; sources also
              write HO840…); `herdbook_number`: a breed association''s registration number (e.g. US Holstein 8 digits).
              Neither is a national ID.'
          learned_from:
            type: string
            enum:
            - source
            - confirmed_pairs
            - deterministic_rule
            default: source
            description: '`confirmed_pairs`: two feeds used these two names for the same service many times (e.g.
              ALTATHUN = THUNDERBIRD); `deterministic_rule`: e.g. DairyComp truncates names to 8 characters (REFLECTO
              = REFLECTOR).'
        required:
        - scheme
        - learned_from
      description: A ExternalIdentifier whose type is AliasIdentifier.
    ElectronicIdentifier:
      allOf:
      - $ref: '#/components/schemas/ExternalIdentifier'
      - type: object
        properties:
          scheme:
            type: string
            enum:
            - iso11784
            - vendor
            description: 'Iso11784: 15 digits, country or manufacturer code (3) + national code (12); when the first
              three digits are a country code (e.g. 380) the last 12 are the national identifier without the ISO
              alpha-2 prefix. vendor: a responder or tag number of one system (Lely 7-digit responder, SCR 8-digit
              tag, DelPro short transponder).'
          vendor:
            type: string
            description: Only for scheme = vendor, e.g. lely, scr.
        required:
        - scheme
      description: A ExternalIdentifier whose type is ElectronicIdentifier.
    Ownership:
      description: 'Records who legally owns an animal or group and which farm manages it, period by period. Ownership
        drives access: members of the legal owner and of the manager farm see the animal according to their role,
        while any other Organization needs a delegation. A transfer closes one period and opens the next at the
        same instant.'
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Key.
        period:
          allOf:
          - $ref: ../../../../common/v1/schemas.yaml#/components/schemas/Period
          description: '`valid_from`: when the ownership started; `valid_until`: when it was transferred to another
            Organization.'
        legal_organization:
          type: string
          format: uuid
          description: ID of the Organization. The legal owner of the animal or group; may be unknown or unrecorded.
        manager_farm:
          type: string
          format: uuid
          description: ID of the Organization that is a Farm. The actual farm that manages the animal or group.
        source_producer:
          type: string
          format: uuid
          description: ID of the SourceProducerEntity.
        system_version:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/SystemVersion
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        type:
          type: string
          enum:
          - AnimalOwnership
          - AnimalGroupOwnership
          description: Which kind of Ownership this is (enum, disjoint + complete).
      required:
      - id
      - period
      - manager_farm
      - system_version
      - created_at
      - updated_at
      - type
    AnimalOwnership:
      allOf:
      - $ref: '#/components/schemas/Ownership'
      - type: object
        properties:
          animal:
            type: string
            format: uuid
            description: ID of the Animal.
        required:
        - animal
      description: A Ownership whose type is AnimalOwnership.
    AnimalGroupOwnership:
      allOf:
      - $ref: '#/components/schemas/Ownership'
      - type: object
        properties:
          animal_group:
            type: string
            format: uuid
            description: ID of the AnimalGroup.
        required:
        - animal_group
      description: A Ownership whose type is AnimalGroupOwnership.
    ExternalIdentifierInput:
      type: object
      description: An identifier to attach, as the source gives it; it is normalized by the scheme's versioned rule.
        `type` says the kind; `nation` and `identification_scheme` apply to a national identifier, `source_channel`
        to an integration identifier, `scheme` to an alias or electronic one.
      properties:
        type:
          type: string
          enum:
          - NationalIdentifier
          - FarmIdentifier
          - IntegrationIdentifier
          - UnknownIdentifier
          - AliasIdentifier
          - ElectronicIdentifier
        value:
          type: string
        namespace:
          type: string
        period:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/Period
        nation:
          type: string
          format: uuid
        identification_scheme:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/CodedValue
        source_channel:
          type: string
          format: uuid
        scheme:
          type: string
        vendor:
          type: string
        unknown_note:
          type: string
      required:
      - type
      - value
    AnimalRegistration:
      type: object
      description: 'Registers an animal typed in the app. The payload is stored as a raw file of the Organization''s
        MoonitoringAppChannel feed and parsed like any other source: the animal, its identifiers, its profile evidence
        and its ownership come from that parse.'
      properties:
        animal_type:
          type: string
          format: uuid
        identifiers:
          type: array
          items:
            $ref: '#/components/schemas/ExternalIdentifierInput'
          minItems: 1
        sex:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/AnimalSexEnum
        birth_date:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/EventTime
        breeds:
          type: array
          items:
            $ref: ../../../../common/v1/schemas.yaml#/components/schemas/BreedShare
        sire:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/ParentReference
        dam:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/ParentReference
        manager_farm:
          type: string
          format: uuid
          description: The farm that manages it; default the Organization when it is a farm.
        legal_organization:
          type: string
          format: uuid
        group:
          type: string
          format: uuid
          description: A group to add it to, optional.
      required:
      - animal_type
      - identifiers
    AnimalProfileEvidenceInput:
      type: object
      description: What the Organization states about an animal's registry attributes, as one more piece of evidence;
        the values on the animal are chosen from all the evidence by the rules. An empty field means not stated.
      properties:
        sex:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/AnimalSexEnum
        birth_date:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/EventTime
        breeds:
          type: array
          items:
            $ref: ../../../../common/v1/schemas.yaml#/components/schemas/BreedShare
        sire:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/ParentReference
        dam:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/ParentReference
        recorded_at:
          $ref: ../../../../common/v1/schemas.yaml#/components/schemas/EventTime
    AnimalView:
      type: object
      description: 'An animal with what the Organization Dashboard shows next to it: its identifiers resolved, its
        breed composition, its current ownership and group memberships.'
      properties:
        animal:
          $ref: '#/components/schemas/Animal'
        identifiers:
          type: array
          items:
            $ref: '#/components/schemas/ExternalIdentifier'
        breed_memberships:
          type: array
          items:
            $ref: '#/components/schemas/BreedMembership'
        ownership:
          $ref: '#/components/schemas/Ownership'
        group_memberships:
          type: array
          items:
            $ref: '#/components/schemas/AnimalGroupMembership'
      required:
      - animal
      - identifiers
      - breed_memberships
    OwnershipTransferRequest:
      type: object
      description: 'Transfers an animal or a group to another Organization: the current period closes and a new
        one starts at the same instant. The receiving Organization sees only registry and genealogy data of the
        time before.'
      properties:
        legal_organization:
          type: string
          format: uuid
          description: The new legal owner; empty when unknown.
        manager_farm:
          type: string
          format: uuid
          description: The farm that will manage it.
        valid_from:
          type: string
          format: date-time
          description: 'Default: now.'
      required:
      - manager_farm
    AnimalGroupInput:
      type: object
      description: 'A group: a herd today; batches are future work.'
      properties:
        name:
          type: string
        description:
          type: string
        identification_mode:
          type: string
          enum:
          - individual
          - collective
          - both
          description: '`individual`: members are Animals (AnimalGroupMembership). collective: the group is counted,
            not its members (e.g. a poultry flock); its head count comes from GroupMovementEvent. both: some members
            are also identified individually.'
        type:
          type: string
          enum:
          - Herd
          - Batch
          description: Which kind of AnimalGroup this is (enum, disjoint).
      required:
      - name
      - identification_mode
      additionalProperties: false
    GroupMemberRequest:
      type: object
      description: Adds an animal to a group from a time.
      properties:
        animal:
          type: string
          format: uuid
        valid_from:
          type: string
          format: date-time
          description: 'Default: now.'
      required:
      - animal
    ClosePeriodRequest:
      type: object
      description: Ends a period now or at a given time.
      properties:
        valid_until:
          type: string
          format: date-time
          description: 'Default: now.'
    AnimalTypeInput:
      type: object
      description: Input to create or change a AnimalType; server-managed fields are left out.
      properties:
        name:
          type: string
        code:
          type: string
          description: Unique.
      required:
      - name
      - code
      additionalProperties: false
    AnimalBreedTypeInput:
      type: object
      description: Input to create or change a AnimalBreedType; server-managed fields are left out.
      properties:
        animal_type:
          type: string
          format: uuid
          description: ID of the AnimalType.
        name:
          type: string
          description: '`(animal_type, name)` is unique.'
      required:
      - animal_type
      - name
      additionalProperties: false
  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.'
