openapi: 3.1.0
info:
  contact:
    name: CIVITAS Connect
    url: https://civitasconnect.digital
  description: >-
    REST API for the CIVITAS/CORE smart city data management platform. Manages
    datasets, data sources, data structures, users, groups, roles, and
    permissions.
  license:
    name: EUPL-1.2
    url: https://eupl.eu/1.2/en/
  summary: Smart city data management REST API
  title: CIVITAS/CORE Data Management API
  version: 2.0.0
externalDocs:
  description: CIVITAS/CORE Developer Documentation
  url: https://docs.core.civitasconnect.digital/docs_v2/Development/intro
servers:
  - url: /v1
security:
  - oauth2: []
tags:
  - description: Role assignment management endpoints
    name: Assignments
  - description: Group management API
    name: Groups
  - description: Role management endpoints
    name: Roles
  - description: Permission management endpoints
    name: Permissions
  - description: Dataset management endpoints
    name: DataSets
  - description: Style management endpoints
    name: Styles
  - description: First-class CORE Mapping artifacts (content stored in Model Forge)
    name: Mappings
  - description: User management endpoints
    name: Users
  - description: Data structure management endpoints
    name: Data Structures
  - description: The data structures the platform's sinks publish
    name: Published structures
  - description: Pipeline management endpoints
    name: Pipelines
  - description: DataSink management endpoints
    name: DataSinks
  - description: Layer management endpoints
    name: Layers
  - description: Data structure version management endpoints
    name: Data Structure Versions
  - description: Datapool management endpoints
    name: DataPools
  - description: Data source management endpoints
    name: DataSources
paths:
  /assignments:
    get:
      description: >-
        Returns a paginated, filterable list of assignments. Supports sorting
        and specification-based filtering.
      operationId: listAssignments
      parameters:
        - description: Zero-based page index (0..N)
          in: query
          name: page
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
        - description: The size of the page to be returned
          in: query
          name: size
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
        - description: >-
            Sorting criteria in the format: property,(asc|desc). Default sort
            order is ascending. Multiple sort criteria are supported.
          in: query
          name: sort
          required: false
          schema:
            type: array
            default:
              - createdAt,DESC
            items:
              type: string
        - description: Filter by one or more IDs (comma-separated).
          example: 1,2,3
          in: query
          name: id
          schema:
            type: string
            example: 1,2,3
        - description: >-
            Filter by creation date greater than or equal to this value (ISO
            8601).
          in: query
          name: createdAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: Filter by creation date less than or equal to this value (ISO 8601).
          in: query
          name: createdAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: >-
            Filter by modification date greater than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: >-
            Filter by modification date less than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: Filter by role ID (exact match).
          in: query
          name: roleId
          schema:
            type: string
            example: role-123
        - description: Filter by user ID (exact match).
          in: query
          name: userId
          schema:
            type: string
            example: user-456
        - description: Filter by group ID (exact match).
          in: query
          name: groupId
          schema:
            type: string
            example: group-789
        - description: Filter by scope ID (exact match).
          in: query
          name: scopeId
          schema:
            type: string
            example: scope-101112
        - description: >-
            Filter by scope type (exact match). One of: TENANT, DATASET,
            DATASOURCE, DATASTRUCTURE, DATAPOOL.
          in: query
          name: scopeType
          schema:
            type: string
            example: DATASET
        - description: 'Filter by role type (exact match). One of: SYSTEM, DATA.'
          in: query
          name: roleType
          schema:
            type: string
            example: DATA
        - description: >-
            Search in role name, role description, or group name (partial match,
            case-insensitive).
          in: query
          name: q
          schema:
            type: string
            example: admin
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageAssignmentOutputDTO'
          description: Page of assignments returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List all assignments
      tags:
        - Assignments
    post:
      description: >-
        Creates a new assignment and returns it with a Location header pointing
        to the new assignment URI.
      operationId: createAssignment
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/AssignmentInputDTO'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssignmentOutputDTO'
          description: Assignment created successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /assignments
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /assignments
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /assignments
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /assignments
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /assignments
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /assignments
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /assignments
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /assignments
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /assignments
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /assignments
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /assignments
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Create a new assignment
      tags:
        - Assignments
  /assignments/{id}:
    delete:
      description: Permanently deletes a assignment by its UUID.
      operationId: deleteAssignment
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Assignment deleted successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /assignments/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Assignment not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /assignments/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /assignments/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /assignments/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /assignments/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /assignments/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (assignment still in use)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Delete a assignment
      tags:
        - Assignments
    get:
      description: Returns a single assignment identified by its UUID.
      operationId: getAssignment
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AssignmentOutputDTO'
          description: Assignment returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /assignments/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Assignment not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get assignment by ID
      tags:
        - Assignments
  /datapools:
    get:
      description: >-
        Returns a paginated, filterable list of datapools. Supports sorting and
        specification-based filtering.
      operationId: listDataPools
      parameters:
        - description: Zero-based page index (0..N)
          in: query
          name: page
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
        - description: The size of the page to be returned
          in: query
          name: size
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
        - description: >-
            Sorting criteria in the format: property,(asc|desc). Default sort
            order is ascending. Multiple sort criteria are supported.
          in: query
          name: sort
          required: false
          schema:
            type: array
            default:
              - createdAt,DESC
            items:
              type: string
        - description: Filter by one or more IDs (comma-separated).
          example: 1,2,3
          in: query
          name: id
          schema:
            type: string
            example: 1,2,3
        - description: >-
            Filter by creation date greater than or equal to this value (ISO
            8601).
          in: query
          name: createdAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: Filter by creation date less than or equal to this value (ISO 8601).
          in: query
          name: createdAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: >-
            Filter by modification date greater than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: >-
            Filter by modification date less than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: Filter by name (partial match, case-insensitive).
          in: query
          name: name
          schema:
            type: string
            example: mobility
        - description: Filter by description (partial match, case-insensitive).
          in: query
          name: description
          schema:
            type: string
            example: governance
        - description: Search in name or description (partial match, case-insensitive).
          in: query
          name: q
          schema:
            type: string
            example: city
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageDataPoolOutputDTO'
          description: Page of datapools returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List all datapools
      tags:
        - DataPools
    post:
      description: >-
        Creates a new datapool and returns it with a Location header pointing to
        the new datapool URI.
      operationId: createDataPool
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataPoolInputDTO'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataPoolOutputDTO'
          description: Datapool created successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datapools
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datapools
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datapools
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datapools
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datapools
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datapools
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datapools
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datapools
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datapools
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datapools
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datapools
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Create a new datapool
      tags:
        - DataPools
  /datapools/{id}:
    delete:
      description: >-
        Permanently deletes a datapool by its UUID. Fails with 409 Conflict if
        any datasets are still assigned to it.
      operationId: deleteDataPool
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Datapool deleted successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datapools/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Datapool not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datapools/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datapools/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datapools/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datapools/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datapools/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict — datasets are still assigned to this datapool
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Delete a datapool
      tags:
        - DataPools
    get:
      description: Returns a single datapool identified by its UUID.
      operationId: getDataPool
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataPoolOutputDTO'
          description: Datapool returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datapools/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Datapool not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get datapool by ID
      tags:
        - DataPools
    patch:
      description: >-
        Applies a partial JSON update to an existing datapool. Only provided
        fields are modified.
      operationId: patchDataPool
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchDataPoolInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataPoolOutputDTO'
          description: Datapool patched successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datapools/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datapools/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datapools/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datapools/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datapools/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datapools/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datapools/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Datapool not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datapools/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datapools/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datapools/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datapools/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datapools/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Partially update a datapool
      tags:
        - DataPools
    put:
      description: Fully replaces an existing datapool with the provided input.
      operationId: updateDataPool
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataPoolInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataPoolOutputDTO'
          description: Datapool updated successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datapools/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datapools/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datapools/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datapools/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datapools/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datapools/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datapools/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Datapool not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datapools/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datapools/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datapools/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datapools/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datapools/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Replace a datapool
      tags:
        - DataPools
  /datapools/{id}/assignments:
    get:
      description: Returns all role assignments scoped to this datapool.
      operationId: getDataPoolAssignments
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AssignmentOutputDTO'
          description: Assignments returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datapools/{id}/assignments
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Datapool not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get assignments
      tags:
        - DataPools
  /datasets:
    get:
      description: >-
        Returns a paginated, filterable list of datasets. Supports sorting and
        specification-based filtering.
      operationId: listDataSets
      parameters:
        - description: Zero-based page index (0..N)
          in: query
          name: page
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
        - description: The size of the page to be returned
          in: query
          name: size
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
        - description: >-
            Sorting criteria in the format: property,(asc|desc). Default sort
            order is ascending. Multiple sort criteria are supported.
          in: query
          name: sort
          required: false
          schema:
            type: array
            default:
              - createdAt,DESC
            items:
              type: string
        - description: Filter by one or more IDs (comma-separated).
          example: 1,2,3
          in: query
          name: id
          schema:
            type: string
            example: 1,2,3
        - description: >-
            Filter by creation date greater than or equal to this value (ISO
            8601).
          in: query
          name: createdAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: Filter by creation date less than or equal to this value (ISO 8601).
          in: query
          name: createdAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: >-
            Filter by modification date greater than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: >-
            Filter by modification date less than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: Filter by name (partial match, case-insensitive).
          in: query
          name: name
          schema:
            type: string
            example: sensor-data
        - description: Filter by description (partial match, case-insensitive).
          in: query
          name: description
          schema:
            type: string
            example: Temperature sensor readings
        - description: Search in name or description (partial match, case-insensitive).
          in: query
          name: q
          schema:
            type: string
            example: sensor
        - description: >-
            Filter by datapool IDs (comma-separated UUIDs, IN-clause). Returns
            datasets assigned to any of the listed datapools.
          in: query
          name: datapoolIds
          schema:
            type: string
            example: >-
              550e8400-e29b-41d4-a716-446655440000,3fa85f64-5717-4562-b3fc-2c963f66afa6
        - description: Include datasets with pendingSagaType DELETE. Defaults to false.
          in: query
          name: includePendingDelete
          schema:
            type: boolean
            default: false
            example: 'true'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageDataSetOutputDTO'
          description: Page of datasets returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List all datasets
      tags:
        - DataSets
    post:
      description: >-
        Creates a new dataset and returns it with a Location header pointing to
        the new dataset URI.
      operationId: createDataSet
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataSetInputDTO'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSetOutputDTO'
          description: Dataset created successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Create a new dataset
      tags:
        - DataSets
  /datasets/{dataSetId}/datasinks:
    get:
      operationId: listDataSinks
      parameters:
        - description: Zero-based page index (0..N)
          in: query
          name: page
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
        - description: The size of the page to be returned
          in: query
          name: size
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
        - description: >-
            Sorting criteria in the format: property,(asc|desc). Default sort
            order is ascending. Multiple sort criteria are supported.
          in: query
          name: sort
          required: false
          schema:
            type: array
            default:
              - createdAt,DESC
            items:
              type: string
        - description: Filter by one or more IDs (comma-separated).
          example: 1,2,3
          in: query
          name: id
          schema:
            type: string
            example: 1,2,3
        - description: >-
            Filter by creation date greater than or equal to this value (ISO
            8601).
          in: query
          name: createdAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: Filter by creation date less than or equal to this value (ISO 8601).
          in: query
          name: createdAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: >-
            Filter by modification date greater than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: >-
            Filter by modification date less than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageDataSinkOutputDTO'
          description: Page of datasinks returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List all DataSinks for a dataset
      tags:
        - DataSinks
    post:
      operationId: createDataSink
      parameters:
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataSinkInputDTO'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSinkOutputDTO'
          description: Datasink created successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/datasinks
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/datasinks
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/datasinks
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/datasinks
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/datasinks
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/datasinks
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/datasinks
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/datasinks
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/datasinks
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/datasinks
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/datasinks
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Create a new DataSink
      tags:
        - DataSinks
  /datasets/{dataSetId}/datasinks/{id}:
    delete:
      operationId: deleteDataSink
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      responses:
        '204':
          description: Datasink deleted successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Datasink not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Delete a DataSink
      tags:
        - DataSinks
    get:
      operationId: getDataSink
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSinkOutputDTO'
          description: Datasink returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Datasink not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get DataSink by ID
      tags:
        - DataSinks
    patch:
      operationId: patchDataSink
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchDataSinkInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSinkOutputDTO'
          description: Datasink patched successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Datasink not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Partially update a DataSink
      tags:
        - DataSinks
    put:
      operationId: updateDataSink
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataSinkInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSinkOutputDTO'
          description: Datasink updated successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Datasink not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/datasinks/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Replace a DataSink
      tags:
        - DataSinks
  /datasets/{dataSetId}/layers:
    get:
      operationId: listLayers
      parameters:
        - description: Zero-based page index (0..N)
          in: query
          name: page
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
        - description: The size of the page to be returned
          in: query
          name: size
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
        - description: >-
            Sorting criteria in the format: property,(asc|desc). Default sort
            order is ascending. Multiple sort criteria are supported.
          in: query
          name: sort
          required: false
          schema:
            type: array
            default:
              - createdAt,DESC
            items:
              type: string
        - description: Filter by one or more IDs (comma-separated).
          example: 1,2,3
          in: query
          name: id
          schema:
            type: string
            example: 1,2,3
        - description: >-
            Filter by creation date greater than or equal to this value (ISO
            8601).
          in: query
          name: createdAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: Filter by creation date less than or equal to this value (ISO 8601).
          in: query
          name: createdAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: >-
            Filter by modification date greater than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: >-
            Filter by modification date less than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageLayerOutputDTO'
          description: Page of layers returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List all Layers for a dataset
      tags:
        - Layers
    post:
      operationId: createLayer
      parameters:
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LayerInputDTO'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LayerOutputDTO'
          description: Layer created successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/layers
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/layers
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/layers
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/layers
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/layers
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/layers
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/layers
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/layers
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/layers
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/layers
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/layers
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Create a new Layer
      tags:
        - Layers
  /datasets/{dataSetId}/layers/{id}:
    delete:
      operationId: deleteLayer
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      responses:
        '204':
          description: Layer deleted successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/layers/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Layer not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/layers/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Delete a Layer
      tags:
        - Layers
    get:
      operationId: getLayer
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LayerOutputDTO'
          description: Layer returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Layer not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get Layer by ID
      tags:
        - Layers
    patch:
      description: >-
        Applies a partial JSON update to an existing layer. Only provided fields
        are modified.
      operationId: patch_1
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchLayerInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LayerOutputDTO'
          description: Layer patched successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/layers/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Layer not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/layers/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Partially update a layer
      tags:
        - Layers
    put:
      operationId: updateLayer
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LayerInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LayerOutputDTO'
          description: Layer updated successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/layers/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Layer not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/layers/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/layers/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Replace a Layer
      tags:
        - Layers
  /datasets/{dataSetId}/mappings:
    delete:
      description: >-
        Rejected while another artifact still references the mapping — a
        pipeline's mappingRef, for instance. Remove that reference at the
        artifact holding it first; deleting a mapping a pipeline still uses
        would leave the pipeline pointing at nothing.
      operationId: delete
      parameters:
        - in: path
          name: dataSetId
          required: true
          schema:
            type: string
            format: uuid
        - in: query
          name: urn
          required: true
          schema:
            type: string
      responses:
        '200':
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Delete a Mapping artifact by its (logical or versioned) CORE URN
      tags:
        - Mappings
    get:
      description: >-
        With urn, returns that mapping's content. Without urn, returns the URNs
        of every mapping of this DataSet — the only way to find one that no
        pipeline names.
      operationId: get
      parameters:
        - in: path
          name: dataSetId
          required: true
          schema:
            type: string
            format: uuid
        - in: query
          name: urn
          required: false
          schema:
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: >-
        Fetch a Mapping artifact's content by CORE URN, or list this DataSet's
        mappings
      tags:
        - Mappings
    post:
      operationId: create
      parameters:
        - in: path
          name: dataSetId
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: object
              additionalProperties: {}
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: >-
        Create a Mapping artifact from a CORE mapping document; returns its URN
        pins
      tags:
        - Mappings
    put:
      operationId: update
      parameters:
        - in: path
          name: dataSetId
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: object
              additionalProperties: {}
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: string
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Version an existing Mapping artifact (body carries its logicalUrn)
      tags:
        - Mappings
  /datasets/{dataSetId}/pipelines:
    get:
      operationId: listPipelines
      parameters:
        - description: Zero-based page index (0..N)
          in: query
          name: page
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
        - description: The size of the page to be returned
          in: query
          name: size
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
        - description: >-
            Sorting criteria in the format: property,(asc|desc). Default sort
            order is ascending. Multiple sort criteria are supported.
          in: query
          name: sort
          required: false
          schema:
            type: array
            default:
              - createdAt,DESC
            items:
              type: string
        - description: Filter by one or more IDs (comma-separated).
          example: 1,2,3
          in: query
          name: id
          schema:
            type: string
            example: 1,2,3
        - description: >-
            Filter by creation date greater than or equal to this value (ISO
            8601).
          in: query
          name: createdAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: Filter by creation date less than or equal to this value (ISO 8601).
          in: query
          name: createdAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: >-
            Filter by modification date greater than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: >-
            Filter by modification date less than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PagePipelineOutputDTO'
          description: Page of pipelines returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List all pipelines
      tags:
        - Pipelines
    post:
      operationId: createPipeline
      parameters:
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PipelineInputDTO'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PipelineOutputDTO'
          description: Pipeline created successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/pipelines
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/pipelines
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/pipelines
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/pipelines
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/pipelines
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/pipelines
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/pipelines
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/pipelines
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/pipelines
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/pipelines
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/pipelines
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Create a new pipeline
      tags:
        - Pipelines
  /datasets/{dataSetId}/pipelines/{id}:
    delete:
      operationId: deletePipeline
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      responses:
        '204':
          description: Pipeline deleted successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Pipeline not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Delete a pipeline
      tags:
        - Pipelines
    get:
      operationId: getPipeline
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PipelineOutputDTO'
          description: Pipeline returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Pipeline not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get pipeline by ID
      tags:
        - Pipelines
    patch:
      operationId: patchPipeline
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchPipelineInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PipelineOutputDTO'
          description: Pipeline patched successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Pipeline not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Partially update a pipeline
      tags:
        - Pipelines
    put:
      operationId: updatePipeline
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PipelineInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PipelineOutputDTO'
          description: Pipeline updated successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Pipeline not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/pipelines/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Replace a pipeline
      tags:
        - Pipelines
  /datasets/{dataSetId}/styles:
    get:
      operationId: listStyles
      parameters:
        - description: Zero-based page index (0..N)
          in: query
          name: page
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
        - description: The size of the page to be returned
          in: query
          name: size
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
        - description: >-
            Sorting criteria in the format: property,(asc|desc). Default sort
            order is ascending. Multiple sort criteria are supported.
          in: query
          name: sort
          required: false
          schema:
            type: array
            default:
              - createdAt,DESC
            items:
              type: string
        - description: Filter by one or more IDs (comma-separated).
          example: 1,2,3
          in: query
          name: id
          schema:
            type: string
            example: 1,2,3
        - description: >-
            Filter by creation date greater than or equal to this value (ISO
            8601).
          in: query
          name: createdAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: Filter by creation date less than or equal to this value (ISO 8601).
          in: query
          name: createdAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: >-
            Filter by modification date greater than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: >-
            Filter by modification date less than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageStyleOutputDTO'
          description: Page of styles returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List all Styles for a dataset
      tags:
        - Styles
    post:
      operationId: createStyle
      parameters:
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StyleInputDTO'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StyleOutputDTO'
          description: Style created successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/styles
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/styles
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/styles
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/styles
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/styles
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/styles
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/styles
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/styles
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/styles
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/styles
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/styles
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Create a new Style
      tags:
        - Styles
  /datasets/{dataSetId}/styles/{id}:
    delete:
      operationId: deleteStyle
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      responses:
        '204':
          description: Style deleted successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/styles/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Style not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/styles/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Delete a Style
      tags:
        - Styles
    get:
      operationId: getStyle
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StyleOutputDTO'
          description: Style returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Style not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get Style by ID
      tags:
        - Styles
    patch:
      description: >-
        Applies a partial JSON update to an existing style. Only provided fields
        are modified.
      operationId: patch
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchStyleInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StyleOutputDTO'
          description: Style patched successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/styles/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Style not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/styles/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Partially update a style
      tags:
        - Styles
    put:
      operationId: updateStyle
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataSetId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StyleInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StyleOutputDTO'
          description: Style updated successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{dataSetId}/styles/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Parent dataset is not in DRAFT
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Style not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{dataSetId}/styles/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{dataSetId}/styles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A saga is in flight on the parent dataset
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Replace a Style
      tags:
        - Styles
  /datasets/{id}:
    delete:
      description: >-
        Deletes a dataset (204 No Content). A never-provisioned dataset is
        removed immediately. A dataset that still holds a provisioned sink is
        torn down asynchronously via a DELETE saga and removed once the saga
        completes. An AVAILABLE dataset cannot be deleted directly — unrelease
        it first (POST /{id}/unrelease).
      operationId: deleteDataSet
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Dataset deleted successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Dataset not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (saga is in-flight for this dataset)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Delete a dataset
      tags:
        - DataSets
    get:
      description: Returns a single dataset identified by its UUID.
      operationId: getDataSet
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSetOutputDTO'
          description: Dataset returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Dataset not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get dataset by ID
      tags:
        - DataSets
    patch:
      description: >-
        Applies a partial JSON update to an existing dataset. Only provided
        fields are modified.
      operationId: patchDataSet
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchDataSetInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSetOutputDTO'
          description: Dataset patched successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Dataset not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Partially update a dataset
      tags:
        - DataSets
    put:
      description: >-
        Updates a dataset in DRAFT status. For released datasets (READY or
        AVAILABLE), use PATCH /datasets/{id}/released/meta instead.
      operationId: updateDataSet
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataSetInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSetOutputDTO'
          description: Dataset updated successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Dataset not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Update a DRAFT dataset
      tags:
        - DataSets
  /datasets/{id}/apis:
    get:
      description: >-
        Returns the named APIs of a PUBLISHED dataset (lifecycle status
        AVAILABLE), including the server-built previewUrl. Per concept #1379
        only active published APIs are discoverable: a DRAFT/READY dataset
        returns an empty list. Respects the caller's X-Allowed-Scope-Ids;
        unknown or out-of-scope datasets return 404.
      operationId: getDataSetApis
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/NamedApiOutputDTO'
          description: Named APIs returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{id}/apis
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Dataset not found or out of scope
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List a dataset's published named APIs
      tags:
        - DataSets
  /datasets/{id}/assignments:
    get:
      description: Returns all role assignments scoped to this dataset.
      operationId: getDataSetAssignments
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AssignmentOutputDTO'
          description: Assignments returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasets/{id}/assignments
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Dataset not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get assignments
      tags:
        - DataSets
  /datasets/{id}/ready/meta:
    patch:
      description: >-
        Applies a JSON merge patch to the metadata of a dataset in READY status,
        requiring only DATASET_UPDATE — unlike PATCH
        /datasets/{id}/released/meta, which also requires DATASET_RELEASE. An
        omitted field keeps its value. Rejects DRAFT and AVAILABLE datasets. A
        field that is not metadata, such as namedApis, answers 400 — unrelease
        the dataset and edit it in DRAFT.
      operationId: updateReadyDataSetMeta
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchDataSetMetaInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSetOutputDTO'
          description: Dataset metadata updated successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{id}/ready/meta
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{id}/ready/meta
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{id}/ready/meta
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{id}/ready/meta
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{id}/ready/meta
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{id}/ready/meta
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: >-
            Dataset is not READY, the request contains a field that is not
            metadata, or the patched metadata is invalid
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{id}/ready/meta
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{id}/ready/meta
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{id}/ready/meta
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{id}/ready/meta
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{id}/ready/meta
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (saga is in-flight for this dataset)
        '422':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A datapool switch leaves a pipeline DataSource out of scope
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Update READY dataset metadata
      tags:
        - DataSets
  /datasets/{id}/release:
    post:
      description: Transitions the entity from DRAFT to AVAILABLE status.
      operationId: releaseDataSet
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '202':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSetOutputDTO'
          description: >-
            The release was accepted; infrastructure is provisioned
            asynchronously
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{id}/release
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{id}/release
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{id}/release
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{id}/release
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{id}/release
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (saga is in-flight for this dataset)
        '422':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: >-
            A pipeline DataSource is out of the dataset's datapool scope, an
            artifact participating in a pipeline's flow cannot carry a release,
            or a flow reaches further than the walk is configured to follow
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Release
      tags:
        - DataSets
  /datasets/{id}/released/meta:
    patch:
      description: >-
        Applies a JSON merge patch to the metadata of a released entity. An
        omitted field keeps its value. A field that is not metadata answers 400,
        and so does null for assignments or datapoolScope. Only works on
        entities that are not in DRAFT status.
      operationId: updateReleasedDataSetMeta
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchDataSetMetaInputDTO'
        required: true
      responses:
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{id}/released/meta
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{id}/released/meta
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{id}/released/meta
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{id}/released/meta
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{id}/released/meta
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (saga is in-flight for this dataset)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Update released metadata
      tags:
        - DataSets
  /datasets/{id}/stage:
    post:
      description: >-
        Validates the dataset's pipeline configuration, then transitions status
        from DRAFT to READY. The artifacts participating in its flows may still
        be DRAFT; release validates them.
      operationId: stageDataSet
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSetOutputDTO'
          description: The dataset is staged
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasets/{id}/stage
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasets/{id}/stage
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasets/{id}/stage
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasets/{id}/stage
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasets/{id}/stage
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasets/{id}/stage
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: >-
            The dataset carries no name, description or Pipeline, or one of its
            Pipelines has no stored definition
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '422':
          content:
            application/problem+json:
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: A pipeline DataSource is out of the dataset's datapool scope
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Stage a dataset
      tags:
        - DataSets
  /datasets/{id}/unrelease:
    post:
      description: Transitions the entity from AVAILABLE back to DRAFT status.
      operationId: unreleaseDataSet
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{id}/unrelease
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{id}/unrelease
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{id}/unrelease
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{id}/unrelease
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{id}/unrelease
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (saga is in-flight for this dataset)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Unrelease
      tags:
        - DataSets
  /datasets/{id}/unstage:
    post:
      description: Reverts the dataset from READY to DRAFT.
      operationId: unstageDataSet
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasets/{id}/unstage
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasets/{id}/unstage
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasets/{id}/unstage
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasets/{id}/unstage
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasets/{id}/unstage
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (saga is in-flight for this dataset)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Unstage a dataset
      tags:
        - DataSets
  /datasources:
    get:
      description: >-
        Returns a paginated, filterable list of datasources. Supports sorting
        and specification-based filtering.
      operationId: listDataSources
      parameters:
        - description: Zero-based page index (0..N)
          in: query
          name: page
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
        - description: The size of the page to be returned
          in: query
          name: size
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
        - description: >-
            Sorting criteria in the format: property,(asc|desc). Default sort
            order is ascending. Multiple sort criteria are supported.
          in: query
          name: sort
          required: false
          schema:
            type: array
            default:
              - createdAt,DESC
            items:
              type: string
        - description: Filter by one or more IDs (comma-separated).
          example: 1,2,3
          in: query
          name: id
          schema:
            type: string
            example: 1,2,3
        - description: >-
            Filter by creation date greater than or equal to this value (ISO
            8601).
          in: query
          name: createdAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: Filter by creation date less than or equal to this value (ISO 8601).
          in: query
          name: createdAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: >-
            Filter by modification date greater than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: >-
            Filter by modification date less than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: Filter by name (partial match, case-insensitive).
          in: query
          name: name
          schema:
            type: string
            example: mqtt-sensor
        - description: Filter by description (partial match, case-insensitive).
          in: query
          name: description
          schema:
            type: string
            example: Temperature sensor
        - description: Search in name or description (partial match, case-insensitive).
          in: query
          name: q
          schema:
            type: string
            example: sensor
        - description: Filter by status (exact match).
          in: query
          name: dataSourceStatus
          schema:
            type: string
            enum:
              - DRAFT
              - AVAILABLE
        - description: Filter by connector type (exact match).
          in: query
          name: connectorType
          schema:
            type: string
            enum:
              - MQTT
              - SQL
        - description: >-
            Filter by DataPool scope. Returns DataSources with scope type ALL,
            or SPECIFIC DataSources that include this DataPool.
          in: query
          name: datapoolId
          schema:
            type: string
            format: uuid
            example: 550e8400-e29b-41d4-a716-446655440000
        - description: Filter by DataPool scope type (exact match).
          in: query
          name: datapoolScopeType
          schema:
            type: string
            enum:
              - ALL
              - NONE
              - SPECIFIC
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageDataSourceOutputDTO'
          description: Page of datasources returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List all datasources
      tags:
        - DataSources
    post:
      description: >-
        Creates a new datasource and returns it with a Location header pointing
        to the new datasource URI.
      operationId: createDataSource
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataSourceInputDTO'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSourceOutputDTO'
          description: Datasource created successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasources
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasources
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasources
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasources
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasources
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasources
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasources
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasources
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasources
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasources
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasources
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Create a new datasource
      tags:
        - DataSources
  /datasources/{id}:
    delete:
      description: Permanently deletes a datasource by its UUID.
      operationId: deleteDataSource
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Datasource deleted successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasources/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Datasource not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasources/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasources/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasources/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasources/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasources/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (datasource still in use)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Delete a datasource
      tags:
        - DataSources
    get:
      description: Returns a single datasource identified by its UUID.
      operationId: getDataSource
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSourceOutputDTO'
          description: Datasource returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasources/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Datasource not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get datasource by ID
      tags:
        - DataSources
    patch:
      description: >-
        Applies a partial JSON update to an existing datasource. Only provided
        fields are modified.
      operationId: patchDataSource
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchDataSourceInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSourceOutputDTO'
          description: Datasource patched successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasources/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasources/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasources/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasources/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasources/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasources/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasources/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Datasource not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasources/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasources/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasources/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasources/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasources/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Partially update a datasource
      tags:
        - DataSources
    put:
      description: Fully replaces an existing datasource with the provided input.
      operationId: updateDataSource
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataSourceInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSourceOutputDTO'
          description: Datasource updated successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datasources/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datasources/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datasources/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datasources/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datasources/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datasources/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasources/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Datasource not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datasources/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datasources/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datasources/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datasources/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datasources/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Replace a datasource
      tags:
        - DataSources
  /datasources/{id}/assignments:
    get:
      description: Returns all role assignments scoped to this datasource.
      operationId: getDataSourceAssignments
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AssignmentOutputDTO'
          description: Assignments returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datasources/{id}/assignments
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Datasource not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get assignments
      tags:
        - DataSources
  /datasources/{id}/release:
    post:
      description: Transitions the entity from DRAFT to AVAILABLE status.
      operationId: releaseDataSource
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSourceOutputDTO'
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Release
      tags:
        - DataSources
  /datasources/{id}/released/meta:
    patch:
      description: >-
        Applies a JSON merge patch to the metadata of a released entity. An
        omitted field keeps its value. A field that is not metadata answers 400,
        and so does null for assignments or datapoolScope. Only works on
        entities that are not in DRAFT status.
      operationId: updateReleasedDataSourceMeta
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchDataSourceMetaInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSourceOutputDTO'
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Update released metadata
      tags:
        - DataSources
  /datasources/{id}/unrelease:
    post:
      description: Transitions the entity from AVAILABLE back to DRAFT status.
      operationId: unreleaseDataSource
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataSourceOutputDTO'
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Unrelease
      tags:
        - DataSources
  /datastructures:
    get:
      description: >-
        Returns a paginated, filterable list of data structures. Supports
        sorting and specification-based filtering.
      operationId: listDataStructures
      parameters:
        - description: Zero-based page index (0..N)
          in: query
          name: page
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
        - description: The size of the page to be returned
          in: query
          name: size
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
        - description: >-
            Sorting criteria in the format: property,(asc|desc). Default sort
            order is ascending. Multiple sort criteria are supported.
          in: query
          name: sort
          required: false
          schema:
            type: array
            default:
              - createdAt,DESC
            items:
              type: string
        - description: Filter by one or more IDs (comma-separated).
          example: 1,2,3
          in: query
          name: id
          schema:
            type: string
            example: 1,2,3
        - description: >-
            Filter by creation date greater than or equal to this value (ISO
            8601).
          in: query
          name: createdAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: Filter by creation date less than or equal to this value (ISO 8601).
          in: query
          name: createdAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: >-
            Filter by modification date greater than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: >-
            Filter by modification date less than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: Filter by name (partial match, case-insensitive).
          in: query
          name: name
          schema:
            type: string
            example: My Data Structure
        - description: Filter by description (partial match, case-insensitive).
          in: query
          name: description
          schema:
            type: string
            example: Data structure description
        - description: Search in name or description (partial match, case-insensitive).
          in: query
          name: q
          schema:
            type: string
            example: structure
        - description: Filter by status (exact match).
          in: query
          name: dataStructureStatus
          schema:
            type: string
            enum:
              - DRAFT
              - AVAILABLE
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageDataStructureOutputDTO'
          description: Page of data structures returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List all data structures
      tags:
        - Data Structures
    post:
      description: >-
        Creates a new data structure and returns it with a Location header
        pointing to the new data structure URI.
      operationId: createDataStructure
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataStructureInputDTO'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStructureOutputDTO'
          description: Data structure created successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datastructures
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datastructures
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datastructures
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datastructures
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datastructures
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datastructures
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datastructures
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datastructures
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datastructures
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datastructures
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datastructures
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Create a new data structure
      tags:
        - Data Structures
  /datastructures/{dataStructureId}/versions:
    post:
      operationId: createDataStructureVersion
      parameters:
        - in: path
          name: dataStructureId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataStructureVersionInputDTO'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStructureVersionOutputDTO'
          description: Data structure version created successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datastructures/{dataStructureId}/versions
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datastructures/{dataStructureId}/versions
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datastructures/{dataStructureId}/versions
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datastructures/{dataStructureId}/versions
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datastructures/{dataStructureId}/versions
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datastructures/{dataStructureId}/versions
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datastructures/{dataStructureId}/versions
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datastructures/{dataStructureId}/versions
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datastructures/{dataStructureId}/versions
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datastructures/{dataStructureId}/versions
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datastructures/{dataStructureId}/versions
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Create a new data structure version
      tags:
        - Data Structure Versions
  /datastructures/{dataStructureId}/versions/{id}:
    get:
      operationId: getDataStructureVersion
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataStructureId
          required: true
          schema:
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStructureVersionOutputDTO'
          description: Data structure version returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Data structure version not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get data structure version by ID
      tags:
        - Data Structure Versions
    patch:
      operationId: patchDataStructureVersion
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataStructureId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchDataStructureVersionInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStructureVersionOutputDTO'
          description: Data structure version patched successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Data structure version not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Partially update a data structure version
      tags:
        - Data Structure Versions
    put:
      operationId: updateDataStructureVersion
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: dataStructureId
          required: true
          schema:
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataStructureVersionInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStructureVersionOutputDTO'
          description: Data structure version updated successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Data structure version not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datastructures/{dataStructureId}/versions/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Replace a data structure version
      tags:
        - Data Structure Versions
  /datastructures/{dataStructureId}/versions/{versionId}/release:
    post:
      description: >-
        Releases a data structure version by setting status to AVAILABLE.
        Requires a model (JSON schema) with exactly one root Element that
        reaches every other member.
      operationId: releaseDataStructureVersion
      parameters:
        - in: path
          name: dataStructureId
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: versionId
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStructureVersionOutputDTO'
          description: Data structure version released successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/release
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/release
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/release
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/release
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/release
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/release
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: >-
            Invalid input (e.g. already released, missing model, no root
            Element, or members the root Element does not reach)
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/release
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Data structure version not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/release
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/release
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/release
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/release
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/release
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: The version's model is missing from the model registry
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Release a data structure version
      tags:
        - Data Structure Versions
  /datastructures/{dataStructureId}/versions/{versionId}/released/meta:
    patch:
      description: >-
        Applies a JSON merge patch to the description of a released data
        structure version (AVAILABLE status). An omitted field keeps its value.
        The description is the only field of a released version that can change;
        a request that contains any other field answers 400. For DRAFT versions,
        use PATCH /datastructures/{dataStructureId}/versions/{versionId}
        instead.
      operationId: updateDataStructureVersionReleasedMeta
      parameters:
        - in: path
          name: dataStructureId
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: versionId
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchDataStructureVersionMetaInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStructureVersionOutputDTO'
          description: Released version metadata updated successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/released/meta
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/released/meta
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/released/meta
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/released/meta
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/released/meta
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/released/meta
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: >-
            Invalid input (e.g. version is DRAFT, or the request contains a
            field other than description)
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/released/meta
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Data structure version not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/released/meta
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/released/meta
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/released/meta
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/released/meta
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/released/meta
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Update metadata of a released data structure version
      tags:
        - Data Structure Versions
  /datastructures/{dataStructureId}/versions/{versionId}/unrelease:
    post:
      description: >-
        Unreleases a data structure version by setting status back to DRAFT.
        Cannot unrelease if this is the only released version of a released
        DataStructure - unrelease the DataStructure first in that case.
      operationId: unreleaseDataStructureVersion
      parameters:
        - in: path
          name: dataStructureId
          required: true
          schema:
            type: string
            format: uuid
        - in: path
          name: versionId
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStructureVersionOutputDTO'
          description: Data structure version unreleased successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/unrelease
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/unrelease
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/unrelease
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/unrelease
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/unrelease
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/unrelease
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input (e.g. already in DRAFT or only released version)
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/unrelease
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Data structure version not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/unrelease
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/unrelease
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/unrelease
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/unrelease
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: >-
                      /datastructures/{dataStructureId}/versions/{versionId}/unrelease
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (version is in use by a DataSource)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Unrelease a data structure version
      tags:
        - Data Structure Versions
  /datastructures/{id}:
    delete:
      description: Permanently deletes a data structure by its UUID.
      operationId: deleteDataStructure
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Data structure deleted successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datastructures/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Data structure not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datastructures/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datastructures/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datastructures/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datastructures/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datastructures/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (data structure still in use)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Delete a data structure
      tags:
        - Data Structures
    get:
      description: Returns a single data structure identified by its UUID.
      operationId: getDataStructure
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStructureOutputDTO'
          description: Data structure returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datastructures/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Data structure not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get data structure by ID
      tags:
        - Data Structures
    patch:
      description: >-
        Applies a partial JSON update to an existing data structure. Only
        provided fields are modified.
      operationId: patchDataStructure
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchDataStructureInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStructureOutputDTO'
          description: Data structure patched successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datastructures/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datastructures/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datastructures/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datastructures/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datastructures/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datastructures/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datastructures/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Data structure not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datastructures/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datastructures/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datastructures/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datastructures/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datastructures/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Partially update a data structure
      tags:
        - Data Structures
    put:
      description: Fully replaces an existing data structure with the provided input.
      operationId: updateDataStructure
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DataStructureInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStructureOutputDTO'
          description: Data structure updated successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /datastructures/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /datastructures/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /datastructures/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /datastructures/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /datastructures/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /datastructures/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datastructures/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Data structure not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /datastructures/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /datastructures/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /datastructures/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /datastructures/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /datastructures/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Replace a data structure
      tags:
        - Data Structures
  /datastructures/{id}/assignments:
    get:
      description: Returns all role assignments scoped to this data structure.
      operationId: getDataStructureAssignments
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/AssignmentOutputDTO'
          description: Assignments returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /datastructures/{id}/assignments
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Data structure not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get assignments
      tags:
        - Data Structures
  /datastructures/{id}/release:
    post:
      description: Transitions the entity from DRAFT to AVAILABLE status.
      operationId: releaseDataStructure
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStructureOutputDTO'
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Release
      tags:
        - Data Structures
  /datastructures/{id}/released/meta:
    patch:
      description: >-
        Applies a JSON merge patch to the metadata of a released entity. An
        omitted field keeps its value. A field that is not metadata answers 400,
        and so does null for assignments or datapoolScope. Only works on
        entities that are not in DRAFT status.
      operationId: updateReleasedDataStructureMeta
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchDataStructureMetaInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStructureOutputDTO'
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Update released metadata
      tags:
        - Data Structures
  /datastructures/{id}/unrelease:
    post:
      description: Transitions the entity from AVAILABLE back to DRAFT status.
      operationId: unreleaseDataStructure
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/DataStructureOutputDTO'
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Unrelease
      tags:
        - Data Structures
  /groups:
    get:
      description: >-
        Returns a paginated, filterable list of groups. Supports sorting and
        specification-based filtering.
      operationId: listGroups
      parameters:
        - description: Zero-based page index (0..N)
          in: query
          name: page
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
        - description: The size of the page to be returned
          in: query
          name: size
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
        - description: >-
            Sorting criteria in the format: property,(asc|desc). Default sort
            order is ascending. Multiple sort criteria are supported.
          in: query
          name: sort
          required: false
          schema:
            type: array
            default:
              - createdAt,DESC
            items:
              type: string
        - description: Filter by one or more IDs (comma-separated).
          example: 1,2,3
          in: query
          name: id
          schema:
            type: string
            example: 1,2,3
        - description: >-
            Filter by creation date greater than or equal to this value (ISO
            8601).
          in: query
          name: createdAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: Filter by creation date less than or equal to this value (ISO 8601).
          in: query
          name: createdAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: >-
            Filter by modification date greater than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: >-
            Filter by modification date less than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: Filter by name (partial match, case-insensitive).
          in: query
          name: name
          schema:
            type: string
            example: Engineering
        - description: Filter by description (partial match, case-insensitive).
          in: query
          name: description
          schema:
            type: string
            example: Development team
        - description: Filter by contact user ID (exact match).
          in: query
          name: contactUserId
          schema:
            type: string
            example: user-123
        - description: Filter by member user ID(s), comma-separated.
          in: query
          name: memberIds
          schema:
            type: string
            example: user-456
        - description: Search in name or description (partial match, case-insensitive).
          in: query
          name: q
          schema:
            type: string
            example: team
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageGroupOutputDTO'
          description: Page of groups returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List all groups
      tags:
        - Groups
    post:
      description: >-
        Creates a new group and returns it with a Location header pointing to
        the new group URI.
      operationId: createGroup
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GroupInputDTO'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupOutputDTO'
          description: Group created successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /groups
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /groups
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /groups
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /groups
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /groups
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /groups
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /groups
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /groups
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /groups
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /groups
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /groups
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Create a new group
      tags:
        - Groups
  /groups/{groupId}/assignments:
    put:
      description: Replaces all role assignments for a group using diff-based semantics.
      operationId: replaceGroupAssignments
      parameters:
        - in: path
          name: groupId
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                $ref: '#/components/schemas/AssignmentGroupInputDTO'
              uniqueItems: true
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupOutputDTO'
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Replace group assignments
      tags:
        - Groups
  /groups/{id}:
    delete:
      description: Permanently deletes a group by its UUID.
      operationId: deleteGroup
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Group deleted successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /groups/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Group not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /groups/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /groups/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /groups/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /groups/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /groups/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (group still in use)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Delete a group
      tags:
        - Groups
    get:
      description: Returns a single group identified by its UUID.
      operationId: getGroup
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupOutputDTO'
          description: Group returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /groups/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Group not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get group by ID
      tags:
        - Groups
    patch:
      description: >-
        Applies a partial JSON update to an existing group. Only provided fields
        are modified.
      operationId: patchGroup
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchGroupInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupOutputDTO'
          description: Group patched successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /groups/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /groups/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /groups/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /groups/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /groups/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /groups/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /groups/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Group not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /groups/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /groups/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /groups/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /groups/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /groups/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Partially update a group
      tags:
        - Groups
    put:
      description: Fully replaces an existing group with the provided input.
      operationId: updateGroup
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/GroupInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GroupOutputDTO'
          description: Group updated successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /groups/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /groups/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /groups/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /groups/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /groups/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /groups/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /groups/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Group not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /groups/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /groups/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /groups/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /groups/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /groups/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Replace a group
      tags:
        - Groups
  /permissions:
    get:
      description: Returns a filterable, sorted list of permissions.
      operationId: listPermissions
      parameters:
        - in: query
          name: sort
          required: true
          schema:
            $ref: '#/components/schemas/Sort'
        - description: Filter by one or more IDs (comma-separated).
          example: 1,2,3
          in: query
          name: id
          schema:
            type: string
            example: 1,2,3
        - description: >-
            Filter by creation date greater than or equal to this value (ISO
            8601).
          in: query
          name: createdAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: Filter by creation date less than or equal to this value (ISO 8601).
          in: query
          name: createdAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: >-
            Filter by modification date greater than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: >-
            Filter by modification date less than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: Filter by name (partial match, case-insensitive).
          in: query
          name: name
          schema:
            type: string
            example: read
        - description: Filter by description (partial match, case-insensitive).
          in: query
          name: description
          schema:
            type: string
            example: Allows read access
        - description: Search in name or description (partial match, case-insensitive).
          in: query
          name: q
          schema:
            type: string
            example: read
        - description: Filter by permission type (exact match).
          in: query
          name: permissionType
          schema:
            type: string
            enum:
              - SYSTEM
              - DATA
        - description: Filter by category (exact match).
          in: query
          name: category
          schema:
            type: string
            enum:
              - TENANT_ADMINISTRATION
              - DATA
        - description: Filter by source (exact match).
          in: query
          name: source
          schema:
            type: string
            enum:
              - INTERNAL
              - DATASET_DASHBOARD
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PermissionOutputDTO'
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List all permissions
      tags:
        - Permissions
  /permissions/{id}:
    get:
      description: Returns a single permission identified by its UUID.
      operationId: getPermission
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PermissionOutputDTO'
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get permission by ID
      tags:
        - Permissions
  /published-structures:
    get:
      operationId: listPublishedStructures
      responses:
        '200':
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/PublishingSinkOutput'
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List the sinks that publish data structures, with their structures
      tags:
        - Published structures
  /published-structures/{key}:
    get:
      operationId: getPublishedStructure
      parameters:
        - in: path
          name: key
          required: true
          schema:
            type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                type: object
                additionalProperties: {}
          description: OK
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get the model document of a published data structure
      tags:
        - Published structures
  /roles:
    get:
      description: >-
        Returns a paginated, filterable list of roles. Supports sorting and
        specification-based filtering.
      operationId: listRoles
      parameters:
        - description: Zero-based page index (0..N)
          in: query
          name: page
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
        - description: The size of the page to be returned
          in: query
          name: size
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
        - description: >-
            Sorting criteria in the format: property,(asc|desc). Default sort
            order is ascending. Multiple sort criteria are supported.
          in: query
          name: sort
          required: false
          schema:
            type: array
            default:
              - createdAt,DESC
            items:
              type: string
        - description: Filter by one or more IDs (comma-separated).
          example: 1,2,3
          in: query
          name: id
          schema:
            type: string
            example: 1,2,3
        - description: >-
            Filter by creation date greater than or equal to this value (ISO
            8601).
          in: query
          name: createdAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: Filter by creation date less than or equal to this value (ISO 8601).
          in: query
          name: createdAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: >-
            Filter by modification date greater than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: >-
            Filter by modification date less than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: Filter by name (partial match, case-insensitive).
          in: query
          name: name
          schema:
            type: string
            example: admin
        - description: Filter by description (partial match, case-insensitive).
          in: query
          name: description
          schema:
            type: string
            example: Full access
        - description: Filter by role type (exact match, comma-separated for multiple).
          in: query
          name: roleType
          schema:
            type: string
            example: SYSTEM
        - description: Search in name or description (partial match, case-insensitive).
          in: query
          name: q
          schema:
            type: string
            example: admin
        - description: Filter by readonly flag (exact match).
          in: query
          name: readonly
          schema:
            type: boolean
            example: 'true'
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageRoleOutputDTO'
          description: Page of roles returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List all roles
      tags:
        - Roles
    post:
      description: >-
        Creates a new role and returns it with a Location header pointing to the
        new role URI.
      operationId: createRole
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoleInputDTO'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoleOutputDTO'
          description: Role created successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /roles
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /roles
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /roles
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /roles
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /roles
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /roles
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /roles
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /roles
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /roles
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /roles
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /roles
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Create a new role
      tags:
        - Roles
  /roles/{id}:
    delete:
      description: Permanently deletes a role by its UUID.
      operationId: deleteRole
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: Role deleted successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /roles/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Role not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /roles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /roles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /roles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /roles/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /roles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (role still in use)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Delete a role
      tags:
        - Roles
    get:
      description: Returns a single role identified by its UUID.
      operationId: getRole
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoleOutputDTO'
          description: Role returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /roles/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Role not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get role by ID
      tags:
        - Roles
    patch:
      description: >-
        Applies a partial JSON update to an existing role. Only provided fields
        are modified.
      operationId: patchRole
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchRoleInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoleOutputDTO'
          description: Role patched successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /roles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /roles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /roles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /roles/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /roles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /roles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /roles/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Role not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /roles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /roles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /roles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /roles/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /roles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Partially update a role
      tags:
        - Roles
    put:
      description: Fully replaces an existing role with the provided input.
      operationId: updateRole
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RoleInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoleOutputDTO'
          description: Role updated successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /roles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /roles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /roles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /roles/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /roles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /roles/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /roles/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Role not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /roles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /roles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /roles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /roles/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /roles/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Replace a role
      tags:
        - Roles
  /users:
    get:
      description: >-
        Returns a paginated, filterable list of users. Supports sorting and
        specification-based filtering.
      operationId: listUsers
      parameters:
        - description: Zero-based page index (0..N)
          in: query
          name: page
          required: false
          schema:
            type: integer
            default: 0
            minimum: 0
        - description: The size of the page to be returned
          in: query
          name: size
          required: false
          schema:
            type: integer
            default: 20
            minimum: 1
        - description: >-
            Sorting criteria in the format: property,(asc|desc). Default sort
            order is ascending. Multiple sort criteria are supported.
          in: query
          name: sort
          required: false
          schema:
            type: array
            default:
              - createdAt,DESC
            items:
              type: string
        - description: Filter by one or more IDs (comma-separated).
          example: 1,2,3
          in: query
          name: id
          schema:
            type: string
            example: 1,2,3
        - description: >-
            Filter by creation date greater than or equal to this value (ISO
            8601).
          in: query
          name: createdAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: Filter by creation date less than or equal to this value (ISO 8601).
          in: query
          name: createdAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: >-
            Filter by modification date greater than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtFrom
          schema:
            type: string
            format: date-time
            example: '2024-01-01T00:00:00Z'
        - description: >-
            Filter by modification date less than or equal to this value (ISO
            8601).
          in: query
          name: modifiedAtTo
          schema:
            type: string
            format: date-time
            example: '2024-12-31T23:59:59Z'
        - description: Filter by first name (partial match, case-insensitive).
          in: query
          name: firstName
          schema:
            type: string
            example: John
        - description: Filter by last name (partial match, case-insensitive).
          in: query
          name: lastName
          schema:
            type: string
            example: Doe
        - description: Filter by email (exact match, case-insensitive).
          in: query
          name: email
          schema:
            type: string
            example: john.doe@example.com
        - description: Search in full name, or email (partial match, case-insensitive).
          in: query
          name: q
          schema:
            type: string
            example: john doe, john@doe.com
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PageUserOutputDTO'
          description: Page of users returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: List all users
      tags:
        - Users
    post:
      description: >-
        Creates a new user and returns it with a Location header pointing to the
        new user URI.
      operationId: createUser
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserInputDTO'
        required: true
      responses:
        '201':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserOutputDTO'
          description: User created successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /users
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /users
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /users
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /users
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /users
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /users
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /users
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /users
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /users
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /users
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /users
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Create a new user
      tags:
        - Users
  /users/me:
    get:
      description: >-
        Returns the profile information of the authenticated user including
        assignments
      operationId: getCurrentUser
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PrincipalUserOutput'
          description: User profile returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get current user
      tags:
        - Users
  /users/{id}:
    delete:
      description: Permanently deletes a user by its UUID.
      operationId: deleteUser
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '204':
          description: User deleted successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /users/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: User not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /users/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /users/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /users/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /users/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /users/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (user still in use)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Delete a user
      tags:
        - Users
    get:
      description: Returns a single user identified by its UUID.
      operationId: getUser
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserOutputDTO'
          description: User returned successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /users/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: User not found
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Get user by ID
      tags:
        - Users
    patch:
      description: >-
        Applies a partial JSON update to an existing user. Only provided fields
        are modified.
      operationId: patchUser
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchUserInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserOutputDTO'
          description: User patched successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /users/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /users/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /users/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /users/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /users/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /users/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /users/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: User not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /users/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /users/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /users/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /users/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /users/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Partially update a user
      tags:
        - Users
    put:
      description: Fully replaces an existing user with the provided input.
      operationId: updateUser
      parameters:
        - in: path
          name: id
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UserInputDTO'
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserOutputDTO'
          description: User updated successfully
        '400':
          content:
            application/problem+json:
              examples:
                dataset_not_editable:
                  summary: dataset_not_editable
                  value:
                    detail: >-
                      A dataset and its sub-entities can only be changed while
                      the dataset is DRAFT. Unstage or unrelease the dataset
                      first.
                    instance: /users/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:DATASET_NOT_EDITABLE
                invalid_input:
                  summary: invalid_input
                  value:
                    detail: 'Validation failed: name must not be blank'
                    instance: /users/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:INVALID_INPUT
                malformed_request:
                  summary: malformed_request
                  value:
                    detail: Failed to read request body
                    instance: /users/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MALFORMED_REQUEST
                model_member_unreachable:
                  summary: model_member_unreachable
                  value:
                    detail: >-
                      DataStructureVersion model has members that its root
                      Element does not reach: Orphan
                    instance: /users/{id}
                    memberNames:
                      - Orphan
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_MEMBER_UNREACHABLE
                model_root_missing:
                  summary: model_root_missing
                  value:
                    detail: >-
                      DataStructureVersion model must designate exactly one root
                      Element before releasing
                    instance: /users/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:MODEL_ROOT_MISSING
                validation_failed:
                  summary: validation_failed
                  value:
                    detail: Request body validation failed
                    instance: /users/{id}
                    status: 400
                    title: Bad Request
                    type: urn:civitas:error:VALIDATION_FAILED
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Invalid input
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          content:
            application/problem+json:
              examples:
                not_found:
                  summary: not_found
                  value:
                    detail: 'Resource not found: 550e8400-e29b-41d4-a716-446655440000'
                    instance: /users/{id}
                    status: 404
                    title: Not Found
                    type: urn:civitas:error:NOT_FOUND
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: User not found
        '409':
          content:
            application/problem+json:
              examples:
                foreign_key_violation:
                  summary: foreign_key_violation
                  value:
                    detail: Referenced entity does not exist
                    instance: /users/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:FOREIGN_KEY_VIOLATION
                model_missing:
                  summary: model_missing
                  value:
                    detail: >-
                      DataStructureVersion model is missing from the model
                      registry
                    instance: /users/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:MODEL_MISSING
                resource_in_use:
                  summary: resource_in_use
                  value:
                    detail: 'Cannot delete: resource is referenced by other entities'
                    instance: /users/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:RESOURCE_IN_USE
                saga_in_flight:
                  summary: saga_in_flight
                  value:
                    detail: 'Cannot write while a saga is in-flight: CREATE'
                    instance: /users/{id}
                    pendingSagaType: CREATE
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:SAGA_IN_FLIGHT
                unique_constraint:
                  summary: unique_constraint
                  value:
                    detail: A resource with this name already exists
                    instance: /users/{id}
                    status: 409
                    title: Conflict
                    type: urn:civitas:error:UNIQUE_CONSTRAINT_VIOLATION
              schema:
                $ref: '#/components/schemas/ProblemDetail'
          description: Conflict (e.g. unique constraint violation)
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Replace a user
      tags:
        - Users
  /users/{userId}/groups:
    put:
      description: >-
        Replaces all group memberships for a user with the provided list of
        group IDs.
      operationId: replaceUserGroups
      parameters:
        - in: path
          name: userId
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        content:
          application/json:
            schema:
              type: array
              items:
                type: string
                format: uuid
        required: true
      responses:
        '200':
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserOutputDTO'
          description: Group memberships updated successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      summary: Replace user group memberships
      tags:
        - Users
components:
  responses:
    Forbidden:
      content:
        application/problem+json:
          examples:
            access_denied:
              summary: access_denied
              value:
                detail: Insufficient privileges
                instance: /v1/datasets
                status: 403
                title: Forbidden
                type: urn:civitas:error:ACCESS_DENIED
          schema:
            $ref: '#/components/schemas/ProblemDetail'
      description: Insufficient privileges
    InternalServerError:
      content:
        application/problem+json:
          examples:
            data_integrity_error:
              summary: data_integrity_error
              value:
                detail: A database constraint was violated
                instance: /v1/datasets
                status: 500
                title: Internal Server Error
                type: urn:civitas:error:DATA_INTEGRITY_ERROR
            persistence_error:
              summary: persistence_error
              value:
                detail: An unexpected database error occurred
                instance: /v1/datasets
                status: 500
                title: Internal Server Error
                type: urn:civitas:error:PERSISTENCE_ERROR
          schema:
            $ref: '#/components/schemas/ProblemDetail'
      description: Internal server error
    Unauthorized:
      content:
        application/problem+json:
          examples:
            expired_token:
              summary: expired_token
              value:
                detail: Authentication required
                instance: /v1/datasets
                status: 401
                title: Unauthorized
                type: urn:civitas:error:UNAUTHORIZED
            invalid_token:
              summary: invalid_token
              value:
                detail: JWT validation failed
                instance: /v1/datasets
                status: 401
                title: Unauthorized
                type: urn:civitas:error:INVALID_TOKEN
          schema:
            $ref: '#/components/schemas/ProblemDetail'
      description: Authentication required
  schemas:
    AssignmentGroupInputDTO:
      type: object
      properties:
        roleId:
          type: string
          format: uuid
        scopeId:
          type: string
          format: uuid
        scopeType:
          type: string
          enum:
            - TENANT
            - DATASTRUCTURE
            - DATASOURCE
            - DATASET
            - DATAPOOL
      required:
        - roleId
    AssignmentInputDTO:
      type: object
      properties:
        groupId:
          type: string
          format: uuid
        roleId:
          type: string
          format: uuid
        scopeId:
          type: string
          format: uuid
        scopeType:
          type: string
          enum:
            - TENANT
            - DATASTRUCTURE
            - DATASOURCE
            - DATASET
            - DATAPOOL
      required:
        - groupId
        - roleId
    AssignmentOutputDTO:
      type: object
      properties:
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the resource was created
          example: '2025-06-15T10:30:00'
          readOnly: true
        group:
          $ref: '#/components/schemas/GroupSummaryDTO'
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        modifiedAt:
          type: string
          format: date-time
          description: Timestamp when the resource was last modified
          example: '2025-06-15T14:22:00'
          readOnly: true
        role:
          $ref: '#/components/schemas/RoleSummaryDTO'
        scope:
          $ref: '#/components/schemas/DataEntitySummaryDTO'
          description: >-
            The specific resource this assignment is scoped to (null for TENANT
            scope)
        scopeType:
          type: string
          enum:
            - TENANT
            - DATASTRUCTURE
            - DATASOURCE
            - DATASET
            - DATAPOOL
          example: DATASET
    AssignmentScopedInputDTO:
      type: object
      properties:
        groupId:
          type: string
          format: uuid
        roleId:
          type: string
          format: uuid
      required:
        - groupId
        - roleId
    DataEntitySummaryDTO:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        name:
          type: string
    DataPoolInputDTO:
      type: object
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentScopedInputDTO'
          uniqueItems: true
        contactPersonId:
          type: string
          format: uuid
          description: ID of the user designated as the contact person for this datapool
        description:
          type: string
          minLength: 1
        name:
          type: string
          maxLength: 255
          minLength: 3
      required:
        - description
        - name
    DataPoolOutputDTO:
      type: object
      properties:
        contactPerson:
          $ref: '#/components/schemas/UserSummaryDTO'
          description: User designated as the contact person for this datapool
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the resource was created
          example: '2025-06-15T10:30:00'
          readOnly: true
        datasets:
          type: array
          description: UUIDs of datasets assigned to this datapool
          items:
            type: string
        description:
          type: string
          example: Groups all mobility-related datasets under one governance boundary
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        modifiedAt:
          type: string
          format: date-time
          description: Timestamp when the resource was last modified
          example: '2025-06-15T14:22:00'
          readOnly: true
        name:
          type: string
          example: City Mobility DataPool
    DataPoolSummaryDTO:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        name:
          type: string
    DataSetInputDTO:
      type: object
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentScopedInputDTO'
          uniqueItems: true
        datapoolId:
          type: string
          format: uuid
          description: ID of the datapool this dataset belongs to.
        description:
          type: string
          minLength: 1
        name:
          type: string
          maxLength: 255
          minLength: 3
        namedApis:
          type: array
          description: >-
            Named API endpoints exposed by this dataset. Each entry produces one
            APISIX route after release.
          items:
            $ref: '#/components/schemas/NamedApiInputDTO'
        openDataAccess:
          type: boolean
          description: Whether this dataset is publicly accessible, defaults to false
      required:
        - description
        - name
    DataSetMetaInputDTO:
      type: object
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentScopedInputDTO'
          uniqueItems: true
        datapoolId:
          type: string
          format: uuid
          description: ID of the datapool this dataset belongs to.
        description:
          type: string
          minLength: 1
        name:
          type: string
          maxLength: 255
          minLength: 3
        openDataAccess:
          type: boolean
          description: Whether this dataset is publicly accessible, defaults to false
      required:
        - description
        - name
    DataSetOutputDTO:
      type: object
      properties:
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the resource was created
          example: '2025-06-15T10:30:00'
          readOnly: true
        createdBy:
          $ref: '#/components/schemas/UserSummaryDTO'
        dataSetStatus:
          type: string
          enum:
            - DRAFT
            - READY
            - AVAILABLE
          example: DRAFT
        datapool:
          $ref: '#/components/schemas/DataPoolSummaryDTO'
          description: Datapool this dataset is assigned to
        description:
          type: string
          example: Hourly vehicle counts at major intersections
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        modifiedAt:
          type: string
          format: date-time
          description: Timestamp when the resource was last modified
          example: '2025-06-15T14:22:00'
          readOnly: true
        name:
          type: string
          example: Traffic Count 2025
        namedApis:
          type: array
          description: >-
            Named API endpoints exposed by this dataset (per concepts #1379 and
            #1383). Each entry's previewUrl is server-populated from the
            configured data-plane domain.
          items:
            $ref: '#/components/schemas/NamedApiOutputDTO'
        openDataAccess:
          type: boolean
          description: Whether this dataset is publicly accessible
        pendingSagaType:
          type: string
          description: >-
            Type of saga currently in progress (CREATE, UPDATE, UNRELEASE,
            DELETE), or null when idle
          enum:
            - CREATE
            - UPDATE
            - UNRELEASE
            - DELETE
          readOnly: true
        pipelines:
          type: array
          items:
            $ref: '#/components/schemas/PipelineSummaryDTO'
        provisioned:
          type: boolean
          description: >-
            Whether a provisioning saga has completed successfully, so whatever
            sinks the dataset carried at release physically exist (a PostGIS
            table / FROST project). Stays true across an unrelease. Decides
            whether a delete needs the teardown saga.
          readOnly: true
        publicUrl:
          type: string
          description: >-
            Public APISIX-fronted URL for this dataset, populated after a
            successful release saga
          example: https://api.core.civitasconnect.digital/datasets/traffic-count-2025
          readOnly: true
    DataSinkConfigurationOutput: {}
    DataSinkInputDTO:
      type: object
      properties:
        configuration:
          type: object
          additionalProperties: {}
          oneOf:
            - $ref: '#/components/schemas/PostgisConfiguration'
            - $ref: '#/components/schemas/FrostConfiguration'
        confirmDataLoss:
          type: boolean
          description: >-
            Acknowledges that this update rebuilds the sink's table and discards
            all stored data. Required (true) when tableName or the referenced
            element changes on a provisioned sink; ignored otherwise.
        dataSinkType:
          type: string
          enum:
            - FROST
            - POSTGIS
      required:
        - configuration
        - dataSinkType
    DataSinkOutputDTO:
      type: object
      description: DataSink details
      properties:
        configuration:
          oneOf:
            - $ref: '#/components/schemas/PostgisConfigurationOutput'
            - $ref: '#/components/schemas/FrostConfigurationOutput'
        configurationUrn:
          type: string
          description: >-
            Versioned CORE URN of this DataSink's configuration artifact in
            Model Forge
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the resource was created
          example: '2025-06-15T10:30:00'
          readOnly: true
        dataSetId:
          type: string
          format: uuid
        dataSinkType:
          type: string
          enum:
            - FROST
            - POSTGIS
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        inUseByLayer:
          type: boolean
          description: True if any Layer publishes this DataSink
        inUseByPipeline:
          type: boolean
          description: True if this DataSink is linked to a Pipeline
        modifiedAt:
          type: string
          format: date-time
          description: Timestamp when the resource was last modified
          example: '2025-06-15T14:22:00'
          readOnly: true
        pipelineId:
          type: string
          format: uuid
        provisioned:
          type: boolean
          description: >-
            True if this DataSink's storage physically exists. Set once a
            provisioning saga has completed; never reset to false.
          readOnly: true
    DataSourceInputDTO:
      type: object
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentScopedInputDTO'
          uniqueItems: true
        configuration:
          type: object
          additionalProperties: {}
          description: >-
            Connector-specific configuration. Structure depends on
            connectorType.
          oneOf:
            - $ref: '#/components/schemas/MqttConnectorConfiguration'
            - $ref: '#/components/schemas/SqlConnectorConfiguration'
        connectorType:
          type: string
          description: Type of connector (e.g. MQTT, SQL)
          enum:
            - MQTT
            - SQL
        dataStructureVersionId:
          type: string
          format: uuid
          description: ID of the data structure version to associate
        datapoolScope:
          $ref: '#/components/schemas/DatapoolScopeInputDTO'
          description: Datapool scope configuration. Defaults to ALL if omitted on create.
        description:
          type: string
          description: Data source description (required)
          minLength: 1
        name:
          type: string
          description: Data source name (required)
          minLength: 1
      required:
        - description
        - name
    DataSourceMetaInputDTO:
      type: object
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentScopedInputDTO'
          uniqueItems: true
        datapoolScope:
          $ref: '#/components/schemas/DatapoolScopeInputDTO'
          description: Datapool scope configuration. Defaults to ALL if omitted on create.
        description:
          type: string
          description: Data source description (required)
          minLength: 1
        name:
          type: string
          description: Data source name (required)
          minLength: 1
      required:
        - description
        - name
    DataSourceOutputDTO:
      type: object
      properties:
        configuration:
          type: object
          additionalProperties: {}
          description: The configuration object, structure depends on the connector type
          oneOf:
            - $ref: '#/components/schemas/MqttConnectorConfiguration'
            - $ref: '#/components/schemas/SqlConnectorConfiguration'
        configurationUrn:
          type: string
          description: >-
            Versioned CORE URN of this DataSource's configuration artifact in
            Model Forge
        connectorType:
          type: string
          description: Type of connector (e.g. MQTT, SQL)
          enum:
            - MQTT
            - SQL
          example: MQTT
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the resource was created
          example: '2025-06-15T10:30:00'
          readOnly: true
        dataSourceStatus:
          type: string
          enum:
            - DRAFT
            - AVAILABLE
          example: ACTIVE
        dataStructureVersion:
          $ref: '#/components/schemas/DataStructureVersionSummaryDTO'
        datapoolScope:
          $ref: '#/components/schemas/DatapoolScopeOutputDTO'
          description: Datapool scope configuration
        description:
          type: string
          example: Real-time traffic sensor data via MQTT broker
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        inUse:
          type: boolean
          description: >-
            Whether any pipeline references this data source. While true, it
            cannot be deleted
          readOnly: true
        inUseByReleased:
          type: boolean
          description: >-
            Whether a Pipeline of a released Dataset references this data
            source. While true, the data source cannot be unreleased and its
            technical fields are locked
          readOnly: true
        modifiedAt:
          type: string
          format: date-time
          description: Timestamp when the resource was last modified
          example: '2025-06-15T14:22:00'
          readOnly: true
        name:
          type: string
          example: Traffic Sensor MQTT
    DataStructureInputDTO:
      type: object
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentScopedInputDTO'
          uniqueItems: true
        description:
          type: string
          minLength: 1
        name:
          type: string
          minLength: 1
      required:
        - description
        - name
    DataStructureMetaInputDTO:
      type: object
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentScopedInputDTO'
          uniqueItems: true
        description:
          type: string
          minLength: 1
        name:
          type: string
          minLength: 1
      required:
        - description
        - name
    DataStructureOutputDTO:
      type: object
      properties:
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the resource was created
          example: '2025-06-15T10:30:00'
          readOnly: true
        dataStructureStatus:
          type: string
          enum:
            - DRAFT
            - AVAILABLE
          example: ACTIVE
        dataStructureVersions:
          type: array
          items:
            $ref: '#/components/schemas/DataStructureVersionUsageSummaryDTO'
        description:
          type: string
          example: Schema for traffic sensor readings
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        inUse:
          type: boolean
          description: >-
            Whether anything references one of this data structure's versions,
            released or draft. While true, it cannot be deleted
          readOnly: true
        inUseByReleased:
          type: boolean
          description: >-
            Whether a released entity references one of this data structure's
            versions. While true, it cannot be unreleased
          readOnly: true
        modifiedAt:
          type: string
          format: date-time
          description: Timestamp when the resource was last modified
          example: '2025-06-15T14:22:00'
          readOnly: true
        name:
          type: string
          example: Traffic Sensor Schema
    DataStructureSummaryDTO:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        name:
          type: string
    DataStructureVersionInputDTO:
      type: object
      properties:
        description:
          type: string
        importedStructureUrns:
          type: array
          items:
            type: string
        model:
          type: object
          additionalProperties: {}
          description: Data model definition as a JSON Schema document
        modelName:
          type: string
        styles:
          type: object
          additionalProperties: {}
    DataStructureVersionMetaInputDTO:
      type: object
      properties:
        description:
          type: string
    DataStructureVersionOutputDTO:
      type: object
      properties:
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the resource was created
          example: '2025-06-15T10:30:00'
          readOnly: true
        dataStructure:
          $ref: '#/components/schemas/DataStructureSummaryDTO'
        dataStructureVersionSource:
          type: string
          description: How this version was created (e.g. MANUAL, AUTO)
          enum:
            - OWN
        dataStructureVersionStatus:
          type: string
          enum:
            - DRAFT
            - AVAILABLE
        description:
          type: string
          example: Initial version of traffic sensor schema
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        importedStructureUrns:
          type: array
          description: >-
            Versioned CORE URNs of the published structures this version was
            built from, each pinned at the version it was loaded at
          items:
            type: string
        inUse:
          type: boolean
          description: >-
            Whether anything references this version, released or draft. While
            true, it cannot be deleted
          readOnly: true
        inUseByReleased:
          type: boolean
          description: >-
            Whether a released entity references this version. While true, it
            cannot be unreleased and its model is locked
          readOnly: true
        model:
          type: object
          additionalProperties: {}
          description: Data model definition as a JSON Schema document
        modelName:
          type: string
        modelUrn:
          type: string
        modifiedAt:
          type: string
          format: date-time
          description: Timestamp when the resource was last modified
          example: '2025-06-15T14:22:00'
          readOnly: true
        styles:
          type: object
          additionalProperties: {}
        version:
          type: string
          example: 1.0.0
    DataStructureVersionSummaryDTO:
      type: object
      properties:
        createdAt:
          type: string
          format: date-time
        dataStructureId:
          type: string
          format: uuid
        dataStructureVersionSource:
          type: string
          enum:
            - OWN
        dataStructureVersionStatus:
          type: string
          enum:
            - DRAFT
            - AVAILABLE
        description:
          type: string
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        modelUrn:
          type: string
        modifiedAt:
          type: string
          format: date-time
        version:
          type: string
    DataStructureVersionUsageSummaryDTO:
      type: object
      properties:
        createdAt:
          type: string
          format: date-time
        dataStructureId:
          type: string
          format: uuid
        dataStructureVersionSource:
          type: string
          enum:
            - OWN
        dataStructureVersionStatus:
          type: string
          enum:
            - DRAFT
            - AVAILABLE
        description:
          type: string
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        inUse:
          type: boolean
          description: >-
            Whether anything references this version, released or draft. While
            true, it cannot be deleted
          readOnly: true
        inUseByReleased:
          type: boolean
          description: >-
            Whether a released entity references this version. While true, it
            cannot be unreleased and its model is locked
          readOnly: true
        modelUrn:
          type: string
        modifiedAt:
          type: string
          format: date-time
        version:
          type: string
    DatapoolScopeInputDTO:
      type: object
      properties:
        datapoolIds:
          type: array
          description: >-
            List of DataPool IDs when type is SPECIFIC. Required and non-empty
            for SPECIFIC type.
          example:
            - 550e8400-e29b-41d4-a716-446655440000
          items:
            type: string
            format: uuid
        type:
          type: string
          description: Scope type defining DataPool access
          enum:
            - ALL
            - NONE
            - SPECIFIC
          example: SPECIFIC
    DatapoolScopeOutputDTO:
      type: object
      properties:
        datapoolIds:
          type: array
          description: >-
            List of DataPool IDs. Populated only when type is SPECIFIC, empty
            otherwise.
          example:
            - 550e8400-e29b-41d4-a716-446655440000
          items:
            type: string
            format: uuid
        type:
          type: string
          description: Scope type defining DataPool access
          enum:
            - ALL
            - NONE
            - SPECIFIC
          example: ALL
    FrostConfiguration:
      type: object
      description: Configuration for a FROST data sink
      properties:
        element:
          type: string
          description: >-
            Versioned CORE URN of the Element (a DataStructureVersion's model)
            of the mapping's Thing-shaped target structure; required when the
            pipeline maps into this sink, absent for passthrough
        port:
          type: string
          description: >-
            The write logic of the sink. There is no default: a sink without a
            port is not configured, and the dataset does not publish.
          enum:
            - Things
            - Observations
            - ThingTree
      required:
        - port
    FrostConfigurationOutput:
      allOf:
        - $ref: '#/components/schemas/DataSinkConfigurationOutput'
        - type: object
          properties:
            element:
              type: string
              description: >-
                Versioned CORE URN of the Element (a DataStructureVersion's
                model) of the mapping's Thing-shaped target structure; absent
                for a passthrough sink
            port:
              type: string
              description: >-
                The write logic of the sink; absent for a sink that is not
                configured yet
              enum:
                - Things
                - Observations
                - ThingTree
      description: Configuration for a FROST data sink (output)
    GroupInputDTO:
      type: object
      properties:
        contactUserId:
          type: string
          format: uuid
          description: ID of the primary contact user
        description:
          type: string
          example: Responsible for urban mobility datasets
        memberIds:
          type: array
          description: IDs of users to add as group members
          items:
            type: string
            format: uuid
        name:
          type: string
          example: City Data Team
          minLength: 1
      required:
        - name
    GroupOutputDTO:
      type: object
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentOutputDTO'
        contactUser:
          $ref: '#/components/schemas/UserSummaryDTO'
          description: Primary contact user for this group
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the resource was created
          example: '2025-06-15T10:30:00'
          readOnly: true
        datapools:
          type: array
          items:
            $ref: '#/components/schemas/DataPoolSummaryDTO'
        description:
          type: string
          example: Responsible for urban mobility datasets
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        members:
          type: array
          items:
            $ref: '#/components/schemas/UserSummaryDTO'
        modifiedAt:
          type: string
          format: date-time
          description: Timestamp when the resource was last modified
          example: '2025-06-15T14:22:00'
          readOnly: true
        name:
          type: string
          example: City Data Team
    GroupSummaryDTO:
      type: object
      properties:
        description:
          type: string
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        name:
          type: string
    LayerInputDTO:
      type: object
      properties:
        alternativeStyleIds:
          type: array
          items:
            type: string
            format: uuid
        attribute:
          type: array
          items:
            type: string
        cqlFilter:
          type: string
        crs:
          type: string
        dataSinkId:
          type: string
          format: uuid
        defaultStyleId:
          type: string
          format: uuid
        description:
          type: string
        geometryColumnRef:
          type: string
        latLonBoundingBox:
          type: object
          additionalProperties: {}
        layerName:
          type: string
          minLength: 1
          pattern: ^[A-Za-z_-][A-Za-z0-9_-]*$
        nativeBoundingBox:
          type: object
          additionalProperties: {}
        title:
          type: string
      required:
        - dataSinkId
        - layerName
    LayerOutputDTO:
      type: object
      description: Layer details
      properties:
        alternativeStyleIds:
          type: array
          description: IDs of alternative styles available for this layer
          items:
            type: string
            format: uuid
        attribute:
          type: array
          description: Attribute names exposed by the layer
          items:
            type: string
        cqlFilter:
          type: string
          description: CQL filter applied to the layer data
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the resource was created
          example: '2025-06-15T10:30:00'
          readOnly: true
        crs:
          type: string
          description: Coordinate reference system (e.g. EPSG:4326)
        dataSetId:
          type: string
          format: uuid
          description: ID of the dataset this layer belongs to
        dataSinkId:
          type: string
          format: uuid
          description: ID of the datasink this layer is derived from
        defaultStyleId:
          type: string
          format: uuid
          description: ID of the default style for this layer
        description:
          type: string
          description: Human-readable description
        geometryColumnRef:
          type: string
          description: Name of the geometry column in the underlying data
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        latLonBoundingBox:
          type: object
          additionalProperties: {}
          description: Bounding box in WGS84 lat/lon coordinates
        layerName:
          type: string
          description: Unique name of the layer within its datasink
        modifiedAt:
          type: string
          format: date-time
          description: Timestamp when the resource was last modified
          example: '2025-06-15T14:22:00'
          readOnly: true
        nativeBoundingBox:
          type: object
          additionalProperties: {}
          description: Native bounding box of the layer data
        title:
          type: string
          description: Human-readable title
    MeAssignmentOutputDTO:
      type: object
      description: Assignment summary for the authenticated user's /me endpoint
      properties:
        permissions:
          type: array
          description: Effective permissions granted by this assignment
          example:
            - DATASET_READ
            - DATASET_CREATE
          items:
            type: string
          uniqueItems: true
        scopeId:
          type: string
          format: uuid
          description: ID of the scoped entity (null for TENANT scope)
          example: 550e8400-e29b-41d4-a716-446655440000
        scopeType:
          type: string
          description: Type of scope this assignment applies to
          enum:
            - TENANT
            - DATASTRUCTURE
            - DATASOURCE
            - DATASET
            - DATAPOOL
          example: DATASET
    MqttConnectorConfiguration:
      type: object
      properties:
        connect_timeout:
          type: string
          description: Connection timeout duration.
          example: 5s
        keepalive:
          type: string
          description: Keepalive interval.
          example: 30s
        password:
          type: string
          description: Broker password. Write-only — returned as "********" in responses.
          example: secret
          writeOnly: true
        protocol_version:
          type: string
          default: '3'
          description: MQTT major protocol version.
          enum:
            - '3'
            - '5'
          example: '3'
          pattern: 3|5
        qos:
          type: integer
          format: int32
          description: 'QoS level: 0 = at most once, 1 = at least once, 2 = exactly once.'
          example: 1
          maximum: 2
          minimum: 0
        tls:
          $ref: '#/components/schemas/Tls'
          description: TLS configuration.
        topics:
          type: array
          description: >-
            MQTT topic filter. Exactly one filter, which may use wildcards (+
            one level, # multiple) to match several topics.
          example:
            - sensor/#
          items:
            type: string
        urls:
          type: array
          description: >-
            Broker URLs. Embedded credentials are stripped — use user/password
            instead.
          example:
            - tcp://broker:1883
          items:
            type: string
        user:
          type: string
          description: Broker username.
          example: mqttuser
      required:
        - protocol_version
    NamedApiInputDTO:
      type: object
      properties:
        description:
          type: string
          description: >-
            Optional free-form description of the named API surfaced in the
            dataset form and discovery responses. Max 150 characters.
          example: Live traffic counter readings from city sensors.
          maxLength: 150
          minLength: 0
        name:
          type: string
          description: Human-readable display label for this named API. Max 255 characters.
          example: Traffic Sensor Readings
          maxLength: 255
          minLength: 0
        slug:
          type: string
          description: >-
            URL slug used as the path segment in the public route
            /v1/datasets/{datasetId}/{slug}. Lowercase alphanumeric with
            internal hyphens, max 32 characters, unique within a dataset, not
            one of the reserved platform names (apis, usable-datasources, api,
            v1, admin), immutable while AVAILABLE.
          example: traffic
          maxLength: 32
          minLength: 0
          pattern: ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$
        standard:
          type: string
          description: >-
            API standard. CUSTOM allows free-form, non-standard APIs. Immutable
            once the dataset reaches AVAILABLE.
          enum:
            - OWS
            - STA
            - CUSTOM
          example: STA
        version:
          type: string
          description: >-
            Optional standard version (e.g. "1.1" for STA). Free-form string,
            max 32 characters.
          example: '1.1'
          maxLength: 32
          minLength: 0
      required:
        - name
        - slug
        - standard
    NamedApiOutputDTO:
      type: object
      properties:
        description:
          type: string
          description: Optional free-form description of the named API. Max 150 characters.
          example: Live traffic counter readings from city sensors.
        name:
          type: string
          description: Human-readable display label for this named API.
          example: Traffic Sensor Readings
        previewUrl:
          type: string
          description: >-
            Predicted public URL once the dataset reaches AVAILABLE:
            {publicUrl}/{slug}, where publicUrl is the base the saga provisioned
            the APISIX route under (APISIX_API_PUBLIC_URL). Falls back to
            {civitas.api.base-url}/v1/datasets/{datasetId}/{slug} for datasets
            provisioned before the saga set publicUrl. Server-populated; absent
            before the dataset is persisted.
          example: >-
            https://api.core.civitasconnect.digital/v1/datasets/b7c8b5d4-3d9c-4e3b-9a12-6b7c3f1d9e2a/traffic
          readOnly: true
        slug:
          type: string
          description: >-
            URL slug used as the path segment in the public route
            /v1/datasets/{datasetId}/{slug}.
          example: traffic
        standard:
          type: string
          description: API standard.
          enum:
            - OWS
            - STA
            - CUSTOM
          example: STA
        version:
          type: string
          description: Optional standard version (e.g. "1.1" for STA).
          example: '1.1'
    PageAssignmentOutputDTO:
      type: object
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentOutputDTO'
        empty:
          type: boolean
        first:
          type: boolean
        last:
          type: boolean
        number:
          type: integer
          format: int32
        numberOfElements:
          type: integer
          format: int32
        pageable:
          $ref: '#/components/schemas/PageableObject'
        size:
          type: integer
          format: int32
        sort:
          $ref: '#/components/schemas/SortObject'
        totalElements:
          type: integer
          format: int64
        totalPages:
          type: integer
          format: int32
    PageDataPoolOutputDTO:
      type: object
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/DataPoolOutputDTO'
        empty:
          type: boolean
        first:
          type: boolean
        last:
          type: boolean
        number:
          type: integer
          format: int32
        numberOfElements:
          type: integer
          format: int32
        pageable:
          $ref: '#/components/schemas/PageableObject'
        size:
          type: integer
          format: int32
        sort:
          $ref: '#/components/schemas/SortObject'
        totalElements:
          type: integer
          format: int64
        totalPages:
          type: integer
          format: int32
    PageDataSetOutputDTO:
      type: object
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/DataSetOutputDTO'
        empty:
          type: boolean
        first:
          type: boolean
        last:
          type: boolean
        number:
          type: integer
          format: int32
        numberOfElements:
          type: integer
          format: int32
        pageable:
          $ref: '#/components/schemas/PageableObject'
        size:
          type: integer
          format: int32
        sort:
          $ref: '#/components/schemas/SortObject'
        totalElements:
          type: integer
          format: int64
        totalPages:
          type: integer
          format: int32
    PageDataSinkOutputDTO:
      type: object
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/DataSinkOutputDTO'
        empty:
          type: boolean
        first:
          type: boolean
        last:
          type: boolean
        number:
          type: integer
          format: int32
        numberOfElements:
          type: integer
          format: int32
        pageable:
          $ref: '#/components/schemas/PageableObject'
        size:
          type: integer
          format: int32
        sort:
          $ref: '#/components/schemas/SortObject'
        totalElements:
          type: integer
          format: int64
        totalPages:
          type: integer
          format: int32
    PageDataSourceOutputDTO:
      type: object
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/DataSourceOutputDTO'
        empty:
          type: boolean
        first:
          type: boolean
        last:
          type: boolean
        number:
          type: integer
          format: int32
        numberOfElements:
          type: integer
          format: int32
        pageable:
          $ref: '#/components/schemas/PageableObject'
        size:
          type: integer
          format: int32
        sort:
          $ref: '#/components/schemas/SortObject'
        totalElements:
          type: integer
          format: int64
        totalPages:
          type: integer
          format: int32
    PageDataStructureOutputDTO:
      type: object
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/DataStructureOutputDTO'
        empty:
          type: boolean
        first:
          type: boolean
        last:
          type: boolean
        number:
          type: integer
          format: int32
        numberOfElements:
          type: integer
          format: int32
        pageable:
          $ref: '#/components/schemas/PageableObject'
        size:
          type: integer
          format: int32
        sort:
          $ref: '#/components/schemas/SortObject'
        totalElements:
          type: integer
          format: int64
        totalPages:
          type: integer
          format: int32
    PageGroupOutputDTO:
      type: object
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/GroupOutputDTO'
        empty:
          type: boolean
        first:
          type: boolean
        last:
          type: boolean
        number:
          type: integer
          format: int32
        numberOfElements:
          type: integer
          format: int32
        pageable:
          $ref: '#/components/schemas/PageableObject'
        size:
          type: integer
          format: int32
        sort:
          $ref: '#/components/schemas/SortObject'
        totalElements:
          type: integer
          format: int64
        totalPages:
          type: integer
          format: int32
    PageLayerOutputDTO:
      type: object
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/LayerOutputDTO'
        empty:
          type: boolean
        first:
          type: boolean
        last:
          type: boolean
        number:
          type: integer
          format: int32
        numberOfElements:
          type: integer
          format: int32
        pageable:
          $ref: '#/components/schemas/PageableObject'
        size:
          type: integer
          format: int32
        sort:
          $ref: '#/components/schemas/SortObject'
        totalElements:
          type: integer
          format: int64
        totalPages:
          type: integer
          format: int32
    PagePipelineOutputDTO:
      type: object
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/PipelineOutputDTO'
        empty:
          type: boolean
        first:
          type: boolean
        last:
          type: boolean
        number:
          type: integer
          format: int32
        numberOfElements:
          type: integer
          format: int32
        pageable:
          $ref: '#/components/schemas/PageableObject'
        size:
          type: integer
          format: int32
        sort:
          $ref: '#/components/schemas/SortObject'
        totalElements:
          type: integer
          format: int64
        totalPages:
          type: integer
          format: int32
    PageRoleOutputDTO:
      type: object
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/RoleOutputDTO'
        empty:
          type: boolean
        first:
          type: boolean
        last:
          type: boolean
        number:
          type: integer
          format: int32
        numberOfElements:
          type: integer
          format: int32
        pageable:
          $ref: '#/components/schemas/PageableObject'
        size:
          type: integer
          format: int32
        sort:
          $ref: '#/components/schemas/SortObject'
        totalElements:
          type: integer
          format: int64
        totalPages:
          type: integer
          format: int32
    PageStyleOutputDTO:
      type: object
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/StyleOutputDTO'
        empty:
          type: boolean
        first:
          type: boolean
        last:
          type: boolean
        number:
          type: integer
          format: int32
        numberOfElements:
          type: integer
          format: int32
        pageable:
          $ref: '#/components/schemas/PageableObject'
        size:
          type: integer
          format: int32
        sort:
          $ref: '#/components/schemas/SortObject'
        totalElements:
          type: integer
          format: int64
        totalPages:
          type: integer
          format: int32
    PageUserOutputDTO:
      type: object
      properties:
        content:
          type: array
          items:
            $ref: '#/components/schemas/UserOutputDTO'
        empty:
          type: boolean
        first:
          type: boolean
        last:
          type: boolean
        number:
          type: integer
          format: int32
        numberOfElements:
          type: integer
          format: int32
        pageable:
          $ref: '#/components/schemas/PageableObject'
        size:
          type: integer
          format: int32
        sort:
          $ref: '#/components/schemas/SortObject'
        totalElements:
          type: integer
          format: int64
        totalPages:
          type: integer
          format: int32
    PageableObject:
      type: object
      properties:
        offset:
          type: integer
          format: int64
        pageNumber:
          type: integer
          format: int32
        pageSize:
          type: integer
          format: int32
        paged:
          type: boolean
        sort:
          $ref: '#/components/schemas/SortObject'
        unpaged:
          type: boolean
    PatchDataPoolInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentScopedInputDTO'
          uniqueItems: true
        contactPersonId:
          type: string
          format: uuid
          description: ID of the user designated as the contact person for this datapool
        description:
          type: string
          minLength: 1
        name:
          type: string
          maxLength: 255
          minLength: 3
    PatchDataSetInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentScopedInputDTO'
          uniqueItems: true
        datapoolId:
          type: string
          format: uuid
          description: ID of the datapool this dataset belongs to.
        description:
          type: string
          minLength: 1
        name:
          type: string
          maxLength: 255
          minLength: 3
        namedApis:
          type: array
          description: >-
            Named API endpoints exposed by this dataset. Each entry produces one
            APISIX route after release.
          items:
            $ref: '#/components/schemas/NamedApiInputDTO'
        openDataAccess:
          type: boolean
          description: Whether this dataset is publicly accessible, defaults to false
    PatchDataSetMetaInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentScopedInputDTO'
          uniqueItems: true
        datapoolId:
          type: string
          format: uuid
          description: ID of the datapool this dataset belongs to.
        description:
          type: string
          minLength: 1
        name:
          type: string
          maxLength: 255
          minLength: 3
        openDataAccess:
          type: boolean
          description: Whether this dataset is publicly accessible, defaults to false
    PatchDataSinkInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        configuration:
          type: object
          additionalProperties: {}
          oneOf:
            - $ref: '#/components/schemas/PostgisConfiguration'
            - $ref: '#/components/schemas/FrostConfiguration'
        confirmDataLoss:
          type: boolean
          description: >-
            Acknowledges that this update rebuilds the sink's table and discards
            all stored data. Required (true) when tableName or the referenced
            element changes on a provisioned sink; ignored otherwise.
        dataSinkType:
          type: string
          enum:
            - FROST
            - POSTGIS
    PatchDataSourceInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentScopedInputDTO'
          uniqueItems: true
        configuration:
          type: object
          additionalProperties: {}
          description: >-
            Connector-specific configuration. Structure depends on
            connectorType.
          oneOf:
            - $ref: '#/components/schemas/MqttConnectorConfiguration'
            - $ref: '#/components/schemas/SqlConnectorConfiguration'
        connectorType:
          type: string
          description: Type of connector (e.g. MQTT, SQL)
          enum:
            - MQTT
            - SQL
        dataStructureVersionId:
          type: string
          format: uuid
          description: ID of the data structure version to associate
        datapoolScope:
          $ref: '#/components/schemas/DatapoolScopeInputDTO'
          description: Datapool scope configuration. Defaults to ALL if omitted on create.
        description:
          type: string
          description: Data source description (required)
          minLength: 1
        name:
          type: string
          description: Data source name (required)
          minLength: 1
    PatchDataSourceMetaInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentScopedInputDTO'
          uniqueItems: true
        datapoolScope:
          $ref: '#/components/schemas/DatapoolScopeInputDTO'
          description: Datapool scope configuration. Defaults to ALL if omitted on create.
        description:
          type: string
          description: Data source description (required)
          minLength: 1
        name:
          type: string
          description: Data source name (required)
          minLength: 1
    PatchDataStructureInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentScopedInputDTO'
          uniqueItems: true
        description:
          type: string
          minLength: 1
        name:
          type: string
          minLength: 1
    PatchDataStructureMetaInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        assignments:
          type: array
          items:
            $ref: '#/components/schemas/AssignmentScopedInputDTO'
          uniqueItems: true
        description:
          type: string
          minLength: 1
        name:
          type: string
          minLength: 1
    PatchDataStructureVersionInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        description:
          type: string
        importedStructureUrns:
          type: array
          items:
            type: string
        model:
          type: object
          additionalProperties: {}
          description: Data model definition as a JSON Schema document
        modelName:
          type: string
        styles:
          type: object
          additionalProperties: {}
    PatchDataStructureVersionMetaInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        description:
          type: string
    PatchGroupInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        contactUserId:
          type: string
          format: uuid
          description: ID of the primary contact user
        description:
          type: string
          example: Responsible for urban mobility datasets
        memberIds:
          type: array
          description: IDs of users to add as group members
          items:
            type: string
            format: uuid
        name:
          type: string
          example: City Data Team
          minLength: 1
    PatchLayerInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        alternativeStyleIds:
          type: array
          items:
            type: string
            format: uuid
        attribute:
          type: array
          items:
            type: string
        cqlFilter:
          type: string
        crs:
          type: string
        dataSinkId:
          type: string
          format: uuid
        defaultStyleId:
          type: string
          format: uuid
        description:
          type: string
        geometryColumnRef:
          type: string
        latLonBoundingBox:
          type: object
          additionalProperties: {}
        layerName:
          type: string
          minLength: 1
          pattern: ^[A-Za-z_-][A-Za-z0-9_-]*$
        nativeBoundingBox:
          type: object
          additionalProperties: {}
        title:
          type: string
    PatchPipelineInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        dataSinkIds:
          type: array
          items:
            type: string
            format: uuid
          uniqueItems: true
        dataSourceIds:
          type: array
          items:
            type: string
            format: uuid
          uniqueItems: true
        description:
          type: string
        model:
          type: object
          additionalProperties: {}
        name:
          type: string
          minLength: 1
        styles:
          type: object
          additionalProperties: {}
    PatchRoleInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        description:
          type: string
          example: Manages datasets and data sources
        name:
          type: string
          example: Data Manager
          minLength: 1
        permissionIds:
          type: array
          description: IDs of permissions to assign to this role
          items:
            type: string
            format: uuid
        readonly:
          type: boolean
          description: Whether this role can be modified, defaults to false
        roleType:
          type: string
          enum:
            - SYSTEM
            - DATA
          example: DATA
    PatchStyleInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        name:
          type: string
          minLength: 1
          pattern: '[A-Za-z0-9_-]+'
        sldContent:
          type: string
          minLength: 1
    PatchUserInputDTO:
      description: Partial update — only provided fields are modified.
      properties:
        email:
          type: string
          format: email
          example: jane.doe@example.com
          minLength: 1
        firstName:
          type: string
          example: Jane
          minLength: 1
        lastName:
          type: string
          example: Doe
          minLength: 1
        phone:
          type: string
          example: +49 170 1234567
        title:
          type: string
          description: Salutation, defaults to OTHER
          enum:
            - MR
            - MS
            - OTHER
          example: MS
    PermissionOutputDTO:
      type: object
      properties:
        category:
          type: string
          description: Functional category (e.g. DATASET, USER)
          enum:
            - TENANT_ADMINISTRATION
            - DATA
          example: DATASET
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the resource was created
          example: '2025-06-15T10:30:00'
          readOnly: true
        description:
          type: string
          example: Read access to datasets
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        modifiedAt:
          type: string
          format: date-time
          description: Timestamp when the resource was last modified
          example: '2025-06-15T14:22:00'
          readOnly: true
        name:
          type: string
          description: Permission identifier (e.g. DATASET_READ)
          example: DATASET_READ
        permissionType:
          type: string
          enum:
            - SYSTEM
            - DATA
          example: DATA
    PermissionSummaryDTO:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        name:
          type: string
        permissionType:
          type: string
          enum:
            - SYSTEM
            - DATA
    PipelineInputDTO:
      type: object
      properties:
        dataSinkIds:
          type: array
          items:
            type: string
            format: uuid
          uniqueItems: true
        dataSourceIds:
          type: array
          items:
            type: string
            format: uuid
          uniqueItems: true
        description:
          type: string
        model:
          type: object
          additionalProperties: {}
        name:
          type: string
          minLength: 1
        styles:
          type: object
          additionalProperties: {}
      required:
        - name
    PipelineOutputDTO:
      type: object
      description: Pipeline details
      properties:
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the resource was created
          example: '2025-06-15T10:30:00'
          readOnly: true
        dataSetId:
          type: string
          format: uuid
        dataSinkIds:
          type: array
          items:
            type: string
            format: uuid
        dataSourceIds:
          type: array
          items:
            type: string
            format: uuid
        description:
          type: string
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        model:
          type: object
          additionalProperties: {}
        modelUrn:
          type: string
        modifiedAt:
          type: string
          format: date-time
          description: Timestamp when the resource was last modified
          example: '2025-06-15T14:22:00'
          readOnly: true
        name:
          type: string
        styles:
          type: object
          additionalProperties: {}
    PipelineRuntimeStatusDTO:
      type: object
      properties:
        lastEventId:
          type: string
          format: uuid
        message:
          type: string
        occurredAt:
          type: string
          format: date-time
        sanitizedStacktrace:
          type: string
        source:
          type: string
          enum:
            - DEPLOYMENT
            - RUNTIME
        state:
          type: string
          enum:
            - OK
            - ERROR
    PipelineSummaryDTO:
      type: object
      properties:
        description:
          type: string
        id:
          type: string
          format: uuid
        name:
          type: string
        runtimeStatus:
          $ref: '#/components/schemas/PipelineRuntimeStatusDTO'
    PostgisConfiguration:
      type: object
      description: Configuration for a POSTGIS data sink
      properties:
        element:
          type: string
          description: >-
            Versioned CORE URN of the Element (a DataStructureVersion's model)
            that defines the output row format. Model Forge tracks this as a
            datasink-element dependency edge.
        tableName:
          type: string
          description: >-
            Target table name in the PostGIS database. Must be a plain unquoted
            SQL identifier and unique across the dataset's POSTGIS sinks, which
            all share one schema.
          example: traffic_data
          maxLength: 63
          pattern: ^[A-Za-z_][A-Za-z0-9_]*$
    PostgisConfigurationOutput:
      allOf:
        - $ref: '#/components/schemas/DataSinkConfigurationOutput'
        - type: object
          properties:
            dataStructureVersion:
              $ref: '#/components/schemas/DataStructureVersionSummaryDTO'
              description: >-
                The DataStructureVersion pinned by 'element', resolved via its
                model URN; absent when no stored version carries that URN
              readOnly: true
            element:
              type: string
              description: >-
                Versioned CORE URN of the Element (a DataStructureVersion's
                model) that defines the table schema
            tableName:
              type: string
              description: Target table name in the PostGIS database
              example: traffic_data
      description: Configuration for a POSTGIS data sink (output)
    PrincipalUserOutput:
      type: object
      properties:
        assignments:
          type: array
          description: User's assignments with role, permissions, scope and group
          items:
            $ref: '#/components/schemas/MeAssignmentOutputDTO'
        email:
          type: string
          description: User's email address
          example: user@example.com
        firstName:
          type: string
          description: User's first name
          example: John
        lastName:
          type: string
          description: User's last name
          example: Doe
        title:
          type: string
          description: User's title
          enum:
            - MR
            - MS
            - OTHER
          example: MS
        username:
          type: string
          description: User's unique identifier
          example: testuser
    ProblemDetail:
      type: object
      properties:
        detail:
          type: string
        instance:
          type: string
          format: uri
        properties:
          type: object
          additionalProperties: {}
        status:
          type: integer
          format: int32
        title:
          type: string
        type:
          type: string
          format: uri
    PublishedStructureOutput:
      type: object
      properties:
        key:
          type: string
        name:
          type: string
        urn:
          type: string
    PublishingSinkOutput:
      type: object
      properties:
        sink:
          type: string
        structures:
          type: array
          items:
            $ref: '#/components/schemas/PublishedStructureOutput'
    RoleInputDTO:
      type: object
      properties:
        description:
          type: string
          example: Manages datasets and data sources
        name:
          type: string
          example: Data Manager
          minLength: 1
        permissionIds:
          type: array
          description: IDs of permissions to assign to this role
          items:
            type: string
            format: uuid
        readonly:
          type: boolean
          description: Whether this role can be modified, defaults to false
        roleType:
          type: string
          enum:
            - SYSTEM
            - DATA
          example: DATA
      required:
        - name
        - roleType
    RoleOutputDTO:
      type: object
      properties:
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the resource was created
          example: '2025-06-15T10:30:00'
          readOnly: true
        datapools:
          type: array
          items:
            $ref: '#/components/schemas/DataPoolSummaryDTO'
        description:
          type: string
          example: Manages datasets and data sources
        groupCount:
          type: integer
          format: int64
          description: Number of groups using this role
          example: 3
          readOnly: true
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        modifiedAt:
          type: string
          format: date-time
          description: Timestamp when the resource was last modified
          example: '2025-06-15T14:22:00'
          readOnly: true
        name:
          type: string
          example: Data Manager
        permissions:
          type: array
          items:
            $ref: '#/components/schemas/PermissionSummaryDTO'
        readonly:
          type: boolean
          description: Whether this role can be modified, defaults to false
          example: false
        roleType:
          type: string
          enum:
            - SYSTEM
            - DATA
          example: DATA
        userCount:
          type: integer
          format: int64
          description: Number of users with this role (via group assignments)
          example: 12
          readOnly: true
    RoleSummaryDTO:
      type: object
      properties:
        description:
          type: string
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        name:
          type: string
        readonly:
          type: boolean
          description: Whether this role can be modified
        roleType:
          type: string
          enum:
            - SYSTEM
            - DATA
    Sort:
      type: object
      properties:
        sort:
          type: array
          items:
            type: string
    SortObject:
      type: object
      properties:
        empty:
          type: boolean
        sorted:
          type: boolean
        unsorted:
          type: boolean
    SqlConnectorConfiguration:
      type: object
      properties:
        columns:
          type: array
          description: Column names to select.
          example:
            - id
            - value
            - timestamp
          items:
            type: string
        driver:
          type: string
          description: Database driver type.
          example: postgres
        dsn:
          type: string
          description: >-
            Connection URL. Embedded credentials are stripped — use
            user/password instead.
          example: postgres://localhost:5432/mydb
        password:
          type: string
          description: Database password. Write-only — returned as "********" in responses.
          example: secret
          writeOnly: true
        table:
          type: string
          description: Target table name.
          example: sensor_readings
        user:
          type: string
          description: Database username.
          example: dbuser
        where:
          type: string
          description: SQL WHERE clause.
          example: id > :last_id
    StyleInputDTO:
      type: object
      properties:
        name:
          type: string
          minLength: 1
          pattern: '[A-Za-z0-9_-]+'
        sldContent:
          type: string
          minLength: 1
      required:
        - name
        - sldContent
    StyleOutputDTO:
      type: object
      description: Style details
      properties:
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the resource was created
          example: '2025-06-15T10:30:00'
          readOnly: true
        dataSetId:
          type: string
          format: uuid
          description: ID of the dataset this style belongs to
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        inUse:
          type: boolean
          description: >-
            True if any Layer references this Style as its default or
            alternative Style
        modifiedAt:
          type: string
          format: date-time
          description: Timestamp when the resource was last modified
          example: '2025-06-15T14:22:00'
          readOnly: true
        name:
          type: string
          description: Unique name of the style within its dataset
        sldContent:
          type: string
          description: SLD (Styled Layer Descriptor) XML content
    Tls:
      type: object
      properties:
        enabled:
          type: boolean
          description: Whether to enable TLS.
          example: false
    UserInputDTO:
      type: object
      properties:
        email:
          type: string
          format: email
          example: jane.doe@example.com
          minLength: 1
        firstName:
          type: string
          example: Jane
          minLength: 1
        lastName:
          type: string
          example: Doe
          minLength: 1
        phone:
          type: string
          example: +49 170 1234567
        title:
          type: string
          description: Salutation, defaults to OTHER
          enum:
            - MR
            - MS
            - OTHER
          example: MS
      required:
        - email
        - firstName
        - lastName
    UserOutputDTO:
      type: object
      properties:
        createdAt:
          type: string
          format: date-time
          description: Timestamp when the resource was created
          example: '2025-06-15T10:30:00'
          readOnly: true
        datapools:
          type: array
          items:
            $ref: '#/components/schemas/DataPoolSummaryDTO'
        email:
          type: string
          example: jane.doe@example.com
        firstName:
          type: string
          example: Jane
        groups:
          type: array
          items:
            $ref: '#/components/schemas/GroupSummaryDTO'
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        lastName:
          type: string
          example: Doe
        modifiedAt:
          type: string
          format: date-time
          description: Timestamp when the resource was last modified
          example: '2025-06-15T14:22:00'
          readOnly: true
        phone:
          type: string
          example: +49 170 1234567
        title:
          type: string
          description: Salutation (e.g. MR, MS, OTHER)
          enum:
            - MR
            - MS
            - OTHER
          example: MS
    UserSummaryDTO:
      type: object
      properties:
        id:
          type: string
          format: uuid
          description: Unique identifier (UUID)
          example: 550e8400-e29b-41d4-a716-446655440000
          readOnly: true
        name:
          type: string
  securitySchemes:
    oauth2:
      description: Keycloak OAuth2 Authorization Code with PKCE
      flows:
        authorizationCode:
          authorizationUrl: >-
            https://auth.example.org/realms/civitas-core/protocol/openid-connect/auth
          scopes: {}
          tokenUrl: >-
            https://auth.example.org/realms/civitas-core/protocol/openid-connect/token
      type: oauth2
