openapi: 3.1.0
info:
  title: eQMS Platform API
  version: 0.10.0
  description: eQMS tenant foundation and shared Phase 2 record-integrity services. Foundation test records
    demonstrate primitives; quality modules arrive in later phases.
  contact:
    name: eQMS platform maintainers
    url: https://github.com
servers:
  - url: /
    description: Same-origin application server
security: []
tags:
  - name: Operations
    description: Minimal public operational probes; not regulated business actions.
  - name: Foundation
    description: Tenant, identity, organization and administration.
  - name: Integrity
    description: Shared record integrity; test records do not implement quality-module approvals.
  - name: Workflows
    description: Versioned workflows, independent review, inbox and reliable integration events.
  - name: Forms
    description: Immutable form design, controlled execution, historical snapshots and export jobs.
  - name: Documents and training
    description: Controlled document revisions, training assessments and attributable qualification.
  - name: Quality events
    description: Controlled master publications, versioned risk scoring, deviations, CAPA and change control.
  - name: QC and equipment
    description: Immutable laboratory publications, OOS/OOT investigations and equipment lifecycle.
  - name: Quality oversight
    description: Audits, supplier qualification, privacy-scoped complaints and durable safety handoff.
  - name: Analytics and inspection
    description: Scoped reports, frozen reviews, controlled exports and retained release evidence.
paths:
  /api/v1/health:
    get:
      operationId: getHealth
      summary: Check application liveness
      description: |
        Returns 200 when the application can process a request. Does not contact dependencies.
        No authentication, tenant context, request body or query parameters are accepted/required.
        No audit/signature side effects, pagination, concurrency or idempotency key applies.
        Invalid query parameters return 422. Unexpected application failures return 500.
        This endpoint is intended for bounded infrastructure probes; edge rate limits are an operator control.
      tags:
        - Operations
      responses:
        "200":
          description: Application process is live.
          headers:
            X-Request-ID:
              $ref: "#/components/headers/RequestId"
            Cache-Control:
              $ref: "#/components/headers/NoStore"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Health"
              example:
                status: ok
                service: eqms-api
                timestamp: 2026-10-17T10:00:00.000Z
                request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
        "422":
          $ref: "#/components/responses/ValidationProblem"
        "500":
          $ref: "#/components/responses/InternalProblem"
  /api/v1/readiness:
    get:
      operationId: getReadiness
      summary: Check configured dependency readiness
      description: |
        Returns 200 after a bounded successful Supabase Auth health probe; otherwise 503.
        Missing/invalid configuration, timeout, redirects or upstream failures fail closed.
        This is an HTTP dependency check, not proof of database migrations, RLS, storage,
        backup health or suitability for regulated use. The predeployment gate checks those separately.
        Authentication, tenant context, body, idempotency and optimistic concurrency do not apply.
        Query parameters return 422. No audit/signature side effects or data access occurs.
        Each request has a 2-second dependency timeout. Use bounded infrastructure polling.
      tags:
        - Operations
      responses:
        "200":
          description: Configured Supabase Auth HTTP dependency is reachable.
          headers:
            X-Request-ID:
              $ref: "#/components/headers/RequestId"
            Cache-Control:
              $ref: "#/components/headers/NoStore"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Readiness"
              example:
                status: ready
                checks:
                  supabase_auth: reachable
                timestamp: 2026-10-17T10:00:00.000Z
                request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
        "422":
          $ref: "#/components/responses/ValidationProblem"
        "500":
          $ref: "#/components/responses/InternalProblem"
        "503":
          description: Required dependency is unconfigured or unavailable. Internal details are withheld.
          headers:
            X-Request-ID:
              $ref: "#/components/headers/RequestId"
            Cache-Control:
              $ref: "#/components/headers/NoStore"
          content:
            application/problem+json:
              schema:
                $ref: "#/components/schemas/Problem"
              example:
                type: urn:eqms:problem:dependency-unavailable
                title: Service unavailable
                status: 503
                detail: A required dependency is not ready.
                code: DEPENDENCY_UNAVAILABLE
                request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
  /api/v1/me:
    get:
      operationId: context_get
      summary: context get
      description: context.get. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
      responses:
        "200":
          $ref: "#/components/responses/FoundationTenantContext"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    patch:
      operationId: profile_update
      summary: profile update
      description: profile.update. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
          description: User-scoped key; same payload replays the result without duplicate side effects. Credential
            secrets are not retained/revealed on replay.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProfileInput"
            example:
              display_name: Example
              timezone: UTC
              locale: en-GB
              expected_version: 1
      responses:
        "200":
          $ref: "#/components/responses/FoundationProfile"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/organizations:
    post:
      operationId: organization_create
      summary: organization create
      description: organization.create. Verified human session required; machine credentials are forbidden. Tenant
        is derived server-side from validated identity and current membership; supplied tenant IDs are
        rejected. Role, active-account, site/department, feature and configured MFA policies apply. Mutations
        use controlled domain commands and attributable security events. Reads have no signature/audit
        mutation effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
          description: User-scoped key; same payload replays the result without duplicate side effects. Credential
            secrets are not retained/revealed on replay.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OnboardingInput"
            example:
              name: Example
              slug: example-organization
              timezone: UTC
              display_name: Example
      responses:
        "200":
          $ref: "#/components/responses/FoundationOrganization"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/organization:
    get:
      operationId: organization_get
      summary: organization get
      description: organization.get. Verified human session or machine key with the matching read scope. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
        - integrationKey: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
      responses:
        "200":
          $ref: "#/components/responses/FoundationOrganization"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    patch:
      operationId: organization_update
      summary: organization update
      description: organization.update. Verified human session required; machine credentials are forbidden. Tenant
        is derived server-side from validated identity and current membership; supplied tenant IDs are
        rejected. Role, active-account, site/department, feature and configured MFA policies apply. Mutations
        use controlled domain commands and attributable security events. Reads have no signature/audit
        mutation effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
          description: User-scoped key; same payload replays the result without duplicate side effects. Credential
            secrets are not retained/revealed on replay.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OrganizationInput"
            example:
              name: Example
              timezone: UTC
              locale: en-GB
              accent: blue
              mfa_required: false
              expected_version: 1
      responses:
        "200":
          $ref: "#/components/responses/FoundationOrganization"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/sites:
    get:
      operationId: sites_list
      summary: sites list
      description: sites.list. Verified human session or machine key with the matching read scope. Tenant is derived
        server-side from validated identity and current membership; supplied tenant IDs are rejected. Role,
        active-account, site/department, feature and configured MFA policies apply. Mutations use controlled
        domain commands and attributable security events. Reads have no signature/audit mutation effect. Lists
        use ascending UUID cursors, default 50/max 100. All responses are uncached with X-Request-ID. Verified
        principals are limited to 120 domain requests/minute; Auth operations also use provider limits.
        Versioned updates require expected_version and return 412 when stale. Invitation links are shared by
        the inviting administrator; this API does not send email. Machine clients support organization:read,
        sites:read and departments:read only; no human signatures or approval capabilities. Expiry is required
        (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do not use ambient
        cookies. Idempotency applies to domain mutations only; auth commands use provider semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
        - integrationKey: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
      responses:
        "200":
          $ref: "#/components/responses/FoundationSitesPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: sites_create
      summary: sites create
      description: sites.create. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
          description: User-scoped key; same payload replays the result without duplicate side effects. Credential
            secrets are not retained/revealed on replay.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/SiteInput"
            example:
              name: Example
              code: EXAMPLE
      responses:
        "200":
          $ref: "#/components/responses/FoundationSite"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/departments:
    get:
      operationId: departments_list
      summary: departments list
      description: departments.list. Verified human session or machine key with the matching read scope. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
        - integrationKey: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
      responses:
        "200":
          $ref: "#/components/responses/FoundationDepartmentsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: departments_create
      summary: departments create
      description: departments.create. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
          description: User-scoped key; same payload replays the result without duplicate side effects. Credential
            secrets are not retained/revealed on replay.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DepartmentInput"
            example:
              name: Example
              code: EXAMPLE
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
      responses:
        "200":
          $ref: "#/components/responses/FoundationDepartment"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/roles:
    get:
      operationId: roles_list
      summary: roles list
      description: roles.list. Verified human session required; machine credentials are forbidden. Tenant is derived
        server-side from validated identity and current membership; supplied tenant IDs are rejected. Role,
        active-account, site/department, feature and configured MFA policies apply. Mutations use controlled
        domain commands and attributable security events. Reads have no signature/audit mutation effect. Lists
        use ascending UUID cursors, default 50/max 100. All responses are uncached with X-Request-ID. Verified
        principals are limited to 120 domain requests/minute; Auth operations also use provider limits.
        Versioned updates require expected_version and return 412 when stale. Invitation links are shared by
        the inviting administrator; this API does not send email. Machine clients support organization:read,
        sites:read and departments:read only; no human signatures or approval capabilities. Expiry is required
        (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do not use ambient
        cookies. Idempotency applies to domain mutations only; auth commands use provider semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
      responses:
        "200":
          $ref: "#/components/responses/FoundationRolesPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: roles_create
      summary: roles create
      description: roles.create. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
          description: User-scoped key; same payload replays the result without duplicate side effects. Credential
            secrets are not retained/revealed on replay.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/RoleInput"
            example:
              name: Example
              permissions: []
      responses:
        "200":
          $ref: "#/components/responses/FoundationRole"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/roles/{id}:
    patch:
      operationId: roles_update
      summary: roles update
      description: roles.update. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
          description: User-scoped key; same payload replays the result without duplicate side effects. Credential
            secrets are not retained/revealed on replay.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                name:
                  type: string
                  minLength: 2
                  maxLength: 80
                permissions:
                  type: array
                  items:
                    type: string
                    minLength: 1
                    maxLength: 80
                  maxItems: 100
                  uniqueItems: true
                expected_version:
                  type: integer
                  minimum: 1
              required:
                - name
                - permissions
                - expected_version
            example:
              name: Example
              permissions: []
              expected_version: 1
      responses:
        "200":
          $ref: "#/components/responses/FoundationRole"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/permissions:
    get:
      operationId: permissions_list
      summary: permissions list
      description: permissions.list. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
      responses:
        "200":
          $ref: "#/components/responses/FoundationPermissionsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/users:
    get:
      operationId: users_list
      summary: users list
      description: users.list. Verified human session required; machine credentials are forbidden. Tenant is derived
        server-side from validated identity and current membership; supplied tenant IDs are rejected. Role,
        active-account, site/department, feature and configured MFA policies apply. Mutations use controlled
        domain commands and attributable security events. Reads have no signature/audit mutation effect. Lists
        use ascending UUID cursors, default 50/max 100. All responses are uncached with X-Request-ID. Verified
        principals are limited to 120 domain requests/minute; Auth operations also use provider limits.
        Versioned updates require expected_version and return 412 when stale. Invitation links are shared by
        the inviting administrator; this API does not send email. Machine clients support organization:read,
        sites:read and departments:read only; no human signatures or approval capabilities. Expiry is required
        (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do not use ambient
        cookies. Idempotency applies to domain mutations only; auth commands use provider semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
      responses:
        "200":
          $ref: "#/components/responses/FoundationUsersPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/users/{id}:
    patch:
      operationId: users_update
      summary: users update
      description: users.update. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
          description: User-scoped key; same payload replays the result without duplicate side effects. Credential
            secrets are not retained/revealed on replay.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                status:
                  enum:
                    - active
                    - suspended
                    - deactivated
                all_sites:
                  type: boolean
                all_departments:
                  type: boolean
                role_ids:
                  type: array
                  items:
                    type: string
                    format: uuid
                  maxItems: 100
                  uniqueItems: true
                site_ids:
                  type: array
                  items:
                    type: string
                    format: uuid
                  maxItems: 100
                  uniqueItems: true
                department_ids:
                  type: array
                  items:
                    type: string
                    format: uuid
                  maxItems: 100
                  uniqueItems: true
                expected_version:
                  type: integer
                  minimum: 1
              required:
                - status
                - all_sites
                - all_departments
                - role_ids
                - site_ids
                - department_ids
                - expected_version
            example:
              status: active
              all_sites: false
              all_departments: false
              role_ids: []
              site_ids: []
              department_ids: []
              expected_version: 1
      responses:
        "200":
          $ref: "#/components/responses/FoundationMembership"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/invitations:
    get:
      operationId: invitations_list
      summary: invitations list
      description: invitations.list. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
      responses:
        "200":
          $ref: "#/components/responses/FoundationInvitationsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: invitations_create
      summary: invitations create
      description: invitations.create. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
          description: User-scoped key; same payload replays the result without duplicate side effects. Credential
            secrets are not retained/revealed on replay.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/InvitationInput"
            example:
              email: reader@example.test
              role_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
      responses:
        "200":
          $ref: "#/components/responses/FoundationInvitationIssued"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/invitations/{id}/revoke:
    post:
      operationId: invitations_revoke
      summary: invitations revoke
      description: invitations.revoke. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
          description: User-scoped key; same payload replays the result without duplicate side effects. Credential
            secrets are not retained/revealed on replay.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties: {}
              required: []
            example: {}
      responses:
        "200":
          $ref: "#/components/responses/FoundationInvitation"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/invitations/accept:
    post:
      operationId: invitations_accept
      summary: invitations accept
      description: invitations.accept. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
          description: User-scoped key; same payload replays the result without duplicate side effects. Credential
            secrets are not retained/revealed on replay.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AcceptInvitationInput"
            example:
              token: "0000000000000000000000000000000000000000000000000000000000000000"
              display_name: Example
      responses:
        "200":
          $ref: "#/components/responses/FoundationAccepted"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integration-clients:
    get:
      operationId: clients_list
      summary: clients list
      description: clients.list. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
      responses:
        "200":
          $ref: "#/components/responses/FoundationClientsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: clients_create
      summary: clients create
      description: clients.create. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
          description: User-scoped key; same payload replays the result without duplicate side effects. Credential
            secrets are not retained/revealed on replay.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ClientInput"
            example:
              name: Example
              scopes:
                - organization:read
              expires_at: 2026-10-18T10:00:00.000Z
      responses:
        "200":
          $ref: "#/components/responses/FoundationClientIssued"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integration-clients/{id}/rotate:
    post:
      operationId: clients_rotate
      summary: clients rotate
      description: clients.rotate. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
          description: User-scoped key; same payload replays the result without duplicate side effects. Credential
            secrets are not retained/revealed on replay.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties: {}
              required: []
            example: {}
      responses:
        "200":
          $ref: "#/components/responses/FoundationClientIssued"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integration-clients/{id}/revoke:
    post:
      operationId: clients_revoke
      summary: clients revoke
      description: clients.revoke. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
          description: User-scoped key; same payload replays the result without duplicate side effects. Credential
            secrets are not retained/revealed on replay.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties: {}
              required: []
            example: {}
      responses:
        "200":
          $ref: "#/components/responses/FoundationClient"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/security-events:
    get:
      operationId: events_list
      summary: events list
      description: events.list. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
      responses:
        "200":
          $ref: "#/components/responses/FoundationEventsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/auth/sign-in:
    post:
      operationId: auth_sign_in
      summary: auth sign in
      description: auth.sign-in. Public identity-provider operation. Tenant is derived server-side from validated
        identity and current membership; supplied tenant IDs are rejected. Role, active-account,
        site/department, feature and configured MFA policies apply. Mutations use controlled domain commands
        and attributable security events. Reads have no signature/audit mutation effect. Lists use ascending
        UUID cursors, default 50/max 100. All responses are uncached with X-Request-ID. Verified principals
        are limited to 120 domain requests/minute; Auth operations also use provider limits. Versioned updates
        require expected_version and return 412 when stale. Invitation links are shared by the inviting
        administrator; this API does not send email. Machine clients support organization:read, sites:read and
        departments:read only; no human signatures or approval capabilities. Expiry is required (maximum 90
        days). Cookie mutations require matching Origin; bearer integrations do not use ambient cookies.
        Idempotency applies to domain mutations only; auth commands use provider semantics.
      tags:
        - Foundation
      security: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CredentialsInput"
            example:
              email: reader@example.test
              password: use-your-own-password
      responses:
        "200":
          $ref: "#/components/responses/FoundationAuthResult"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/auth/sign-up:
    post:
      operationId: auth_sign_up
      summary: auth sign up
      description: auth.sign-up. Public identity-provider operation. Tenant is derived server-side from validated
        identity and current membership; supplied tenant IDs are rejected. Role, active-account,
        site/department, feature and configured MFA policies apply. Mutations use controlled domain commands
        and attributable security events. Reads have no signature/audit mutation effect. Lists use ascending
        UUID cursors, default 50/max 100. All responses are uncached with X-Request-ID. Verified principals
        are limited to 120 domain requests/minute; Auth operations also use provider limits. Versioned updates
        require expected_version and return 412 when stale. Invitation links are shared by the inviting
        administrator; this API does not send email. Machine clients support organization:read, sites:read and
        departments:read only; no human signatures or approval capabilities. Expiry is required (maximum 90
        days). Cookie mutations require matching Origin; bearer integrations do not use ambient cookies.
        Idempotency applies to domain mutations only; auth commands use provider semantics.
      tags:
        - Foundation
      security: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CredentialsInput"
            example:
              email: reader@example.test
              password: use-your-own-password
      responses:
        "200":
          $ref: "#/components/responses/FoundationAuthResult"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/auth/sign-out:
    post:
      operationId: auth_sign_out
      summary: auth sign out
      description: auth.sign-out. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EmptyInput"
            example: {}
      responses:
        "200":
          $ref: "#/components/responses/FoundationAuthResult"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/auth/reset-password:
    post:
      operationId: auth_reset_password
      summary: auth reset password
      description: auth.reset-password. Public identity-provider operation. Tenant is derived server-side from
        validated identity and current membership; supplied tenant IDs are rejected. Role, active-account,
        site/department, feature and configured MFA policies apply. Mutations use controlled domain commands
        and attributable security events. Reads have no signature/audit mutation effect. Lists use ascending
        UUID cursors, default 50/max 100. All responses are uncached with X-Request-ID. Verified principals
        are limited to 120 domain requests/minute; Auth operations also use provider limits. Versioned updates
        require expected_version and return 412 when stale. Invitation links are shared by the inviting
        administrator; this API does not send email. Machine clients support organization:read, sites:read and
        departments:read only; no human signatures or approval capabilities. Expiry is required (maximum 90
        days). Cookie mutations require matching Origin; bearer integrations do not use ambient cookies.
        Idempotency applies to domain mutations only; auth commands use provider semantics.
      tags:
        - Foundation
      security: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EmailInput"
            example:
              email: reader@example.test
      responses:
        "200":
          $ref: "#/components/responses/FoundationAuthResult"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/auth/password:
    post:
      operationId: auth_password
      summary: auth password
      description: auth.password. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PasswordInput"
            example:
              password: use-your-own-password
      responses:
        "200":
          $ref: "#/components/responses/FoundationAuthResult"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/auth/confirm:
    post:
      operationId: auth_confirm
      summary: auth confirm
      description: auth.confirm. Public identity-provider operation. Tenant is derived server-side from validated
        identity and current membership; supplied tenant IDs are rejected. Role, active-account,
        site/department, feature and configured MFA policies apply. Mutations use controlled domain commands
        and attributable security events. Reads have no signature/audit mutation effect. Lists use ascending
        UUID cursors, default 50/max 100. All responses are uncached with X-Request-ID. Verified principals
        are limited to 120 domain requests/minute; Auth operations also use provider limits. Versioned updates
        require expected_version and return 412 when stale. Invitation links are shared by the inviting
        administrator; this API does not send email. Machine clients support organization:read, sites:read and
        departments:read only; no human signatures or approval capabilities. Expiry is required (maximum 90
        days). Cookie mutations require matching Origin; bearer integrations do not use ambient cookies.
        Idempotency applies to domain mutations only; auth commands use provider semantics.
      tags:
        - Foundation
      security: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ConfirmInput"
            example:
              code: EXAMPLE
      responses:
        "200":
          $ref: "#/components/responses/FoundationAuthResult"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/auth/mfa:
    get:
      operationId: auth_mfa
      summary: auth mfa
      description: auth.mfa. Verified human session required; machine credentials are forbidden. Tenant is derived
        server-side from validated identity and current membership; supplied tenant IDs are rejected. Role,
        active-account, site/department, feature and configured MFA policies apply. Mutations use controlled
        domain commands and attributable security events. Reads have no signature/audit mutation effect. Lists
        use ascending UUID cursors, default 50/max 100. All responses are uncached with X-Request-ID. Verified
        principals are limited to 120 domain requests/minute; Auth operations also use provider limits.
        Versioned updates require expected_version and return 412 when stale. Invitation links are shared by
        the inviting administrator; this API does not send email. Machine clients support organization:read,
        sites:read and departments:read only; no human signatures or approval capabilities. Expiry is required
        (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do not use ambient
        cookies. Idempotency applies to domain mutations only; auth commands use provider semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 50
      responses:
        "200":
          $ref: "#/components/responses/FoundationMfaStatus"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/auth/mfa/enroll:
    post:
      operationId: auth_mfa_enroll
      summary: auth mfa enroll
      description: auth.mfa.enroll. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/EmptyInput"
            example: {}
      responses:
        "200":
          $ref: "#/components/responses/FoundationMfaEnrollment"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/auth/mfa/verify:
    post:
      operationId: auth_mfa_verify
      summary: auth mfa verify
      description: auth.mfa.verify. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MfaVerifyInput"
            example:
              factor_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              code: "000000"
      responses:
        "200":
          $ref: "#/components/responses/FoundationAuthResult"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/auth/mfa/disable:
    post:
      operationId: auth_mfa_disable
      summary: auth mfa disable
      description: auth.mfa.disable. Verified human session required; machine credentials are forbidden. Tenant is
        derived server-side from validated identity and current membership; supplied tenant IDs are rejected.
        Role, active-account, site/department, feature and configured MFA policies apply. Mutations use
        controlled domain commands and attributable security events. Reads have no signature/audit mutation
        effect. Lists use ascending UUID cursors, default 50/max 100. All responses are uncached with
        X-Request-ID. Verified principals are limited to 120 domain requests/minute; Auth operations also use
        provider limits. Versioned updates require expected_version and return 412 when stale. Invitation
        links are shared by the inviting administrator; this API does not send email. Machine clients support
        organization:read, sites:read and departments:read only; no human signatures or approval capabilities.
        Expiry is required (maximum 90 days). Cookie mutations require matching Origin; bearer integrations do
        not use ambient cookies. Idempotency applies to domain mutations only; auth commands use provider
        semantics.
      tags:
        - Foundation
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/MfaFactorInput"
            example:
              factor_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
      responses:
        "200":
          $ref: "#/components/responses/FoundationAuthResult"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/records:
    get:
      operationId: integrity_records_list
      summary: integrity records list
      description: integrity.records.list. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityRecordsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: integrity_records_create
      summary: integrity records create
      description: integrity.records.create. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/IntegrityCreate"
            example:
              title: Example
              content: Example
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityRecord"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/records/{id}:
    get:
      operationId: integrity_records_get
      summary: integrity records get
      description: integrity.records.get. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    patch:
      operationId: integrity_records_update
      summary: integrity records update
      description: integrity.records.update. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                title:
                  type: string
                  minLength: 2
                  maxLength: 200
                content:
                  type: string
                  minLength: 0
                  maxLength: 10000
              required:
                - expected_version
                - reason
                - title
                - content
            example:
              expected_version: 1
              reason: Example
              title: Example
              content: Example
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityRecord"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/records/{id}/sign:
    post:
      operationId: integrity_records_sign
      summary: integrity records sign
      description: integrity.records.sign. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                content_hash:
                  type: string
                  pattern: ^[a-f0-9]{64}$
                meaning:
                  enum:
                    - authorship
                    - review
                    - acknowledgement
                consent:
                  type: boolean
                  const: true
                password:
                  type: string
                  minLength: 12
                  maxLength: 128
                mfa_code:
                  type: string
                  pattern: ^[0-9]{6}$
              required:
                - expected_version
                - reason
                - content_hash
                - meaning
                - consent
                - password
            example:
              expected_version: 1
              reason: Example
              content_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              meaning: authorship
              consent: true
              password: your-own-password
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegritySignature"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/records/{id}/cancel:
    post:
      operationId: integrity_records_cancel
      summary: integrity records cancel
      description: integrity.records.cancel. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityRecord"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/records/{id}/retention:
    post:
      operationId: integrity_records_retention
      summary: integrity records retention
      description: integrity.records.retention. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                legal_hold:
                  type: boolean
                retain_until:
                  type: string
                  format: date-time
              required:
                - expected_version
                - reason
                - legal_hold
                - retain_until
            example:
              expected_version: 1
              reason: Example
              legal_hold: false
              retain_until: 2026-10-18T10:00:00Z
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityRecord"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/records/{id}/archive:
    post:
      operationId: integrity_records_archive
      summary: integrity records archive
      description: integrity.records.archive. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityRecord"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/records/{id}/comments:
    post:
      operationId: integrity_comments_create
      summary: integrity comments create
      description: integrity.comments.create. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                body:
                  type: string
                  minLength: 1
                  maxLength: 2000
              required:
                - expected_version
                - reason
                - body
            example:
              expected_version: 1
              reason: Example
              body: Example
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityComment"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/records/{id}/links:
    post:
      operationId: integrity_links_create
      summary: integrity links create
      description: integrity.links.create. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                target_id:
                  type: string
                  format: uuid
                relation:
                  enum:
                    - related
                    - supports
                    - supersedes
              required:
                - expected_version
                - reason
                - target_id
                - relation
            example:
              expected_version: 1
              reason: Example
              target_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              relation: related
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityLink"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/records/{id}/attachments:
    post:
      operationId: integrity_attachments_reserve
      summary: integrity attachments reserve
      description: integrity.attachments.reserve. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                filename:
                  type: string
                  minLength: 1
                  maxLength: 180
                  pattern: ^[^/\\]+$
                mime_type:
                  enum:
                    - text/plain
                    - application/pdf
                size_bytes:
                  type: integer
                  minimum: 1
                  maximum: 10485760
                sha256:
                  type: string
                  pattern: ^[a-f0-9]{64}$
              required:
                - expected_version
                - reason
                - filename
                - mime_type
                - size_bytes
                - sha256
            example:
              expected_version: 1
              reason: Example
              filename: Example
              mime_type: text/plain
              size_bytes: 1
              sha256: "0000000000000000000000000000000000000000000000000000000000000000"
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityAttachment"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/attachments/{id}/download:
    post:
      operationId: integrity_attachments_download
      summary: integrity attachments download
      description: integrity.attachments.download. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties: {}
              required: []
            example: {}
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityDownload"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/settings:
    get:
      operationId: integrity_settings_get
      summary: integrity settings get
      description: integrity.settings.get. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegritySettings"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    patch:
      operationId: integrity_settings_update
      summary: integrity settings update
      description: integrity.settings.update. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/IntegritySettingsInput"
            example:
              prefix: TEST
              retention_years: 1
              vocabulary:
                - Example
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegritySettings"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/audit:
    get:
      operationId: integrity_audit_list
      summary: integrity audit list
      description: integrity.audit.list. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
        - name: record_id
          in: query
          schema:
            type: string
            format: uuid
        - name: action
          in: query
          schema:
            type: string
            minLength: 1
            maxLength: 100
        - name: since
          in: query
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          schema:
            type: string
            format: date-time
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityAuditPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/notifications:
    get:
      operationId: integrity_notifications_list
      summary: integrity notifications list
      description: integrity.notifications.list. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityNotificationsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/notifications/{id}/read:
    post:
      operationId: integrity_notifications_read
      summary: integrity notifications read
      description: integrity.notifications.read. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties: {}
              required: []
            example: {}
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityNotification"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/attachments/{id}/upload:
    post:
      operationId: integrity_attachments_upload
      summary: integrity attachments upload
      description: integrity.attachments.upload. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                content_base64:
                  type: string
                  minLength: 4
                  maxLength: 13981016
                  pattern: ^[A-Za-z0-9+/]+={0,2}$
              required:
                - content_base64
            example:
              content_base64: Example
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseAccepted"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/integrity/records/{id}/history:
    get:
      operationId: integrity_history_list
      summary: integrity history list
      description: integrity.history.list. Verified human session only; machine keys forbidden. Tenant and
        site/department scope derive from live membership. integrity.read is required; writes require
        integrity.write; signatures separately require integrity.sign, explicit consent and fresh password
        reauthentication; numbering/retention settings require fully scoped integrity.admin. No administrative
        role implicitly grants signature authority. Mutations require reason, Idempotency-Key and
        expected_version where applicable; stale versions return 412. Signing binds immutable version hash
        including attachment references, preserving earlier signatures on revision. Number allocation, state,
        audit and outbox persist in one transaction. Cancelled numbers are never reused. Quarantined
        attachments cannot be downloaded or signed; downloads last 60 seconds and are bearer links valid until
        expiry. Attachments are immutable and limited to 10 MiB PDF/text. Lists use ascending UUID cursors, 50
        default/100 maximum; responses are uncached. 120 verified-principal requests per minute. Audit
        technical before/after details require security.read; filters apply before cursor pagination. Export
        audit by paging this API and preserving request IDs. Notification delivery is asynchronous and
        retry-safe; notification list/read have no record mutation. Test-record signing is not a regulated
        quality approval.
      tags:
        - Integrity
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: kind
          in: query
          schema:
            enum:
              - versions
              - signatures
              - comments
              - links
              - attachments
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
      responses:
        "200":
          $ref: "#/components/responses/IntegrityResponseIntegrityHistoryPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/workflows/calendars:
    get:
      operationId: workflow_calendars_list
      summary: workflow calendars list
      description: workflow.calendars.list. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowCalendarsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: workflow_calendars_create
      summary: workflow calendars create
      description: workflow.calendars.create. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WorkflowCalendarInput"
            example:
              name: Example
              timezone: UTC
              weekdays:
                - 1
              start_minute: 0
              end_minute: 1
              holidays: []
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowCalendar"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/workflows/templates:
    get:
      operationId: workflow_templates_list
      summary: workflow templates list
      description: workflow.templates.list. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowTemplatesPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: workflow_templates_publish
      summary: workflow templates publish
      description: workflow.templates.publish. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WorkflowTemplateInput"
            example:
              name: Example
              expected_version: 0
              calendar_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              site_ids: []
              categories: []
              stages:
                - id: Example
                  name: Example
                  mode: sequential
                  selector:
                    kind: named
                    userIds:
                      - 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                  signedActions: []
                  allowDelegation: false
                  slaHours: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowTemplate"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/workflows/instances:
    get:
      operationId: workflow_instances_list
      summary: workflow instances list
      description: workflow.instances.list. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowInstancesPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: workflow_instances_start
      summary: workflow instances start
      description: workflow.instances.start. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WorkflowStartInput"
            example:
              record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowInstance"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/workflows/instances/{id}:
    get:
      operationId: workflow_instances_get
      summary: workflow instances get
      description: workflow.instances.get. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/workflows/instances/{id}/actions:
    post:
      operationId: workflow_instances_act
      summary: workflow instances act
      description: workflow.instances.act. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                action:
                  enum:
                    - approve
                    - reject
                    - request_changes
                    - delegate
                    - reassign
                    - withdraw
                    - resubmit
                    - close
                    - void
                task_id:
                  type: string
                  format: uuid
                target_id:
                  type: string
                  format: uuid
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                consent:
                  type: boolean
                password:
                  type: string
                  minLength: 12
                  maxLength: 128
                  writeOnly: true
                mfa_code:
                  type: string
                  pattern: ^[0-9]{6}$
                  writeOnly: true
              required:
                - action
                - expected_version
                - reason
            example:
              action: approve
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowInstance"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/workflows/instances/{id}/events:
    get:
      operationId: workflow_events_list
      summary: workflow events list
      description: workflow.events.list. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowEventsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/workflows/tasks:
    get:
      operationId: workflow_tasks_list
      summary: workflow tasks list
      description: workflow.tasks.list. Verified human only; integration keys are forbidden. Tenant/live membership,
        MFA and record site/department scope are authoritative. Explicit workflow.submit/review/manage/close
        permissions apply; publishing and reassignment require fully scoped workflow.manage. Webhook
        configuration/recovery requires webhooks.manage. Administration never implicitly grants
        review/signature authority. Mutations require a reason and actor-scoped idempotency key;
        expected_version returns 412 on conflict. Configured signed decisions require consent=true and fresh
        password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app notification
        and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds a new record
        version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowTasksPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/workflows/webhooks:
    get:
      operationId: workflow_webhooks_list
      summary: workflow webhooks list
      description: workflow.webhooks.list. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowWebhooksPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: workflow_webhooks_create
      summary: workflow webhooks create
      description: workflow.webhooks.create. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WorkflowWebhookInput"
            example:
              name: Example
              url: https://example.test/eqms
              event_types:
                - workflow.submitted.v1
              enabled: false
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowWebhookIssued"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/workflows/webhooks/{id}:
    patch:
      operationId: workflow_webhooks_update
      summary: workflow webhooks update
      description: workflow.webhooks.update. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                enabled:
                  type: boolean
              required:
                - expected_version
                - reason
                - enabled
            example:
              expected_version: 1
              reason: Example
              enabled: false
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowWebhook"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/workflows/webhooks/{id}/rotate:
    post:
      operationId: workflow_webhooks_rotate
      summary: workflow webhooks rotate
      description: workflow.webhooks.rotate. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowWebhookIssued"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/workflows/deliveries:
    get:
      operationId: workflow_deliveries_list
      summary: workflow deliveries list
      description: workflow.deliveries.list. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowDeliveriesPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/workflows/deliveries/{id}/replay:
    post:
      operationId: workflow_deliveries_replay
      summary: workflow deliveries replay
      description: workflow.deliveries.replay. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - reason
            example:
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowDelivery"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/workflows/instances/{id}/history:
    get:
      operationId: workflow_history_list
      summary: workflow history list
      description: workflow.history.list. Verified human only; integration keys are forbidden. Tenant/live
        membership, MFA and record site/department scope are authoritative. Explicit
        workflow.submit/review/manage/close permissions apply; publishing and reassignment require fully
        scoped workflow.manage. Webhook configuration/recovery requires webhooks.manage. Administration never
        implicitly grants review/signature authority. Mutations require a reason and actor-scoped idempotency
        key; expected_version returns 412 on conflict. Configured signed decisions require consent=true and
        fresh password/MFA reauthentication plus integrity.sign. Signature, transition, audit, in-app
        notification and webhook outbox persist atomically. Later reviewers remain blocked. Resubmission binds
        a new record version and preserves previous rounds. Calendar deadlines use configured local
        weekdays/windows/holidays and absolute UTC instants. Lists use UUID cursors (50 default/100 max), 120
        principal requests/minute and uncached request IDs. Webhook secrets are revealed once and excluded
        from replay/audit; worker destinations require a separate exact-host allowlist, HTTPS and
        public-address validation. Delivery IDs/events remain stable across retries and manual dead-letter
        replay. Detailed tasks show the current round (max 2000); event history is paged. Templates and round
        snapshots are immutable.
      tags:
        - Workflows
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: kind
          in: query
          schema:
            enum:
              - rounds
              - tasks
          required: true
        - name: round
          in: query
          schema:
            type: integer
            minimum: 1
          required: false
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/WorkflowResponseWorkflowHistoryPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/templates:
    get:
      operationId: forms_templates_list
      summary: forms templates list
      description: forms.templates.list. Verified human only. Live tenant membership/MFA and site/department scope
        are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormTemplatesPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: forms_templates_create
      summary: forms templates create
      description: forms.templates.create. Verified human only. Live tenant membership/MFA and site/department scope
        are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FormDraftInput"
            example:
              definition:
                name: Example
                schema:
                  schemaVersion: 1
                  sections:
                    - id: main
                      title: Example
                      columns: 1
                  fields: []
                  rules: []
                site_ids: []
                department_ids: []
                workflow_template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormTemplate"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/templates/{id}:
    get:
      operationId: forms_templates_get
      summary: forms templates get
      description: forms.templates.get. Verified human only. Live tenant membership/MFA and site/department scope
        are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormTemplateDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    patch:
      operationId: forms_templates_revise
      summary: forms templates revise
      description: forms.templates.revise. Verified human only. Live tenant membership/MFA and site/department scope
        are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                definition:
                  $ref: "#/components/schemas/FormDefinition"
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - definition
                - reason
            example:
              expected_version: 1
              definition:
                name: Example
                schema:
                  schemaVersion: 1
                  sections:
                    - id: main
                      title: Example
                      columns: 1
                  fields: []
                  rules: []
                site_ids: []
                department_ids: []
                workflow_template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormTemplate"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/templates/{id}/publish:
    post:
      operationId: forms_templates_publish
      summary: forms templates publish
      description: forms.templates.publish. Verified human only. Live tenant membership/MFA and site/department
        scope are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormPublication"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/publications:
    get:
      operationId: forms_publications_list
      summary: forms publications list
      description: forms.publications.list. Verified human only. Live tenant membership/MFA and site/department
        scope are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormPublicationsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/publications/{id}:
    get:
      operationId: forms_publications_get
      summary: forms publications get
      description: forms.publications.get. Verified human only. Live tenant membership/MFA and site/department scope
        are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormPublication"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/records:
    get:
      operationId: forms_records_list
      summary: forms records list
      description: forms.records.list. Verified human only. Live tenant membership/MFA and site/department scope are
        authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
        - name: q
          in: query
          schema:
            type: string
            minLength: 0
            maxLength: 100
          required: false
        - name: template_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: site_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: department_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: state
          in: query
          schema:
            enum:
              - draft
              - active
              - approved
              - closed
              - rejected
              - changes_requested
              - withdrawn
              - void
          required: false
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormRecordsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: forms_records_create
      summary: forms records create
      description: forms.records.create. Verified human only. Live tenant membership/MFA and site/department scope
        are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FormRecordInput"
            example:
              publication_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              title: Example
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              values: {}
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormRecordDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/records/{id}:
    get:
      operationId: forms_records_get
      summary: forms records get
      description: forms.records.get. Verified human only. Live tenant membership/MFA and site/department scope are
        authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: version
          in: query
          schema:
            type: integer
            minimum: 1
          required: false
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormRecordDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    patch:
      operationId: forms_records_correct
      summary: forms records correct
      description: forms.records.correct. Verified human only. Live tenant membership/MFA and site/department scope
        are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                title:
                  type: string
                  minLength: 2
                  maxLength: 200
                values:
                  $ref: "#/components/schemas/FormValues"
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - title
                - values
                - reason
            example:
              expected_version: 1
              title: Example
              values: {}
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormRecordDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/records/{id}/submit:
    post:
      operationId: forms_records_submit
      summary: forms records submit
      description: forms.records.submit. Verified human only. Live tenant membership/MFA and site/department scope
        are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                values:
                  $ref: "#/components/schemas/FormValues"
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormRecordDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/records/{id}/attachments:
    post:
      operationId: forms_attachments_reserve
      summary: forms attachments reserve
      description: forms.attachments.reserve. Verified human only. Live tenant membership/MFA and site/department
        scope are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                field_id:
                  type: string
                  pattern: ^[a-z][a-z0-9_]{0,39}$
                filename:
                  type: string
                  minLength: 1
                  maxLength: 180
                mime_type:
                  enum:
                    - text/plain
                    - application/pdf
                size_bytes:
                  type: integer
                  minimum: 1
                  maximum: 10000000
                sha256:
                  type: string
                  pattern: ^[a-f0-9]{64}$
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - field_id
                - filename
                - mime_type
                - size_bytes
                - sha256
                - reason
            example:
              expected_version: 1
              field_id: main
              filename: Example
              mime_type: text/plain
              size_bytes: 1
              sha256: "0000000000000000000000000000000000000000000000000000000000000000"
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/FormResponseIntegrityAttachment"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/history:
    get:
      operationId: forms_history_list
      summary: forms history list
      description: forms.history.list. Verified human only. Live tenant membership/MFA and site/department scope are
        authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: query
          schema:
            type: string
            format: uuid
          required: true
        - name: resource
          in: query
          schema:
            enum:
              - template
              - record
              - vocabulary
          required: true
        - name: kind
          in: query
          schema:
            enum:
              - drafts
              - publications
          required: false
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormHistoryPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/vocabularies:
    get:
      operationId: forms_vocabularies_list
      summary: forms vocabularies list
      description: forms.vocabularies.list. Verified human only. Live tenant membership/MFA and site/department
        scope are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormVocabulariesPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: forms_vocabularies_create
      summary: forms vocabularies create
      description: forms.vocabularies.create. Verified human only. Live tenant membership/MFA and site/department
        scope are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FormVocabularyInput"
            example:
              name: Example
              options:
                - value: Example
                  label: Example
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormVocabulary"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/vocabularies/{id}:
    patch:
      operationId: forms_vocabularies_update
      summary: forms vocabularies update
      description: forms.vocabularies.update. Verified human only. Live tenant membership/MFA and site/department
        scope are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                name:
                  type: string
                  minLength: 2
                  maxLength: 120
                options:
                  type: array
                  items:
                    $ref: "#/components/schemas/FormOption"
                  maxItems: 100
                  minItems: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - name
                - options
                - reason
            example:
              expected_version: 1
              name: Example
              options:
                - value: Example
                  label: Example
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormVocabulary"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/references:
    get:
      operationId: forms_references_list
      summary: forms references list
      description: forms.references.list. Verified human only. Live tenant membership/MFA and site/department scope
        are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
        - name: kind
          in: query
          schema:
            enum:
              - product
              - material
              - batch
              - equipment
              - supplier
              - document
          required: false
        - name: site_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormReferencesPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: forms_references_create
      summary: forms references create
      description: forms.references.create. Verified human only. Live tenant membership/MFA and site/department
        scope are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FormReferenceInput"
            example:
              kind: product
              code: Example
              name: Example
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormReference"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/references/{id}:
    patch:
      operationId: forms_references_update
      summary: forms references update
      description: forms.references.update. Verified human only. Live tenant membership/MFA and site/department
        scope are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                name:
                  type: string
                  minLength: 1
                  maxLength: 160
                active:
                  type: boolean
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - name
                - active
                - reason
            example:
              expected_version: 1
              name: Example
              active: false
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormReference"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/options:
    get:
      operationId: forms_options_list
      summary: forms options list
      description: forms.options.list. Verified human only. Live tenant membership/MFA and site/department scope are
        authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: publication_id
          in: query
          schema:
            type: string
            format: uuid
          required: true
        - name: field_id
          in: query
          schema:
            type: string
            pattern: ^[a-z][a-z0-9_]{0,39}$
          required: true
        - name: site_id
          in: query
          schema:
            type: string
            format: uuid
          required: true
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormOptionsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/views:
    get:
      operationId: forms_views_list
      summary: forms views list
      description: forms.views.list. Verified human only. Live tenant membership/MFA and site/department scope are
        authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormViewsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: forms_views_create
      summary: forms views create
      description: forms.views.create. Verified human only. Live tenant membership/MFA and site/department scope are
        authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/FormViewInput"
            example:
              name: Example
              filters: {}
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormView"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/views/{id}:
    patch:
      operationId: forms_views_update
      summary: forms views update
      description: forms.views.update. Verified human only. Live tenant membership/MFA and site/department scope are
        authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                name:
                  type: string
                  minLength: 2
                  maxLength: 80
                filters:
                  $ref: "#/components/schemas/FormFilters"
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - name
                - filters
                - reason
            example:
              expected_version: 1
              name: Example
              filters: {}
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormView"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/exports:
    get:
      operationId: forms_exports_list
      summary: forms exports list
      description: forms.exports.list. Verified human only. Live tenant membership/MFA and site/department scope are
        authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormExportsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/records/{id}/exports:
    post:
      operationId: forms_exports_create
      summary: forms exports create
      description: forms.exports.create. Verified human only. Live tenant membership/MFA and site/department scope
        are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                version:
                  type: integer
                  minimum: 1
                format:
                  enum:
                    - pdf
                    - json
                    - csv
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - format
                - reason
            example:
              format: pdf
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormExport"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/exports/{id}/download:
    post:
      operationId: forms_exports_download
      summary: forms exports download
      description: forms.exports.download. Verified human only. Live tenant membership/MFA and site/department scope
        are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties: {}
              required: []
            example: {}
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormDownload"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/context:
    get:
      operationId: forms_context_get
      summary: forms context get
      description: forms.context.get. Verified human only. Live tenant membership/MFA and site/department scope are
        authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters: []
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormAccess"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/forms/locations:
    get:
      operationId: forms_locations_list
      summary: forms locations list
      description: forms.locations.list. Verified human only. Live tenant membership/MFA and site/department scope
        are authoritative; machine integration keys are forbidden. Explicit
        forms.read/manage/execute/submit/export and shared integrity permissions apply; management requires
        full scope. Draft revisions and published schema/vocabulary snapshots are preserved. Expressions are
        bounded JSON operators; arbitrary code/HTML and unbounded regular expressions are forbidden. Hidden,
        generated, calculated and role-restricted field edits fail at the database boundary. Repeating rows
        use stable _row_id UUIDs; protected cells survive reordering and cannot be removed by unprivileged
        editors. Submit validates all rules and atomically binds a new exact record version to the published
        workflow; configured approvals reuse fresh human signatures. Lists use UUID cursors (50 default/100
        maximum); historical version retrieval never adopts a newer schema. Stored field values and frozen
        display labels are projected by current field roles; no raw values enter shared audit/receipts.
        Corrections require reasons, expected_version and actor-scoped idempotency. Requests are bounded to 32
        KiB, canonical form values to 20 KiB, schema fields to 100, one grid level to 100 rows/20 columns and
        expressions to depth 12. Export requests queue private immutable PDF/JSON/CSV jobs; a separately
        hosted worker is required. Downloads recheck current scope/field access and issue 60-second bearer
        URLs. Saved views remain private to their owner and do not bypass current filters.
      tags:
        - Forms
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: kind
          in: query
          schema:
            enum:
              - site
              - department
          required: true
        - name: site_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/FormResponseFormLocationsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/documents:
    get:
      operationId: documents_register_list
      summary: documents register list
      description: "documents.register.list. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseDocumentPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: documents_register_create
      summary: documents register create
      description: "documents.register.create. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/DocumentCreate"
            example:
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              definition:
                title: Example
                kind: sop
                owner_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                change_summary: Example
                effective_at: 2026-10-18T10:00:00Z
                review_on: 2026-10-18
                expires_on: 2026-10-18
                workflow_template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                training_rule: none
                external_reference: Example
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseDocumentDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/documents/{id}:
    get:
      operationId: documents_register_get
      summary: documents register get
      description: "documents.register.get. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseDocumentDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/documents/{id}/policy:
    patch:
      operationId: documents_policy_update
      summary: documents policy update
      description: "documents.policy.update. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                allow_download:
                  type: boolean
                allow_print:
                  type: boolean
              required:
                - expected_version
                - reason
                - allow_download
                - allow_print
            example:
              expected_version: 1
              reason: Example
              allow_download: false
              allow_print: false
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseDocumentDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/documents/{id}/revisions:
    post:
      operationId: documents_revisions_create
      summary: documents revisions create
      description: "documents.revisions.create. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                definition:
                  $ref: "#/components/schemas/DocumentDefinition"
              required:
                - expected_version
                - reason
                - definition
            example:
              expected_version: 1
              reason: Example
              definition:
                title: Example
                kind: sop
                owner_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                change_summary: Example
                effective_at: 2026-10-18T10:00:00Z
                review_on: 2026-10-18
                expires_on: 2026-10-18
                workflow_template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                training_rule: none
                external_reference: Example
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseDocumentDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/document-revisions/{id}:
    patch:
      operationId: documents_revisions_correct
      summary: documents revisions correct
      description: "documents.revisions.correct. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                definition:
                  $ref: "#/components/schemas/DocumentDefinition"
              required:
                - expected_version
                - reason
                - definition
            example:
              expected_version: 1
              reason: Example
              definition:
                title: Example
                kind: sop
                owner_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                change_summary: Example
                effective_at: 2026-10-18T10:00:00Z
                review_on: 2026-10-18
                expires_on: 2026-10-18
                workflow_template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                training_rule: none
                external_reference: Example
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseDocumentDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/document-revisions/{id}/source:
    post:
      operationId: documents_sources_reserve
      summary: documents sources reserve
      description: "documents.sources.reserve. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                filename:
                  type: string
                  minLength: 1
                  maxLength: 180
                mime_type:
                  enum:
                    - text/plain
                    - application/pdf
                size_bytes:
                  type: integer
                  minimum: 1
                  maximum: 10485760
                sha256:
                  type: string
                  pattern: ^[a-f0-9]{64}$
              required:
                - expected_version
                - reason
                - filename
                - mime_type
                - size_bytes
                - sha256
            example:
              expected_version: 1
              reason: Example
              filename: Example
              mime_type: text/plain
              size_bytes: 1
              sha256: "0000000000000000000000000000000000000000000000000000000000000000"
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseIntegrityAttachment"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/document-revisions/{id}/submit:
    post:
      operationId: documents_revisions_submit
      summary: documents revisions submit
      description: "documents.revisions.submit. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseDocumentDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/document-revisions/{id}/issue:
    post:
      operationId: documents_revisions_issue
      summary: documents revisions issue
      description: "documents.revisions.issue. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseDocumentDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/document-revisions/{id}/reconcile:
    post:
      operationId: documents_revisions_reconcile
      summary: documents revisions reconcile
      description: "documents.revisions.reconcile. Verified human and live tenant/MFA/site/department scope
        required; integration keys forbidden. Explicit module permissions and shared integrity permissions
        apply. Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseDocumentDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/training/courses:
    get:
      operationId: training_courses_list
      summary: training courses list
      description: "training.courses.list. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseTrainingCoursesPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: training_courses_create
      summary: training courses create
      description: "training.courses.create. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TrainingCourseCreate"
            example:
              definition:
                name: Example
                mode: document
                document_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                requires_verification: false
                valid_days: 1
                pass_mark: 1
                max_attempts: 1
                questions: []
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseTrainingPublication"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/training/courses/{id}:
    patch:
      operationId: training_courses_revise
      summary: training courses revise
      description: "training.courses.revise. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                definition:
                  $ref: "#/components/schemas/TrainingDefinition"
              required:
                - expected_version
                - reason
                - definition
            example:
              expected_version: 1
              reason: Example
              definition:
                name: Example
                mode: document
                document_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                requires_verification: false
                valid_days: 1
                pass_mark: 1
                max_attempts: 1
                questions: []
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseTrainingPublication"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/training/courses/{id}/answer-key:
    get:
      operationId: training_courses_key
      summary: training courses key
      description: "training.courses.key. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseTrainingDefinition"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/training/assignments:
    get:
      operationId: training_assignments_list
      summary: training assignments list
      description: "training.assignments.list. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseTrainingAssignmentsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: training_assignments_create
      summary: training assignments create
      description: "training.assignments.create. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TrainingAssign"
            example:
              course_version_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              document_revision_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              assignee_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              supervisor_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              due_at: 2026-10-18T10:00:00Z
              grace_days: 1
              required: false
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseTrainingAssignment"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/training/assignments/{id}:
    get:
      operationId: training_assignments_get
      summary: training assignments get
      description: "training.assignments.get. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseTrainingDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/training/assignments/{id}/complete:
    post:
      operationId: training_assignments_complete
      summary: training assignments complete
      description: "training.assignments.complete. Verified human and live tenant/MFA/site/department scope
        required; integration keys forbidden. Explicit module permissions and shared integrity permissions
        apply. Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                password:
                  type: string
                  minLength: 1
                  maxLength: 1024
                mfa_code:
                  type: string
                  pattern: ^[0-9]{6}$
                consent:
                  type: boolean
                  const: true
                answers:
                  type: object
                  maxProperties: 20
                  propertyNames:
                    type: string
                    pattern: ^[a-z][a-z0-9_]{0,39}$
                  additionalProperties:
                    type: integer
                    minimum: 0
                    maximum: 9
                activity:
                  type: object
                  additionalProperties: false
                  properties:
                    completed_on:
                      type: string
                      format: date
                    instructor:
                      type: string
                      minLength: 2
                      maxLength: 300
                    provider:
                      type: string
                      minLength: 2
                      maxLength: 300
                    certificate_reference:
                      type: string
                      minLength: 1
                      maxLength: 300
                  required: []
              required:
                - expected_version
                - reason
                - password
                - consent
                - answers
                - activity
            example:
              expected_version: 1
              reason: Example
              password: Example
              consent: true
              answers: {}
              activity: {}
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseTrainingDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/training/assignments/{id}/verify:
    post:
      operationId: training_assignments_verify
      summary: training assignments verify
      description: "training.assignments.verify. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                password:
                  type: string
                  minLength: 1
                  maxLength: 1024
                mfa_code:
                  type: string
                  pattern: ^[0-9]{6}$
                consent:
                  type: boolean
                  const: true
              required:
                - expected_version
                - reason
                - password
                - consent
            example:
              expected_version: 1
              reason: Example
              password: Example
              consent: true
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseTrainingDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/training/assignments/{id}/deadline:
    patch:
      operationId: training_assignments_extend
      summary: training assignments extend
      description: "training.assignments.extend. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                extra_attempts:
                  type: integer
                  minimum: 0
                  maximum: 10
                due_at:
                  type: string
                  format: date-time
                grace_days:
                  type: integer
                  minimum: 0
                  maximum: 90
              required:
                - expected_version
                - reason
                - extra_attempts
                - due_at
                - grace_days
            example:
              expected_version: 1
              reason: Example
              extra_attempts: 1
              due_at: 2026-10-18T10:00:00Z
              grace_days: 1
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseTrainingDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/training/assignments/{id}/evidence:
    post:
      operationId: training_evidence_reserve
      summary: training evidence reserve
      description: "training.evidence.reserve. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                filename:
                  type: string
                  minLength: 1
                  maxLength: 180
                mime_type:
                  enum:
                    - text/plain
                    - application/pdf
                size_bytes:
                  type: integer
                  minimum: 1
                  maximum: 10485760
                sha256:
                  type: string
                  pattern: ^[a-f0-9]{64}$
              required:
                - expected_version
                - reason
                - filename
                - mime_type
                - size_bytes
                - sha256
            example:
              expected_version: 1
              reason: Example
              filename: Example
              mime_type: text/plain
              size_bytes: 1
              sha256: "0000000000000000000000000000000000000000000000000000000000000000"
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseIntegrityAttachment"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/document-revisions/{id}/copies:
    post:
      operationId: documents_copies_create
      summary: documents copies create
      description: "documents.copies.create. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                purpose:
                  enum:
                    - view
                    - download
                    - print
                    - inspection
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - purpose
                - reason
            example:
              purpose: view
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseControlledCopy"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/training/assignments/{id}/material:
    post:
      operationId: training_material_create
      summary: training material create
      description: "training.material.create. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - reason
            example:
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseControlledCopy"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/controlled-copies:
    get:
      operationId: controlled_copies_list
      summary: controlled copies list
      description: "controlled.copies.list. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseControlledCopiesPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/controlled-copies/{id}/download:
    post:
      operationId: controlled_copies_download
      summary: controlled copies download
      description: "controlled.copies.download. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties: {}
              required: []
            example: {}
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseFormDownload"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/controlled/choices:
    get:
      operationId: controlled_choices_list
      summary: controlled choices list
      description: "controlled.choices.list. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: kind
          in: query
          schema:
            enum:
              - site
              - department
              - person
              - workflow
              - obsolescence
              - role
          required: true
        - name: site_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: department_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseFormLocationsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/training/curricula:
    get:
      operationId: training_curricula_list
      summary: training curricula list
      description: "training.curricula.list. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseTrainingCurriculaPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: training_curricula_create
      summary: training curricula create
      description: "training.curricula.create. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TrainingCurriculumCreate"
            example:
              definition:
                name: Example
                role_ids: []
                site_ids: []
                department_ids: []
                course_version_ids:
                  - 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                due_days: 1
                grace_days: 1
                required: false
                supervisor_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseTrainingCurriculumPublication"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/training/curricula/{id}:
    patch:
      operationId: training_curricula_revise
      summary: training curricula revise
      description: "training.curricula.revise. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                definition:
                  $ref: "#/components/schemas/TrainingCurriculumDefinition"
              required:
                - expected_version
                - reason
                - definition
            example:
              expected_version: 1
              reason: Example
              definition:
                name: Example
                role_ids: []
                site_ids: []
                department_ids: []
                course_version_ids:
                  - 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                due_days: 1
                grace_days: 1
                required: false
                supervisor_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseTrainingCurriculumPublication"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/training/curricula/{id}/enroll:
    post:
      operationId: training_curricula_enroll
      summary: training curricula enroll
      description: "training.curricula.enroll. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                revision_id:
                  anyOf:
                    - type: string
                      format: uuid
                    - type: "null"
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - revision_id
                - reason
            example:
              revision_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseTrainingEnrollment"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/documents/{id}/obsolescence:
    post:
      operationId: documents_obsolescence_request
      summary: documents obsolescence request
      description: "documents.obsolescence.request. Verified human and live tenant/MFA/site/department scope
        required; integration keys forbidden. Explicit module permissions and shared integrity permissions
        apply. Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                workflow_template_id:
                  type: string
                  format: uuid
              required:
                - expected_version
                - reason
                - workflow_template_id
            example:
              expected_version: 1
              reason: Example
              workflow_template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseDocumentObsolescence"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/document-obsolescence/{id}/apply:
    post:
      operationId: documents_obsolescence_apply
      summary: documents obsolescence apply
      description: "documents.obsolescence.apply. Verified human and live tenant/MFA/site/department scope required;
        integration keys forbidden. Explicit module permissions and shared integrity permissions apply.
        Training management requires full tenant scope. Changes use expected versions, reasons and
        actor-scoped idempotency. Published courses and failed attempts are retained; learner projections omit
        answer keys. Assessments and verification require fresh password authentication and explicit consent.
        Approval alone does not activate a revision: the effective date and configured required qualification
        gate must pass. Document source files never use ordinary evidence downloads."
      tags:
        - Documents and training
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/ControlledResponseDocumentDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/masters:
    get:
      operationId: quality_masters_list
      summary: quality masters list
      description: quality.masters.list. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
        - name: kind
          in: query
          schema:
            type: string
            enum:
              - product
              - material
              - batch
              - process
          required: false
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityMastersPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: quality_masters_create
      summary: quality masters create
      description: quality.masters.create. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/QualityMasterCreate"
            example:
              kind: product
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              definition:
                code: EXAMPLE-1
                name: Example
                active: false
                source_system: Example
                external_id: Example
                source_uri: https://example.test/reference
                related_version_ids: []
                manufactured_on: 2027-10-18
                expires_on: 2027-10-18
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityMasterPublication"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/masters/{id}:
    get:
      operationId: quality_masters_get
      summary: quality masters get
      description: quality.masters.get. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityMasterDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    patch:
      operationId: quality_masters_revise
      summary: quality masters revise
      description: quality.masters.revise. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                definition:
                  $ref: "#/components/schemas/QualityMasterDefinition"
              required:
                - expected_version
                - reason
                - definition
            example:
              expected_version: 1
              reason: Example
              definition:
                code: EXAMPLE-1
                name: Example
                active: false
                source_system: Example
                external_id: Example
                source_uri: https://example.test/reference
                related_version_ids: []
                manufactured_on: 2027-10-18
                expires_on: 2027-10-18
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityMasterPublication"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/risk-models:
    get:
      operationId: quality_models_list
      summary: quality models list
      description: quality.models.list. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityModelsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: quality_models_create
      summary: quality models create
      description: quality.models.create. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/QualityModelCreate"
            example:
              expected_version: 1
              definition:
                name: Example
                method: matrix
                severity_max: 2
                probability_max: 2
                detection_max: 1
                tiers:
                  - label: Example
                    max_score: 1
                    acceptance_required: false
                  - label: Example
                    max_score: 1
                    acceptance_required: false
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityRiskModel"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/cases:
    get:
      operationId: quality_cases_list
      summary: quality cases list
      description: quality.cases.list. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
        - name: kind
          in: query
          schema:
            type: string
            enum:
              - risk
              - deviation
              - capa
              - change
          required: false
        - name: state
          in: query
          schema:
            type: string
            enum:
              - draft
              - triage
              - investigation
              - assessment
              - planning
              - authorization
              - implementation
              - effectiveness
              - verification
              - qa_review
              - closed
          required: false
        - name: search
          in: query
          schema:
            type: string
            minLength: 1
            maxLength: 120
          required: false
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityCasesPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: quality_cases_create
      summary: quality cases create
      description: quality.cases.create. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/QualityCaseCreate"
            example:
              kind: risk
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              owner_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              due_at: 2026-10-18T10:00:00Z
              data:
                title: Example
                description: Example
                master_version_ids: []
                reference_ids: []
                required_dependencies: []
                details:
                  model_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                  hazards: []
                  acceptance_rationale: Example
                  review_on: 2027-10-18
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/cases/{id}:
    get:
      operationId: quality_cases_get
      summary: quality cases get
      description: quality.cases.get. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    patch:
      operationId: quality_cases_update
      summary: quality cases update
      description: quality.cases.update. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                data:
                  $ref: "#/components/schemas/QualityCaseData"
              required:
                - expected_version
                - reason
                - data
            example:
              expected_version: 1
              reason: Example
              data:
                title: Example
                description: Example
                master_version_ids: []
                reference_ids: []
                required_dependencies: []
                details:
                  model_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                  hazards: []
                  acceptance_rationale: Example
                  review_on: 2027-10-18
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/cases/{id}/advance:
    post:
      operationId: quality_cases_advance
      summary: quality cases advance
      description: quality.cases.advance. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/cases/{id}/reopen:
    post:
      operationId: quality_cases_reopen
      summary: quality cases reopen
      description: quality.cases.reopen. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/cases/{id}/evidence:
    post:
      operationId: quality_cases_evidence
      summary: quality cases evidence
      description: quality.cases.evidence. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                filename:
                  type: string
                  minLength: 1
                  maxLength: 180
                mime_type:
                  enum:
                    - text/plain
                    - application/pdf
                size_bytes:
                  type: integer
                  minimum: 1
                  maximum: 10485760
                sha256:
                  type: string
                  pattern: ^[a-f0-9]{64}$
              required:
                - expected_version
                - reason
                - filename
                - mime_type
                - size_bytes
                - sha256
            example:
              expected_version: 1
              reason: Example
              filename: Example
              mime_type: text/plain
              size_bytes: 1
              sha256: "0000000000000000000000000000000000000000000000000000000000000000"
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseIntegrityAttachment"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/cases/{id}/actions:
    post:
      operationId: quality_actions_create
      summary: quality actions create
      description: quality.actions.create. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                kind:
                  type: string
                  enum:
                    - correction
                    - corrective
                    - preventive
                    - mitigation
                    - implementation
                    - validation
                    - regulatory
                    - disposition
                title:
                  type: string
                  minLength: 3
                  maxLength: 500
                assignee_id:
                  type: string
                  format: uuid
                verifier_id:
                  type: string
                  format: uuid
                due_at:
                  type: string
                  format: date-time
              required:
                - expected_version
                - reason
                - kind
                - title
                - assignee_id
                - verifier_id
                - due_at
            example:
              expected_version: 1
              reason: Example
              kind: correction
              title: Example
              assignee_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              verifier_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              due_at: 2026-10-18T10:00:00Z
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/actions/{id}/complete:
    post:
      operationId: quality_actions_complete
      summary: quality actions complete
      description: quality.actions.complete. Verified human, live tenant/MFA/site/department scope and explicit
        module permissions required. Integration keys are forbidden. Updates require expected versions, reason
        and actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                result:
                  type: string
                  minLength: 3
                  maxLength: 3000
                attachment_ids:
                  type: array
                  items:
                    type: string
                    format: uuid
                  maxItems: 20
                  minItems: 1
              required:
                - expected_version
                - reason
                - result
                - attachment_ids
            example:
              expected_version: 1
              reason: Example
              result: Example
              attachment_ids:
                - 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/actions/{id}/verify:
    post:
      operationId: quality_actions_verify
      summary: quality actions verify
      description: quality.actions.verify. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                password:
                  type: string
                  minLength: 8
                  maxLength: 128
                mfa_code:
                  type: string
                  pattern: ^[0-9]{6}$
                consent:
                  const: true
                  type: boolean
              required:
                - expected_version
                - reason
                - password
                - consent
            example:
              expected_version: 1
              reason: Example
              password: Example-password-74!
              consent: true
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/cases/{id}/evaluate:
    post:
      operationId: quality_cases_evaluate
      summary: quality cases evaluate
      description: quality.cases.evaluate. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                password:
                  type: string
                  minLength: 8
                  maxLength: 128
                mfa_code:
                  type: string
                  pattern: ^[0-9]{6}$
                consent:
                  const: true
                  type: boolean
                passed:
                  type: boolean
                result:
                  type: string
                  minLength: 3
                  maxLength: 3000
              required:
                - expected_version
                - reason
                - password
                - consent
                - passed
                - result
            example:
              expected_version: 1
              reason: Example
              password: Example-password-74!
              consent: true
              passed: false
              result: Example
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/cases/{id}/dependencies:
    post:
      operationId: quality_dependencies_create
      summary: quality dependencies create
      description: quality.dependencies.create. Verified human, live tenant/MFA/site/department scope and explicit
        module permissions required. Integration keys are forbidden. Updates require expected versions, reason
        and actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                target_record_id:
                  type: string
                  format: uuid
                required:
                  type: boolean
              required:
                - expected_version
                - reason
                - target_record_id
                - required
            example:
              expected_version: 1
              reason: Example
              target_record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              required: false
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/cases/{id}/retire-dependency:
    post:
      operationId: quality_dependencies_retire
      summary: quality dependencies retire
      description: quality.dependencies.retire. Verified human, live tenant/MFA/site/department scope and explicit
        module permissions required. Integration keys are forbidden. Updates require expected versions, reason
        and actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                target_record_id:
                  type: string
                  format: uuid
              required:
                - expected_version
                - reason
                - target_record_id
            example:
              expected_version: 1
              reason: Example
              target_record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/cases/{id}/approvals:
    post:
      operationId: quality_approvals_request
      summary: quality approvals request
      description: quality.approvals.request. Verified human, live tenant/MFA/site/department scope and explicit
        module permissions required. Integration keys are forbidden. Updates require expected versions, reason
        and actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                stage:
                  type: string
                  enum:
                    - triage
                    - authorization
                    - closure
                    - extension
                workflow_template_id:
                  type: string
                  format: uuid
                due_at:
                  type: string
                  format: date-time
                action_id:
                  type: string
                  format: uuid
              required:
                - expected_version
                - reason
                - stage
                - workflow_template_id
            example:
              expected_version: 1
              reason: Example
              stage: triage
              workflow_template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/approvals/{id}/apply:
    post:
      operationId: quality_approvals_apply
      summary: quality approvals apply
      description: quality.approvals.apply. Verified human, live tenant/MFA/site/department scope and explicit
        module permissions required. Integration keys are forbidden. Updates require expected versions, reason
        and actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/choices:
    get:
      operationId: quality_choices_list
      summary: quality choices list
      description: quality.choices.list. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
        - name: kind
          in: query
          schema:
            type: string
            enum:
              - site
              - department
              - person
              - workflow
              - reference
          required: true
        - name: site_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: department_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: category
          in: query
          schema:
            type: string
            minLength: 1
            maxLength: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseFormLocationsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/search:
    get:
      operationId: quality_search_list
      summary: quality search list
      description: quality.search.list. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
        - name: search
          in: query
          schema:
            type: string
            minLength: 2
            maxLength: 120
          required: true
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualitySearchPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/dashboard:
    get:
      operationId: quality_dashboard_get
      summary: quality dashboard get
      description: quality.dashboard.get. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters: []
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDashboard"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/cases/{id}/inspection:
    post:
      operationId: quality_inspection_create
      summary: quality inspection create
      description: quality.inspection.create. Verified human, live tenant/MFA/site/department scope and explicit
        module permissions required. Integration keys are forbidden. Updates require expected versions, reason
        and actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - reason
            example:
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityInspection"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/quality/cases/{id}/reassess:
    post:
      operationId: quality_cases_reassess
      summary: quality cases reassess
      description: quality.cases.reassess. Verified human, live tenant/MFA/site/department scope and explicit module
        permissions required. Integration keys are forbidden. Updates require expected versions, reason and
        actor-scoped idempotency. Publications are immutable. Quality approval checkpoints freeze an exact
        version and use independently signed workflows. Closure rechecks required dependencies and
        effectiveness evidence. Verification requires fresh password authentication and consent.
      tags:
        - Quality events
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/QualityResponseQualityDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/qc/objects:
    get:
      operationId: qc_objects_list
      summary: qc objects list
      description: qc.objects.list. Verified human identity, live scoped membership and explicit QC permissions
        required. Original definitions and result events are immutable. Retest, resample, disposition and
        equipment release require independently signed workflow checkpoints. Expected version and actor-scoped
        idempotency protect mutations.
      tags:
        - QC and equipment
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
        - name: kind
          in: query
          schema:
            type: string
            enum:
              - laboratory
              - method
              - specification
              - equipment
              - oos
              - oot
          required: false
        - name: search
          in: query
          schema:
            type: string
            minLength: 1
            maxLength: 120
            pattern: \S
          required: false
        - name: due_only
          in: query
          schema:
            type: boolean
          required: false
      responses:
        "200":
          $ref: "#/components/responses/QcResponseQcPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: qc_objects_create
      summary: qc objects create
      description: qc.objects.create. Verified human identity, live scoped membership and explicit QC permissions
        required. Original definitions and result events are immutable. Retest, resample, disposition and
        equipment release require independently signed workflow checkpoints. Expected version and actor-scoped
        idempotency protect mutations.
      tags:
        - QC and equipment
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/QcCreate"
            example:
              kind: laboratory
              code: EXAMPLE-1
              title: Example
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              owner_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              expected_publication: 1
              source_system: Example
              external_id: Example
              source_revision: Example
              definition:
                kind: laboratory
                location: Example
                accreditation: Example
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/QcResponseQcDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/qc/objects/{id}:
    get:
      operationId: qc_objects_get
      summary: qc objects get
      description: qc.objects.get. Verified human identity, live scoped membership and explicit QC permissions
        required. Original definitions and result events are immutable. Retest, resample, disposition and
        equipment release require independently signed workflow checkpoints. Expected version and actor-scoped
        idempotency protect mutations.
      tags:
        - QC and equipment
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          $ref: "#/components/responses/QcResponseQcDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/qc/objects/{id}/events:
    post:
      operationId: qc_events_create
      summary: qc events create
      description: qc.events.create. Verified human identity, live scoped membership and explicit QC permissions
        required. Original definitions and result events are immutable. Retest, resample, disposition and
        equipment release require independently signed workflow checkpoints. Expected version and actor-scoped
        idempotency protect mutations.
      tags:
        - QC and equipment
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                  pattern: \S
                data:
                  $ref: "#/components/schemas/QcEventData"
              required:
                - expected_version
                - reason
                - data
            example:
              expected_version: 1
              reason: Example
              data:
                kind: phase_i
                calculation_review: Example
                sample_preparation_review: Example
                system_suitability_review: Example
                hypothesis: Example
                conclusion: Example
                phase_ii_required: false
      responses:
        "200":
          $ref: "#/components/responses/QcResponseQcDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/qc/objects/{id}/evidence:
    post:
      operationId: qc_evidence_reserve
      summary: qc evidence reserve
      description: qc.evidence.reserve. Verified human identity, live scoped membership and explicit QC permissions
        required. Original definitions and result events are immutable. Retest, resample, disposition and
        equipment release require independently signed workflow checkpoints. Expected version and actor-scoped
        idempotency protect mutations.
      tags:
        - QC and equipment
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                filename:
                  type: string
                  minLength: 1
                  maxLength: 180
                mime_type:
                  enum:
                    - text/plain
                    - application/pdf
                size_bytes:
                  type: integer
                  minimum: 1
                  maximum: 10485760
                sha256:
                  type: string
                  pattern: ^[a-f0-9]{64}$
              required:
                - expected_version
                - reason
                - filename
                - mime_type
                - size_bytes
                - sha256
            example:
              expected_version: 1
              reason: Example
              filename: Example
              mime_type: text/plain
              size_bytes: 1
              sha256: "0000000000000000000000000000000000000000000000000000000000000000"
      responses:
        "200":
          $ref: "#/components/responses/QcResponseIntegrityAttachment"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/qc/objects/{id}/approvals:
    post:
      operationId: qc_approvals_request
      summary: qc approvals request
      description: qc.approvals.request. Verified human identity, live scoped membership and explicit QC permissions
        required. Original definitions and result events are immutable. Retest, resample, disposition and
        equipment release require independently signed workflow checkpoints. Expected version and actor-scoped
        idempotency protect mutations.
      tags:
        - QC and equipment
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                  pattern: \S
                stage:
                  type: string
                  enum:
                    - retest
                    - resample
                    - disposition
                    - release
                workflow_template_id:
                  type: string
                  format: uuid
                plan:
                  $ref: "#/components/schemas/QcApprovalPlan"
              required:
                - expected_version
                - reason
                - stage
                - workflow_template_id
                - plan
            example:
              expected_version: 1
              reason: Example
              stage: retest
              workflow_template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              plan:
                assessment: Example
                sample_count: 1
                sampling_plan: Example
                disposition: pending
      responses:
        "200":
          $ref: "#/components/responses/QcResponseQcDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/qc/approvals/{id}/apply:
    post:
      operationId: qc_approvals_apply
      summary: qc approvals apply
      description: qc.approvals.apply. Verified human identity, live scoped membership and explicit QC permissions
        required. Original definitions and result events are immutable. Retest, resample, disposition and
        equipment release require independently signed workflow checkpoints. Expected version and actor-scoped
        idempotency protect mutations.
      tags:
        - QC and equipment
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/QcResponseQcDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/qc/reconciliation:
    post:
      operationId: qc_reconcile
      summary: qc reconcile
      description: qc.reconcile. Verified human identity, live scoped membership and explicit QC permissions
        required. Original definitions and result events are immutable. Retest, resample, disposition and
        equipment release require independently signed workflow checkpoints. Expected version and actor-scoped
        idempotency protect mutations.
      tags:
        - QC and equipment
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/QcReconcile"
            example:
              source_system: Example
              items:
                - external_id: Example
                  source_revision: Example
                  definition_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/QcResponseQcReconciliation"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/qc/choices:
    get:
      operationId: qc_choices_list
      summary: qc choices list
      description: qc.choices.list. Verified human identity, live scoped membership and explicit QC permissions
        required. Original definitions and result events are immutable. Retest, resample, disposition and
        equipment release require independently signed workflow checkpoints. Expected version and actor-scoped
        idempotency protect mutations.
      tags:
        - QC and equipment
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
        - name: kind
          in: query
          schema:
            type: string
            enum:
              - site
              - department
              - person
              - workflow
              - reference
          required: true
        - name: site_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: department_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: category
          in: query
          schema:
            type: string
            minLength: 1
            maxLength: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/QcResponseFormLocationsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/choices:
    get:
      operationId: oversight_choices_list
      summary: oversight choices list
      description: oversight.choices.list. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
        - name: kind
          in: query
          schema:
            type: string
            enum:
              - site
              - department
              - person
              - workflow
              - reference
          required: true
        - name: site_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: department_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: category
          in: query
          schema:
            type: string
            minLength: 1
            maxLength: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseFormLocationsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/objects:
    get:
      operationId: oversight_objects_list
      summary: oversight objects list
      description: oversight.objects.list. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
        - name: kind
          in: query
          schema:
            type: string
            enum:
              - program
              - checklist
              - questionnaire
              - supplier
              - audit
              - complaint
          required: false
        - name: search
          in: query
          schema:
            type: string
            minLength: 1
            maxLength: 120
            pattern: \S
          required: false
        - name: eligible_only
          in: query
          schema:
            type: boolean
          required: false
        - name: due_only
          in: query
          schema:
            type: boolean
          required: false
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: oversight_objects_create
      summary: oversight objects create
      description: oversight.objects.create. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/OversightCreate"
            example:
              kind: program
              code: EXAMPLE-1
              title: Example
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              owner_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              due_at: 2026-10-19T10:00:00Z
              expected_publication: 1
              source_system: Example
              external_id: Example
              source_revision: Example
              definition:
                kind: program
                year: 2020
                scope: Example
                objectives: Example
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/objects/{id}:
    get:
      operationId: oversight_objects_get
      summary: oversight objects get
      description: oversight.objects.get. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/objects/{id}/events:
    post:
      operationId: oversight_events_create
      summary: oversight events create
      description: oversight.events.create. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                  pattern: \S
                data:
                  $ref: "#/components/schemas/OversightEventData"
              required:
                - expected_version
                - reason
                - data
            example:
              expected_version: 1
              reason: Example
              data:
                kind: answers
                publication_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                answers:
                  - question_id: EXAMPLE-1
                    answer: Example
                    evidence_ids: []
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/objects/{id}/evidence:
    post:
      operationId: oversight_evidence_reserve
      summary: oversight evidence reserve
      description: oversight.evidence.reserve. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                filename:
                  type: string
                  minLength: 1
                  maxLength: 180
                mime_type:
                  enum:
                    - text/plain
                    - application/pdf
                size_bytes:
                  type: integer
                  minimum: 1
                  maximum: 10485760
                sha256:
                  type: string
                  pattern: ^[a-f0-9]{64}$
              required:
                - expected_version
                - reason
                - filename
                - mime_type
                - size_bytes
                - sha256
            example:
              expected_version: 1
              reason: Example
              filename: Example
              mime_type: text/plain
              size_bytes: 1
              sha256: "0000000000000000000000000000000000000000000000000000000000000000"
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseIntegrityAttachment"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/objects/{id}/findings:
    post:
      operationId: oversight_findings_create
      summary: oversight findings create
      description: oversight.findings.create. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                  pattern: \S
                question_id:
                  anyOf:
                    - type: string
                      pattern: ^[A-Z0-9][A-Z0-9._-]{0,49}$
                    - type: "null"
                classification:
                  type: string
                  enum:
                    - minor
                    - major
                    - critical
                    - observation
                observation:
                  type: string
                  minLength: 3
                  maxLength: 3000
                  pattern: \S
                criterion:
                  type: string
                  minLength: 3
                  maxLength: 2000
                  pattern: \S
                assignee_id:
                  type: string
                  format: uuid
                due_at:
                  type: string
                  format: date-time
                repeat_finding_id:
                  anyOf:
                    - type: string
                      format: uuid
                    - type: "null"
                capa_required:
                  type: boolean
              required:
                - expected_version
                - reason
                - question_id
                - classification
                - observation
                - criterion
                - assignee_id
                - due_at
                - repeat_finding_id
                - capa_required
            example:
              expected_version: 1
              reason: Example
              question_id: EXAMPLE-1
              classification: minor
              observation: Example
              criterion: Example
              assignee_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              due_at: 2026-10-19T10:00:00Z
              repeat_finding_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              capa_required: false
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/findings/{id}/respond:
    post:
      operationId: oversight_findings_respond
      summary: oversight findings respond
      description: oversight.findings.respond. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                  pattern: \S
                response:
                  type: string
                  minLength: 3
                  maxLength: 3000
                  pattern: \S
                attachment_ids:
                  type: array
                  items:
                    type: string
                    format: uuid
                  maxItems: 20
                  minItems: 1
                capa_record_id:
                  anyOf:
                    - type: string
                      format: uuid
                    - type: "null"
              required:
                - expected_version
                - reason
                - response
                - attachment_ids
                - capa_record_id
            example:
              expected_version: 1
              reason: Example
              response: Example
              attachment_ids:
                - 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              capa_record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/findings/{id}/capa:
    post:
      operationId: oversight_findings_capa
      summary: oversight findings capa
      description: oversight.findings.capa. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                  pattern: \S
                details:
                  $ref: "#/components/schemas/QualityCapaData"
              required:
                - expected_version
                - reason
                - details
            example:
              expected_version: 1
              reason: Example
              details:
                source: deviation
                problem: Example
                root_cause: Example
                priority: low
                effectiveness_plan: Example
                effectiveness_criteria: Example
                effectiveness_due_at: 2026-10-19T10:00:00Z
                verifier_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/findings/{id}/verify:
    post:
      operationId: oversight_findings_verify
      summary: oversight findings verify
      description: oversight.findings.verify. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                password:
                  type: string
                  minLength: 8
                  maxLength: 128
                mfa_code:
                  type: string
                  pattern: ^[0-9]{6}$
                consent:
                  const: true
                  type: boolean
              required:
                - expected_version
                - reason
                - password
                - consent
            example:
              expected_version: 1
              reason: Example
              password: Example-password-74!
              consent: true
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/objects/{id}/approvals:
    post:
      operationId: oversight_approvals_request
      summary: oversight approvals request
      description: oversight.approvals.request. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                  pattern: \S
                stage:
                  type: string
                  enum:
                    - closure
                    - qualification
                workflow_template_id:
                  type: string
                  format: uuid
                assessment:
                  type: string
                  minLength: 3
                  maxLength: 3000
                  pattern: \S
                supplier_status:
                  type: string
                  enum:
                    - approved
                    - conditionally_approved
                conditions:
                  type: string
                  minLength: 0
                  maxLength: 2000
                valid_until:
                  anyOf:
                    - type: string
                      format: date-time
                    - type: "null"
              required:
                - expected_version
                - reason
                - stage
                - workflow_template_id
                - assessment
                - supplier_status
                - conditions
                - valid_until
            example:
              expected_version: 1
              reason: Example
              stage: closure
              workflow_template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              assessment: Example
              supplier_status: approved
              conditions: Example
              valid_until: 2026-10-19T10:00:00Z
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/approvals/{id}/apply:
    post:
      operationId: oversight_approvals_apply
      summary: oversight approvals apply
      description: oversight.approvals.apply. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - expected_version
                - reason
            example:
              expected_version: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/objects/{id}/reporter:
    get:
      operationId: oversight_reporter_get
      summary: oversight reporter get
      description: oversight.reporter.get. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightReporterHistory"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    patch:
      operationId: oversight_reporter_update
      summary: oversight reporter update
      description: oversight.reporter.update. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                expected_version:
                  type: integer
                  minimum: 1
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                  pattern: \S
                reporter:
                  $ref: "#/components/schemas/OversightReporter"
              required:
                - expected_version
                - reason
                - reporter
            example:
              expected_version: 1
              reason: Example
              reporter:
                name: Example
                contact: Example
                organization: Example
                details: Example
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightReporterHistory"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/objects/{id}/report:
    post:
      operationId: oversight_report_create
      summary: oversight report create
      description: oversight.report.create. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                include_reporter:
                  type: boolean
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                  pattern: \S
              required:
                - include_reporter
                - reason
            example:
              include_reporter: false
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightReport"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/handoffs/{id}/retry:
    post:
      operationId: oversight_handoffs_retry
      summary: oversight handoffs retry
      description: oversight.handoffs.retry. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
              required:
                - reason
            example:
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightDetail"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/dashboard:
    get:
      operationId: oversight_dashboard_get
      summary: oversight dashboard get
      description: oversight.dashboard.get. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters: []
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseOversightDashboard"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/oversight/reconciliation:
    post:
      operationId: oversight_reconcile
      summary: oversight reconcile
      description: oversight.reconcile. Verified human session and live tenant/site/department/module scope
        required. Mutations bind expected versions, reason and actor-scoped idempotency. Reporter identity
        requires a separate permission and is excluded from ordinary reports and shared history. Closure and
        qualification use independent signed checkpoints; safety handoff requires explicit external
        acknowledgement.
      tags:
        - Quality oversight
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/QcReconcile"
            example:
              source_system: Example
              items:
                - external_id: Example
                  source_revision: Example
                  definition_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/OversightResponseQcReconciliation"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/analytics/definitions:
    get:
      operationId: analytics_definitions_list
      summary: analytics definitions list
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: kind
          in: query
          schema:
            type: string
            enum:
              - kpi
              - report
              - layout
          required: false
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseAnalyticsDefinitionsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: analytics_definitions_create
      summary: analytics definitions create
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AnalyticsDefinitionInput"
            example:
              name: Example
              expected_publication: 1
              definition:
                kind: kpi
                code: EXAMPLE
                label: Example
                effective_from: 2026-10-19T10:00:00Z
                effective_until: 2026-10-19T10:00:00Z
                closed_states:
                  - Example
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseAnalyticsDefinition"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/analytics/records:
    get:
      operationId: analytics_records_list
      summary: analytics records list
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: from
          in: query
          schema:
            type: string
            format: date-time
          required: true
        - name: to
          in: query
          schema:
            type: string
            format: date-time
          required: true
        - name: module
          in: query
          schema:
            type: string
            enum:
              - risk
              - deviation
              - capa
              - change
              - oos
              - oot
              - equipment
              - audit
              - supplier
              - complaint
              - training
              - document
              - form
              - integrity
          required: false
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
        - name: site_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: department_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseAnalyticsRowsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/analytics/snapshots:
    get:
      operationId: analytics_snapshots_list
      summary: analytics snapshots list
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseAnalyticsSnapshotsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: analytics_snapshots_create
      summary: analytics snapshots create
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AnalyticsSnapshotInput"
            example:
              definition_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              title: Example
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseAnalyticsSnapshot"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/analytics/snapshots/{id}:
    get:
      operationId: analytics_snapshots_get
      summary: analytics snapshots get
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseAnalyticsSnapshot"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/analytics/inspections:
    post:
      operationId: analytics_inspections_create
      summary: analytics inspections create
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AnalyticsInspectionInput"
            example:
              root_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              title: Example
              depth: 1
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseAnalyticsSnapshot"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/analytics/reviews:
    post:
      operationId: analytics_reviews_create
      summary: analytics reviews create
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AnalyticsReviewInput"
            example:
              kind: access
              from: 2026-10-19T10:00:00Z
              to: 2026-10-19T10:00:00Z
              title: Example
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseAnalyticsSnapshot"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/analytics/snapshots/{id}/sign:
    post:
      operationId: analytics_snapshots_sign
      summary: analytics snapshots sign
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                sha256:
                  type: string
                  pattern: ^[a-f0-9]{64}$
                consent:
                  type: boolean
                  const: true
                password:
                  type: string
                  minLength: 1
                  maxLength: 128
                  pattern: \S
                mfa_code:
                  type: string
                  pattern: ^[0-9]{6}$
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                  pattern: \S
              required:
                - sha256
                - consent
                - password
                - reason
            example:
              sha256: "0000000000000000000000000000000000000000000000000000000000000000"
              consent: true
              password: Example
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseAnalyticsSnapshot"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/analytics/snapshots/{id}/retention:
    patch:
      operationId: analytics_snapshots_retention
      summary: analytics snapshots retention
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                retain_until:
                  type: string
                  format: date-time
                legal_hold:
                  type: boolean
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                  pattern: \S
              required:
                - retain_until
                - legal_hold
                - reason
            example:
              retain_until: 2026-10-19T10:00:00Z
              legal_hold: false
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseAnalyticsSnapshot"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/analytics/snapshots/{id}/exports:
    post:
      operationId: analytics_exports_create
      summary: analytics exports create
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties:
                format:
                  type: string
                  enum:
                    - json
                    - pdf
                    - csv
                    - xlsx
                    - bundle
                layout_id:
                  anyOf:
                    - type: string
                      format: uuid
                    - type: "null"
                reason:
                  type: string
                  minLength: 3
                  maxLength: 1000
                  pattern: \S
              required:
                - format
                - layout_id
                - reason
            example:
              format: json
              layout_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseAnalyticsExport"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/analytics/exports:
    get:
      operationId: analytics_exports_list
      summary: analytics exports list
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseAnalyticsExportsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/analytics/exports/{id}/download:
    post:
      operationId: analytics_exports_download
      summary: analytics exports download
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              additionalProperties: false
              properties: {}
              required: []
            example: {}
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseFormDownload"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/analytics/releases:
    get:
      operationId: analytics_releases_list
      summary: analytics releases list
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseAnalyticsReleasesPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
    post:
      operationId: analytics_releases_create
      summary: analytics releases create
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: Idempotency-Key
          in: header
          required: true
          schema:
            type: string
            minLength: 16
            maxLength: 128
            pattern: \S
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AnalyticsReleaseInput"
            example:
              release: Example
              commit: "0000000000000000000000000000000000000000"
              record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              attachment_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              artifact_sha256: "0000000000000000000000000000000000000000000000000000000000000000"
              reason: Example
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseAnalyticsRelease"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
  /api/v1/analytics/choices:
    get:
      operationId: analytics_choices_list
      summary: analytics choices list
      description: Verified human, live tenant/site/department/module authorization. Explicit analytics permissions
        required. Snapshots bind exact request-time projections and effective KPI metadata; later source
        changes do not rewrite them. Export jobs recheck the requesting session, current permissions and
        source scope at claim, finish and download. Reviewer signatures require fresh password
        reauthentication and consent. Reports are owner-private, bounded and attributable. Reasons and
        actor-scoped idempotency apply to mutations. Scheduled delivery is not enabled.
      tags:
        - Analytics and inspection
      security:
        - humanBearer: []
        - sessionCookie: []
      parameters:
        - name: kind
          in: query
          schema:
            type: string
            enum:
              - site
              - department
          required: true
        - name: site_id
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: cursor
          in: query
          schema:
            type: string
            format: uuid
          required: false
        - name: limit
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
          required: false
      responses:
        "200":
          $ref: "#/components/responses/AnalyticsResponseFormLocationsPage"
        "401":
          $ref: "#/components/responses/FoundationError401"
        "403":
          $ref: "#/components/responses/FoundationError403"
        "404":
          $ref: "#/components/responses/FoundationError404"
        "409":
          $ref: "#/components/responses/FoundationError409"
        "412":
          $ref: "#/components/responses/FoundationError412"
        "422":
          $ref: "#/components/responses/FoundationError422"
        "429":
          $ref: "#/components/responses/FoundationError429"
        "500":
          $ref: "#/components/responses/FoundationError500"
        "503":
          $ref: "#/components/responses/FoundationError503"
components:
  headers:
    RequestId:
      description: Server-generated correlation ID; caller input is never echoed.
      required: true
      schema:
        type: string
        format: uuid
    NoStore:
      description: Operational responses are never cached.
      required: true
      schema:
        type: string
        const: no-store
  schemas:
    Health:
      type: object
      additionalProperties: false
      required:
        - status
        - service
        - timestamp
        - request_id
      properties:
        status:
          type: string
          const: ok
        service:
          type: string
          const: eqms-api
        timestamp:
          type: string
          format: date-time
          pattern: Z$
        request_id:
          type: string
          format: uuid
    Readiness:
      type: object
      additionalProperties: false
      required:
        - status
        - checks
        - timestamp
        - request_id
      properties:
        status:
          type: string
          const: ready
        checks:
          type: object
          additionalProperties: false
          required:
            - supabase_auth
          properties:
            supabase_auth:
              type: string
              const: reachable
        timestamp:
          type: string
          format: date-time
          pattern: Z$
        request_id:
          type: string
          format: uuid
    Problem:
      type: object
      additionalProperties: false
      required:
        - type
        - title
        - status
        - detail
        - code
        - request_id
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
          minLength: 1
        status:
          type: integer
          minimum: 400
          maximum: 599
        detail:
          type: string
          minLength: 1
        code:
          type: string
          enum:
            - VALIDATION_ERROR
            - DEPENDENCY_UNAVAILABLE
            - INTERNAL_ERROR
        request_id:
          type: string
          format: uuid
        errors:
          type: array
          items:
            type: object
            additionalProperties: false
            required:
              - field
              - message
            properties:
              field:
                type: string
              message:
                type: string
    ListQuery:
      type: object
      additionalProperties: false
      properties:
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
      required: []
    EmptyInput:
      type: object
      additionalProperties: false
      properties: {}
      required: []
    IdentifierInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
      required:
        - id
    OnboardingInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 120
        slug:
          type: string
          pattern: ^[a-z0-9][a-z0-9-]{2,47}$
        timezone:
          type: string
          minLength: 1
          maxLength: 80
        display_name:
          type: string
          minLength: 1
          maxLength: 120
      required:
        - name
        - slug
        - timezone
        - display_name
    ProfileInput:
      type: object
      additionalProperties: false
      properties:
        display_name:
          type: string
          minLength: 1
          maxLength: 120
        timezone:
          type: string
          minLength: 1
          maxLength: 80
        locale:
          enum:
            - en-GB
            - en-US
        expected_version:
          type: integer
          minimum: 1
      required:
        - display_name
        - timezone
        - locale
        - expected_version
    OrganizationInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 120
        timezone:
          type: string
          minLength: 1
          maxLength: 80
        locale:
          enum:
            - en-GB
            - en-US
        accent:
          enum:
            - blue
            - teal
            - indigo
            - violet
            - rose
            - emerald
            - amber
            - slate
            - cyan
            - orange
        mfa_required:
          type: boolean
        expected_version:
          type: integer
          minimum: 1
      required:
        - name
        - timezone
        - locale
        - accent
        - mfa_required
        - expected_version
    SiteInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 120
        code:
          type: string
          pattern: ^[A-Z0-9_-]{2,20}$
      required:
        - name
        - code
    DepartmentInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 120
        code:
          type: string
          pattern: ^[A-Z0-9_-]{2,20}$
        site_id:
          type: string
          format: uuid
      required:
        - name
        - code
        - site_id
    RoleInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 80
        permissions:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 80
          maxItems: 100
          uniqueItems: true
      required:
        - name
        - permissions
    RoleUpdateInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 2
          maxLength: 80
        permissions:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 80
          maxItems: 100
          uniqueItems: true
        expected_version:
          type: integer
          minimum: 1
      required:
        - id
        - name
        - permissions
        - expected_version
    UserInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        status:
          enum:
            - active
            - suspended
            - deactivated
        all_sites:
          type: boolean
        all_departments:
          type: boolean
        role_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 100
          uniqueItems: true
        site_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 100
          uniqueItems: true
        department_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 100
          uniqueItems: true
        expected_version:
          type: integer
          minimum: 1
      required:
        - id
        - status
        - all_sites
        - all_departments
        - role_ids
        - site_ids
        - department_ids
        - expected_version
    InvitationInput:
      type: object
      additionalProperties: false
      properties:
        email:
          type: string
          format: email
          maxLength: 254
        role_id:
          type: string
          format: uuid
      required:
        - email
        - role_id
    AcceptInvitationInput:
      type: object
      additionalProperties: false
      properties:
        token:
          type: string
          pattern: ^[a-f0-9]{64}$
        display_name:
          type: string
          minLength: 1
          maxLength: 120
      required:
        - token
        - display_name
    ClientInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 80
        scopes:
          type: array
          items:
            enum:
              - organization:read
              - sites:read
              - departments:read
          maxItems: 100
          uniqueItems: true
          minItems: 1
        expires_at:
          type: string
          format: date-time
      required:
        - name
        - scopes
        - expires_at
    CredentialsInput:
      type: object
      additionalProperties: false
      properties:
        email:
          type: string
          format: email
          maxLength: 254
        password:
          type: string
          minLength: 12
          maxLength: 128
      required:
        - email
        - password
    EmailInput:
      type: object
      additionalProperties: false
      properties:
        email:
          type: string
          format: email
          maxLength: 254
      required:
        - email
    PasswordInput:
      type: object
      additionalProperties: false
      properties:
        password:
          type: string
          minLength: 12
          maxLength: 128
      required:
        - password
    ConfirmInput:
      type: object
      additionalProperties: false
      properties:
        code:
          type: string
          minLength: 1
          maxLength: 2048
      required:
        - code
    MfaFactorInput:
      type: object
      additionalProperties: false
      properties:
        factor_id:
          type: string
          format: uuid
      required:
        - factor_id
    MfaVerifyInput:
      type: object
      additionalProperties: false
      properties:
        factor_id:
          type: string
          format: uuid
        code:
          type: string
          pattern: ^[0-9]{6}$
      required:
        - factor_id
        - code
    Organization:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 2
          maxLength: 120
        slug:
          type: string
          minLength: 1
          maxLength: 48
        timezone:
          type: string
          minLength: 1
          maxLength: 80
        locale:
          enum:
            - en-GB
            - en-US
        accent:
          enum:
            - blue
            - teal
            - indigo
            - violet
            - rose
            - emerald
            - amber
            - slate
            - cyan
            - orange
        mfa_required:
          type: boolean
        version:
          type: integer
          minimum: 1
        created_at:
          type: string
          format: date-time
      required:
        - id
        - name
        - slug
        - timezone
        - locale
        - accent
        - mfa_required
        - version
        - created_at
    Profile:
      type: object
      additionalProperties: false
      properties:
        user_id:
          type: string
          format: uuid
        display_name:
          type: string
          minLength: 1
          maxLength: 120
        timezone:
          type: string
          minLength: 1
          maxLength: 80
        locale:
          enum:
            - en-GB
            - en-US
        version:
          type: integer
          minimum: 1
      required:
        - user_id
        - display_name
        - timezone
        - locale
        - version
    TenantContext:
      type: object
      additionalProperties: false
      properties:
        user:
          type: object
          additionalProperties: false
          properties:
            id:
              type: string
              format: uuid
            email:
              type: string
              format: email
            display_name:
              type: string
          required:
            - id
            - email
            - display_name
        tenant:
          anyOf:
            - $ref: "#/components/schemas/Organization"
            - type: "null"
        permissions:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 80
          maxItems: 100
          uniqueItems: true
        mfa_satisfied:
          type: boolean
        profile:
          anyOf:
            - $ref: "#/components/schemas/Profile"
            - type: object
              additionalProperties: false
              properties: {}
              required: []
      required:
        - user
        - tenant
        - permissions
        - mfa_satisfied
        - profile
    Site:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 120
        code:
          type: string
          minLength: 1
          maxLength: 20
        active:
          type: boolean
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - name
        - code
        - active
        - created_at
    Department:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        site_id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 120
        code:
          type: string
          minLength: 1
          maxLength: 20
        active:
          type: boolean
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - site_id
        - name
        - code
        - active
        - created_at
    Role:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 80
        version:
          type: integer
          minimum: 1
        permissions:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 80
          maxItems: 100
          uniqueItems: true
      required:
        - id
        - tenant_id
        - name
        - version
        - permissions
    Permission:
      type: object
      additionalProperties: false
      properties:
        code:
          type: string
          minLength: 1
          maxLength: 80
        description:
          type: string
          minLength: 1
          maxLength: 200
      required:
        - code
        - description
    Membership:
      type: object
      additionalProperties: false
      properties:
        tenant_id:
          type: string
          format: uuid
        user_id:
          type: string
          format: uuid
        status:
          enum:
            - active
            - suspended
            - deactivated
        all_sites:
          type: boolean
        all_departments:
          type: boolean
        version:
          type: integer
          minimum: 1
      required:
        - tenant_id
        - user_id
        - status
        - all_sites
        - all_departments
        - version
    Invitation:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        email:
          type: string
          format: email
        role_id:
          type: string
          format: uuid
        status:
          enum:
            - pending
            - accepted
            - revoked
        expires_at:
          type: string
          format: date-time
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - email
        - role_id
        - status
        - expires_at
        - created_by
        - created_at
    Client:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 80
        scopes:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 80
          maxItems: 100
          uniqueItems: true
        expires_at:
          type: string
          format: date-time
        revoked_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        created_at:
          type: string
          format: date-time
        rotated_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        last_used_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
      required:
        - id
        - tenant_id
        - name
        - scopes
        - expires_at
        - revoked_at
        - created_at
        - rotated_at
        - last_used_at
    SecurityEvent:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        actor_id:
          type: string
          format: uuid
        actor_name:
          type: string
          minLength: 1
          maxLength: 120
        action:
          type: string
          minLength: 1
          maxLength: 80
        resource_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        summary:
          type: string
          minLength: 1
          maxLength: 500
        request_id:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        before_state:
          type:
            - object
            - "null"
        after_state:
          type: object
      required:
        - id
        - tenant_id
        - actor_id
        - actor_name
        - action
        - resource_id
        - summary
        - request_id
        - created_at
        - before_state
        - after_state
    Accepted:
      type: object
      additionalProperties: false
      properties:
        accepted:
          const: true
          type: boolean
      required:
        - accepted
    AuthResult:
      type: object
      additionalProperties: false
      properties:
        message:
          type: string
          minLength: 1
          maxLength: 500
        signed_in:
          type: boolean
      required:
        - message
        - signed_in
    MfaStatus:
      type: object
      additionalProperties: false
      properties:
        factors:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
                format: uuid
              friendly_name:
                type:
                  - string
                  - "null"
              status:
                enum:
                  - verified
                  - unverified
            required:
              - id
              - friendly_name
              - status
          maxItems: 100
          uniqueItems: true
      required:
        - factors
    MfaEnrollment:
      type: object
      additionalProperties: false
      properties:
        factor_id:
          type: string
          format: uuid
        qr_code:
          type: string
          minLength: 1
          maxLength: 2097152
        secret:
          type: string
          minLength: 1
          maxLength: 256
      required:
        - factor_id
        - qr_code
        - secret
    ApiProblem:
      type: object
      additionalProperties: false
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
          minLength: 1
          maxLength: 100
        status:
          type: integer
          minimum: 400
          maximum: 599
        detail:
          type: string
          minLength: 1
          maxLength: 500
        code:
          enum:
            - UNAUTHENTICATED
            - FORBIDDEN
            - MFA_REQUIRED
            - NOT_FOUND
            - CONFLICT
            - LAST_ADMIN
            - STALE_VERSION
            - VALIDATION_ERROR
            - IDEMPOTENCY_REQUIRED
            - RATE_LIMITED
            - DEPENDENCY_UNAVAILABLE
            - INTERNAL_ERROR
            - METHOD_NOT_ALLOWED
        request_id:
          type: string
          format: uuid
        errors:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              field:
                type: string
                minLength: 1
                maxLength: 200
              message:
                type: string
                minLength: 1
                maxLength: 200
            required:
              - field
              - message
          maxItems: 100
          uniqueItems: true
      required:
        - type
        - title
        - status
        - detail
        - code
        - request_id
    DirectoryUser:
      type: object
      additionalProperties: false
      properties:
        tenant_id:
          type: string
          format: uuid
        user_id:
          type: string
          format: uuid
        status:
          enum:
            - active
            - suspended
            - deactivated
        all_sites:
          type: boolean
        all_departments:
          type: boolean
        version:
          type: integer
          minimum: 1
        id:
          type: string
          format: uuid
        display_name:
          type: string
          minLength: 1
          maxLength: 120
        timezone:
          type: string
          minLength: 1
          maxLength: 80
        locale:
          enum:
            - en-GB
            - en-US
        role_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 100
          uniqueItems: true
        site_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 100
          uniqueItems: true
        department_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 100
          uniqueItems: true
      required:
        - tenant_id
        - user_id
        - status
        - all_sites
        - all_departments
        - version
        - id
        - display_name
        - timezone
        - locale
        - role_ids
        - site_ids
        - department_ids
    InvitationIssued:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        email:
          type: string
          format: email
        role_id:
          type: string
          format: uuid
        status:
          enum:
            - pending
            - accepted
            - revoked
        expires_at:
          type: string
          format: date-time
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        token:
          type: string
          pattern: ^[a-f0-9]{64}$
          description: One-time reveal. Absent on idempotent replay; not retained in receipts.
      required:
        - id
        - tenant_id
        - email
        - role_id
        - status
        - expires_at
        - created_by
        - created_at
    ClientIssued:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 1
          maxLength: 80
        scopes:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 80
          maxItems: 100
          uniqueItems: true
        expires_at:
          type: string
          format: date-time
        revoked_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        created_at:
          type: string
          format: date-time
        rotated_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        last_used_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        key:
          type: string
          pattern: ^eqms_[a-f0-9]{64}$
          description: One-time reveal; absent on replay. Store securely; only hash retained.
      required:
        - id
        - tenant_id
        - name
        - scopes
        - expires_at
        - revoked_at
        - created_at
        - rotated_at
        - last_used_at
    SitesPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/Site"
        next_cursor:
          type:
            - string
            - "null"
      required:
        - items
        - next_cursor
    DepartmentsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/Department"
        next_cursor:
          type:
            - string
            - "null"
      required:
        - items
        - next_cursor
    RolesPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/Role"
        next_cursor:
          type:
            - string
            - "null"
      required:
        - items
        - next_cursor
    PermissionsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/Permission"
        next_cursor:
          type:
            - string
            - "null"
      required:
        - items
        - next_cursor
    UsersPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/DirectoryUser"
        next_cursor:
          type:
            - string
            - "null"
      required:
        - items
        - next_cursor
    InvitationsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/Invitation"
        next_cursor:
          type:
            - string
            - "null"
      required:
        - items
        - next_cursor
    ClientsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/Client"
        next_cursor:
          type:
            - string
            - "null"
      required:
        - items
        - next_cursor
    EventsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/SecurityEvent"
        next_cursor:
          type:
            - string
            - "null"
      required:
        - items
        - next_cursor
    IntegrityCreate:
      type: object
      additionalProperties: false
      properties:
        title:
          type: string
          minLength: 2
          maxLength: 200
        content:
          type: string
          minLength: 0
          maxLength: 10000
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - title
        - content
        - site_id
        - department_id
        - reason
    IntegrityUpdate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        title:
          type: string
          minLength: 2
          maxLength: 200
        content:
          type: string
          minLength: 0
          maxLength: 10000
      required:
        - id
        - expected_version
        - reason
        - title
        - content
    IntegritySign:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        content_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        meaning:
          enum:
            - authorship
            - review
            - acknowledgement
        consent:
          type: boolean
          const: true
        password:
          type: string
          minLength: 12
          maxLength: 128
        mfa_code:
          type: string
          pattern: ^[0-9]{6}$
      required:
        - id
        - expected_version
        - reason
        - content_hash
        - meaning
        - consent
        - password
    IntegrityCancel:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - expected_version
        - reason
    IntegrityArchive:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - expected_version
        - reason
    IntegrityRetention:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        legal_hold:
          type: boolean
        retain_until:
          type: string
          format: date-time
      required:
        - id
        - expected_version
        - reason
        - legal_hold
        - retain_until
    IntegrityCommentInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        body:
          type: string
          minLength: 1
          maxLength: 2000
      required:
        - id
        - expected_version
        - reason
        - body
    IntegrityLinkInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        target_id:
          type: string
          format: uuid
        relation:
          enum:
            - related
            - supports
            - supersedes
      required:
        - id
        - expected_version
        - reason
        - target_id
        - relation
    IntegrityAttachmentInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        filename:
          type: string
          minLength: 1
          maxLength: 180
          pattern: ^[^/\\]+$
        mime_type:
          enum:
            - text/plain
            - application/pdf
        size_bytes:
          type: integer
          minimum: 1
          maximum: 10485760
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
      required:
        - id
        - expected_version
        - reason
        - filename
        - mime_type
        - size_bytes
        - sha256
    IntegritySettingsInput:
      type: object
      additionalProperties: false
      properties:
        prefix:
          type: string
          pattern: ^[A-Z]{2,10}$
        retention_years:
          type: integer
          minimum: 1
          maximum: 30
        vocabulary:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 80
          maxItems: 50
          minItems: 1
          uniqueItems: true
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - prefix
        - retention_years
        - vocabulary
        - expected_version
        - reason
    IntegrityAuditQuery:
      type: object
      additionalProperties: false
      properties:
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
        record_id:
          type: string
          format: uuid
        action:
          type: string
          minLength: 1
          maxLength: 100
        since:
          type: string
          format: date-time
        until:
          type: string
          format: date-time
      required: []
    IntegrityRecord:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        number:
          type: string
          minLength: 1
          maxLength: 40
        title:
          type: string
          minLength: 2
          maxLength: 200
        content:
          type: string
          minLength: 0
          maxLength: 10000
        version:
          type: integer
          minimum: 1
        status:
          enum:
            - draft
            - signed
            - cancelled
            - archived
        content_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        retain_until:
          type: string
          format: date-time
        legal_hold:
          type: boolean
      required:
        - id
        - tenant_id
        - site_id
        - department_id
        - number
        - title
        - content
        - version
        - status
        - content_hash
        - created_by
        - created_at
        - updated_at
        - retain_until
        - legal_hold
    IntegritySignature:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        record_id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        content_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        signer_id:
          type: string
          format: uuid
        signer_name:
          type: string
          minLength: 1
          maxLength: 120
        meaning:
          enum:
            - authorship
            - review
            - acknowledgement
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        signed_at:
          type: string
          format: date-time
        authentication_method:
          const: password
          type: string
        request_id:
          type: string
          format: uuid
      required:
        - id
        - tenant_id
        - record_id
        - version
        - content_hash
        - signer_id
        - signer_name
        - meaning
        - reason
        - signed_at
        - authentication_method
        - request_id
    IntegrityComment:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        record_id:
          type: string
          format: uuid
        body:
          type: string
          minLength: 1
          maxLength: 2000
        actor_id:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - record_id
        - body
        - actor_id
        - created_at
    IntegrityLink:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        record_id:
          type: string
          format: uuid
        target_id:
          type: string
          format: uuid
        relation:
          enum:
            - related
            - supports
            - supersedes
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - record_id
        - target_id
        - relation
        - created_at
    IntegrityAttachment:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        record_id:
          type: string
          format: uuid
        record_version:
          type: integer
          minimum: 1
        filename:
          type: string
          minLength: 1
          maxLength: 180
        mime_type:
          enum:
            - text/plain
            - application/pdf
        size_bytes:
          type: integer
          minimum: 1
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        object_path:
          type: string
          minLength: 1
          maxLength: 200
        state:
          enum:
            - quarantined
            - clean
            - rejected
        scanner:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 200
            - type: "null"
        scanned_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - record_id
        - record_version
        - filename
        - mime_type
        - size_bytes
        - sha256
        - object_path
        - state
        - scanner
        - scanned_at
        - created_by
        - created_at
    IntegrityVersion:
      type: object
      additionalProperties: false
      properties:
        tenant_id:
          type: string
          format: uuid
        record_id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        snapshot:
          type: object
        content_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        created_at:
          type: string
          format: date-time
        id:
          type: string
          format: uuid
      required:
        - tenant_id
        - record_id
        - version
        - snapshot
        - content_hash
        - created_at
        - id
    IntegrityDetail:
      type: object
      additionalProperties: false
      properties:
        record:
          $ref: "#/components/schemas/IntegrityRecord"
        versions:
          type: array
          items:
            $ref: "#/components/schemas/IntegrityVersion"
          maxItems: 100
        signatures:
          type: array
          items:
            $ref: "#/components/schemas/IntegritySignature"
          maxItems: 100
        comments:
          type: array
          items:
            $ref: "#/components/schemas/IntegrityComment"
          maxItems: 100
        links:
          type: array
          items:
            $ref: "#/components/schemas/IntegrityLink"
          maxItems: 100
        attachments:
          type: array
          items:
            $ref: "#/components/schemas/IntegrityAttachment"
          maxItems: 100
      required:
        - record
        - versions
        - signatures
        - comments
        - links
        - attachments
    IntegritySettings:
      type: object
      additionalProperties: false
      properties:
        tenant_id:
          type: string
          format: uuid
        prefix:
          type: string
          minLength: 2
          maxLength: 10
        retention_years:
          type: integer
          minimum: 1
          maximum: 30
        vocabulary:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 80
          maxItems: 50
          minItems: 1
        version:
          type: integer
          minimum: 1
      required:
        - tenant_id
        - prefix
        - retention_years
        - vocabulary
        - version
    IntegrityAudit:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        record_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        actor_id:
          type: string
          format: uuid
        actor_name:
          type: string
          minLength: 1
          maxLength: 120
        actor_type:
          const: human
          type: string
        action:
          type: string
          minLength: 1
          maxLength: 100
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        summary:
          type: string
          minLength: 1
          maxLength: 300
        changed_fields:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 100
          maxItems: 100
        before_state:
          anyOf:
            - type: object
            - type: "null"
        after_state:
          type: object
        request_id:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - record_id
        - actor_id
        - actor_name
        - actor_type
        - action
        - reason
        - summary
        - changed_fields
        - before_state
        - after_state
        - request_id
        - created_at
    IntegrityNotification:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        record_id:
          type: string
          format: uuid
        event_id:
          type: string
          format: uuid
        recipient_id:
          type: string
          format: uuid
        message:
          type: string
          minLength: 1
          maxLength: 300
        read_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - record_id
        - event_id
        - recipient_id
        - message
        - read_at
        - created_at
    IntegrityDownload:
      type: object
      additionalProperties: false
      properties:
        url:
          type: string
          format: uri
        expires_at:
          type: string
          format: date-time
      required:
        - url
        - expires_at
    IntegrityRecordsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/IntegrityRecord"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    IntegrityAuditPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/IntegrityAudit"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    IntegrityNotificationsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/IntegrityNotification"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    IntegrityUpload:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        content_base64:
          type: string
          minLength: 4
          maxLength: 13981016
          pattern: ^[A-Za-z0-9+/]+={0,2}$
      required:
        - id
        - content_base64
    IntegrityHistoryQuery:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        kind:
          enum:
            - versions
            - signatures
            - comments
            - links
            - attachments
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
      required:
        - id
        - kind
    IntegrityHistoryPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            anyOf:
              - $ref: "#/components/schemas/IntegrityVersion"
              - $ref: "#/components/schemas/IntegritySignature"
              - $ref: "#/components/schemas/IntegrityComment"
              - $ref: "#/components/schemas/IntegrityLink"
              - $ref: "#/components/schemas/IntegrityAttachment"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    WorkflowStage:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          minLength: 1
          maxLength: 120
        name:
          type: string
          minLength: 1
          maxLength: 120
        mode:
          enum:
            - sequential
            - one_of
            - unanimous
            - quorum
        selector:
          anyOf:
            - type: object
              additionalProperties: false
              properties:
                kind:
                  const: named
                  type: string
                userIds:
                  type: array
                  items:
                    type: string
                    format: uuid
                  maxItems: 100
                  minItems: 1
                  uniqueItems: true
              required:
                - kind
                - userIds
            - type: object
              additionalProperties: false
              properties:
                kind:
                  const: role
                  type: string
                roleId:
                  type: string
                  format: uuid
              required:
                - kind
                - roleId
        threshold:
          type: integer
          minimum: 1
          maximum: 100
        signedActions:
          type: array
          items:
            enum:
              - approve
              - reject
              - request_changes
          maxItems: 100
          uniqueItems: true
        allowDelegation:
          type: boolean
        slaHours:
          type: number
          minimum: 1
          maximum: 2400
        escalationHours:
          type: number
          minimum: 1
          maximum: 2400
      required:
        - id
        - name
        - mode
        - selector
        - signedActions
        - allowDelegation
        - slaHours
    WorkflowCalendarInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 120
        timezone:
          type: string
          minLength: 1
          maxLength: 80
        weekdays:
          type: array
          items:
            type: integer
            minimum: 1
            maximum: 7
          maxItems: 7
          minItems: 1
          uniqueItems: true
        start_minute:
          type: integer
          minimum: 0
          maximum: 1439
        end_minute:
          type: integer
          minimum: 1
          maximum: 1440
        holidays:
          type: array
          items:
            type: string
            format: date
          maxItems: 366
          uniqueItems: true
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - name
        - timezone
        - weekdays
        - start_minute
        - end_minute
        - holidays
        - reason
    WorkflowCalendar:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 2
          maxLength: 120
        timezone:
          type: string
          minLength: 1
          maxLength: 80
        weekdays:
          type: array
          items:
            type: integer
            minimum: 1
            maximum: 7
          maxItems: 7
          minItems: 1
          uniqueItems: true
        start_minute:
          type: integer
          minimum: 0
          maximum: 1439
        end_minute:
          type: integer
          minimum: 1
          maximum: 1440
        holidays:
          type: array
          items:
            type: string
            format: date
          maxItems: 366
          uniqueItems: true
        version:
          type: integer
          minimum: 1
      required:
        - id
        - tenant_id
        - name
        - timezone
        - weekdays
        - start_minute
        - end_minute
        - holidays
        - version
    WorkflowTemplateInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 120
        family_id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 0
        calendar_id:
          type: string
          format: uuid
        site_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 100
          uniqueItems: true
        categories:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 80
          maxItems: 100
          uniqueItems: true
        stages:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowStage"
          maxItems: 20
          minItems: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - name
        - expected_version
        - calendar_id
        - site_ids
        - categories
        - stages
        - reason
    WorkflowTemplate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        family_id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        name:
          type: string
          minLength: 2
          maxLength: 120
        site_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 100
        categories:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 80
          maxItems: 100
        stages:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowStage"
          maxItems: 20
        calendar_snapshot:
          $ref: "#/components/schemas/WorkflowCalendar"
        published_by:
          type: string
          format: uuid
        published_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - family_id
        - version
        - name
        - site_ids
        - categories
        - stages
        - calendar_snapshot
        - published_by
        - published_at
    WorkflowStartInput:
      type: object
      additionalProperties: false
      properties:
        record_id:
          type: string
          format: uuid
        template_id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - record_id
        - template_id
        - expected_version
        - reason
    WorkflowActionInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        action:
          enum:
            - approve
            - reject
            - request_changes
            - delegate
            - reassign
            - withdraw
            - resubmit
            - close
            - void
        task_id:
          type: string
          format: uuid
        target_id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        consent:
          type: boolean
        password:
          type: string
          minLength: 12
          maxLength: 128
          writeOnly: true
        mfa_code:
          type: string
          pattern: ^[0-9]{6}$
          writeOnly: true
      required:
        - id
        - action
        - expected_version
        - reason
    WorkflowEventsQuery:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
      required:
        - id
    WorkflowInstance:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        record_id:
          type: string
          format: uuid
        template_id:
          type: string
          format: uuid
        template_snapshot:
          $ref: "#/components/schemas/WorkflowTemplate"
        record_version:
          type: integer
          minimum: 1
        content_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        submitter_id:
          type: string
          format: uuid
        status:
          enum:
            - active
            - approved
            - rejected
            - changes_requested
            - withdrawn
            - closed
            - void
        version:
          type: integer
          minimum: 1
        round:
          type: integer
          minimum: 1
        stage_index:
          type: integer
          minimum: 0
        resolved:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              stage_id:
                type: string
                minLength: 1
                maxLength: 120
              assignees:
                type: array
                items:
                  type: string
                  format: uuid
                maxItems: 100
            required:
              - stage_id
              - assignees
          maxItems: 100
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - record_id
        - template_id
        - template_snapshot
        - record_version
        - content_hash
        - submitter_id
        - status
        - version
        - round
        - stage_index
        - resolved
        - created_at
        - updated_at
    WorkflowTask:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        instance_id:
          type: string
          format: uuid
        round:
          type: integer
          minimum: 1
        stage_index:
          type: integer
          minimum: 0
        position:
          type: integer
          minimum: 0
        original_assignee_id:
          type: string
          format: uuid
        assignee_id:
          type: string
          format: uuid
        assignee_name:
          type: string
          minLength: 1
          maxLength: 120
        original_assignee_name:
          type: string
          minLength: 1
          maxLength: 120
        status:
          enum:
            - blocked
            - open
            - approved
            - rejected
            - changes_requested
            - cancelled
        opened_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        due_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        escalate_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        reminded_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        escalated_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        decided_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        signature_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - id
        - tenant_id
        - instance_id
        - round
        - stage_index
        - position
        - original_assignee_id
        - assignee_id
        - assignee_name
        - original_assignee_name
        - status
        - opened_at
        - due_at
        - escalate_at
        - reminded_at
        - escalated_at
        - decided_at
        - signature_id
    WorkflowInboxTask:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        instance_id:
          type: string
          format: uuid
        round:
          type: integer
          minimum: 1
        stage_index:
          type: integer
          minimum: 0
        position:
          type: integer
          minimum: 0
        original_assignee_id:
          type: string
          format: uuid
        assignee_id:
          type: string
          format: uuid
        assignee_name:
          type: string
          minLength: 1
          maxLength: 120
        original_assignee_name:
          type: string
          minLength: 1
          maxLength: 120
        status:
          enum:
            - blocked
            - open
            - approved
            - rejected
            - changes_requested
            - cancelled
        opened_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        due_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        escalate_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        reminded_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        escalated_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        decided_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        signature_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        record_id:
          type: string
          format: uuid
        instance_version:
          type: integer
          minimum: 1
        title:
          type: string
          minLength: 1
          maxLength: 200
        number:
          type: string
          minLength: 1
          maxLength: 40
      required:
        - id
        - tenant_id
        - instance_id
        - round
        - stage_index
        - position
        - original_assignee_id
        - assignee_id
        - assignee_name
        - original_assignee_name
        - status
        - opened_at
        - due_at
        - escalate_at
        - reminded_at
        - escalated_at
        - decided_at
        - signature_id
        - record_id
        - instance_version
        - title
        - number
    WorkflowRound:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        instance_id:
          type: string
          format: uuid
        round:
          type: integer
          minimum: 1
        record_id:
          type: string
          format: uuid
        record_version:
          type: integer
          minimum: 1
        content_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - instance_id
        - round
        - record_id
        - record_version
        - content_hash
        - created_at
    WorkflowDetail:
      type: object
      additionalProperties: false
      properties:
        instance:
          $ref: "#/components/schemas/WorkflowInstance"
        tasks:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowTask"
          maxItems: 2000
        rounds:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowRound"
          maxItems: 50
      required:
        - instance
        - tasks
        - rounds
    WorkflowEvent:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        instance_id:
          type: string
          format: uuid
        record_id:
          type: string
          format: uuid
        event_type:
          enum:
            - workflow.submitted.v1
            - workflow.approve.v1
            - workflow.reject.v1
            - workflow.request_changes.v1
            - workflow.delegate.v1
            - workflow.reassign.v1
            - workflow.withdraw.v1
            - workflow.resubmit.v1
            - workflow.close.v1
            - workflow.void.v1
            - workflow.reminder.v1
            - workflow.escalated.v1
        actor_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        actor_name:
          type: string
          minLength: 1
          maxLength: 120
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        request_id:
          type: string
          format: uuid
        record_version:
          type: integer
          minimum: 1
        instance_version:
          type: integer
          minimum: 1
        round:
          type: integer
          minimum: 1
        task_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        signature_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        details:
          type: object
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - instance_id
        - record_id
        - event_type
        - actor_id
        - actor_name
        - reason
        - request_id
        - record_version
        - instance_version
        - round
        - task_id
        - signature_id
        - details
        - created_at
    WorkflowWebhookInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 120
        url:
          type: string
          format: uri
          maxLength: 2048
          pattern: ^https://
        event_types:
          type: array
          items:
            enum:
              - workflow.submitted.v1
              - workflow.approve.v1
              - workflow.reject.v1
              - workflow.request_changes.v1
              - workflow.delegate.v1
              - workflow.reassign.v1
              - workflow.withdraw.v1
              - workflow.resubmit.v1
              - workflow.close.v1
              - workflow.void.v1
              - workflow.reminder.v1
              - workflow.escalated.v1
          maxItems: 20
          minItems: 1
          uniqueItems: true
        enabled:
          type: boolean
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - name
        - url
        - event_types
        - enabled
        - reason
    WorkflowWebhook:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 2
          maxLength: 120
        url:
          type: string
          format: uri
        event_types:
          type: array
          items:
            enum:
              - workflow.submitted.v1
              - workflow.approve.v1
              - workflow.reject.v1
              - workflow.request_changes.v1
              - workflow.delegate.v1
              - workflow.reassign.v1
              - workflow.withdraw.v1
              - workflow.resubmit.v1
              - workflow.close.v1
              - workflow.void.v1
              - workflow.reminder.v1
              - workflow.escalated.v1
          maxItems: 100
        enabled:
          type: boolean
        version:
          type: integer
          minimum: 1
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - name
        - url
        - event_types
        - enabled
        - version
        - created_at
    WorkflowWebhookIssued:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 2
          maxLength: 120
        url:
          type: string
          format: uri
        event_types:
          type: array
          items:
            enum:
              - workflow.submitted.v1
              - workflow.approve.v1
              - workflow.reject.v1
              - workflow.request_changes.v1
              - workflow.delegate.v1
              - workflow.reassign.v1
              - workflow.withdraw.v1
              - workflow.resubmit.v1
              - workflow.close.v1
              - workflow.void.v1
              - workflow.reminder.v1
              - workflow.escalated.v1
          maxItems: 100
        enabled:
          type: boolean
        version:
          type: integer
          minimum: 1
        created_at:
          type: string
          format: date-time
        secret:
          type: string
          pattern: ^[a-f0-9]{64}$
          description: One-time reveal; omitted from audit and idempotent replay.
      required:
        - id
        - tenant_id
        - name
        - url
        - event_types
        - enabled
        - version
        - created_at
    WorkflowVersionInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - expected_version
        - reason
    WorkflowWebhookUpdate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        enabled:
          type: boolean
      required:
        - id
        - expected_version
        - reason
        - enabled
    WorkflowReplayInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - reason
    WorkflowDelivery:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        subscription_id:
          type: string
          format: uuid
        event_id:
          type: string
          format: uuid
        status:
          enum:
            - pending
            - inflight
            - delivered
            - dead
        attempts:
          type: integer
          minimum: 0
        replay_count:
          type: integer
          minimum: 0
        next_attempt_at:
          type: string
          format: date-time
        last_status:
          anyOf:
            - type: integer
            - type: "null"
        last_error:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
            - type: "null"
        completed_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - subscription_id
        - event_id
        - status
        - attempts
        - replay_count
        - next_attempt_at
        - last_status
        - last_error
        - completed_at
        - created_at
    WorkflowCalendarsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowCalendar"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    WorkflowTemplatesPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowTemplate"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    WorkflowInstancesPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowInstance"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    WorkflowTasksPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowInboxTask"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    WorkflowEventsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowEvent"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    WorkflowWebhooksPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowWebhook"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    WorkflowDeliveriesPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/WorkflowDelivery"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    WorkflowHistoryQuery:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        kind:
          enum:
            - rounds
            - tasks
        round:
          type: integer
          minimum: 1
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
      required:
        - id
        - kind
    WorkflowHistoryPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            anyOf:
              - $ref: "#/components/schemas/WorkflowRound"
              - $ref: "#/components/schemas/WorkflowTask"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    FormScalar:
      anyOf:
        - type: "null"
        - type: boolean
        - type: number
          minimum: -1000000000
          maximum: 1000000000
        - type: string
          minLength: 0
          maxLength: 10000
    FormValue:
      anyOf:
        - $ref: "#/components/schemas/FormScalar"
        - type: array
          items:
            $ref: "#/components/schemas/FormValue"
          maxItems: 100
        - type: object
          maxProperties: 101
          additionalProperties:
            $ref: "#/components/schemas/FormValue"
    FormValues:
      type: object
      maxProperties: 100
      propertyNames:
        type: string
        pattern: ^[a-z][a-z0-9_]{0,39}$
      additionalProperties:
        $ref: "#/components/schemas/FormValue"
    FormExpression:
      anyOf:
        - type: object
          additionalProperties: false
          properties:
            op:
              const: literal
              type: string
            value:
              $ref: "#/components/schemas/FormScalar"
          required:
            - op
            - value
        - type: object
          additionalProperties: false
          properties:
            op:
              const: field
              type: string
            id:
              type: string
              pattern: ^[a-z][a-z0-9_]{0,39}$
          required:
            - op
            - id
        - type: object
          additionalProperties: false
          properties:
            op:
              const: not
              type: string
            arg:
              $ref: "#/components/schemas/FormExpression"
          required:
            - op
            - arg
        - type: object
          additionalProperties: false
          properties:
            op:
              enum:
                - eq
                - ne
                - gt
                - gte
                - lt
                - lte
                - and
                - or
                - add
                - sub
                - mul
                - div
                - concat
                - coalesce
                - contains
            args:
              type: array
              items:
                $ref: "#/components/schemas/FormExpression"
              maxItems: 20
              minItems: 2
          required:
            - op
            - args
    FormOption:
      type: object
      additionalProperties: false
      properties:
        value:
          type: string
          minLength: 1
          maxLength: 80
        label:
          type: string
          minLength: 1
          maxLength: 120
      required:
        - value
        - label
    FormField:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          pattern: ^[a-z][a-z0-9_]{0,39}$
        label:
          type: string
          minLength: 1
          maxLength: 120
        type:
          enum:
            - text
            - multiline
            - richtext
            - integer
            - decimal
            - date
            - datetime
            - time
            - boolean
            - choice
            - multiselect
            - radio
            - checkboxes
            - user
            - role
            - site
            - department
            - reference
            - attachment
            - grid
            - calculated
            - generated
        section:
          type: string
          pattern: ^[a-z][a-z0-9_]{0,39}$
        help:
          type: string
          minLength: 0
          maxLength: 500
        required:
          type: boolean
        readRoles:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 50
          uniqueItems: true
        editRoles:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 50
          uniqueItems: true
        default:
          $ref: "#/components/schemas/FormValue"
        min:
          type: number
          minimum: -1000000000
          maximum: 1000000000
        max:
          type: number
          minimum: -1000000000
          maximum: 1000000000
        pattern:
          type: string
          minLength: 1
          maxLength: 100
        options:
          type: array
          items:
            $ref: "#/components/schemas/FormOption"
          maxItems: 100
        vocabularyId:
          type: string
          format: uuid
        vocabularyVersion:
          type: integer
          minimum: 1
        referenceKind:
          enum:
            - product
            - material
            - batch
            - equipment
            - supplier
            - document
        visibleWhen:
          $ref: "#/components/schemas/FormExpression"
        requiredWhen:
          $ref: "#/components/schemas/FormExpression"
        calculate:
          $ref: "#/components/schemas/FormExpression"
        generated:
          enum:
            - record_number
            - actor_name
            - created_at
        columns:
          type: array
          items:
            $ref: "#/components/schemas/FormField"
          maxItems: 20
          minItems: 1
      required:
        - id
        - label
        - type
        - section
    FormSchema:
      type: object
      additionalProperties: false
      properties:
        schemaVersion:
          const: 1
          type: integer
        sections:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
                pattern: ^[a-z][a-z0-9_]{0,39}$
              title:
                type: string
                minLength: 1
                maxLength: 120
              columns:
                enum:
                  - 1
                  - 2
            required:
              - id
              - title
              - columns
          maxItems: 20
          minItems: 1
        fields:
          type: array
          items:
            $ref: "#/components/schemas/FormField"
          maxItems: 100
        rules:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              expression:
                $ref: "#/components/schemas/FormExpression"
              message:
                type: string
                minLength: 1
                maxLength: 200
            required:
              - expression
              - message
          maxItems: 20
      required:
        - schemaVersion
        - sections
        - fields
        - rules
    FormDefinition:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 120
        schema:
          $ref: "#/components/schemas/FormSchema"
        site_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 100
          uniqueItems: true
        department_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 100
          uniqueItems: true
        workflow_template_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - name
        - schema
        - site_ids
        - department_ids
        - workflow_template_id
    FormDraftInput:
      type: object
      additionalProperties: false
      properties:
        definition:
          $ref: "#/components/schemas/FormDefinition"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - definition
        - reason
    FormDraftUpdate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        definition:
          $ref: "#/components/schemas/FormDefinition"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - expected_version
        - definition
        - reason
    FormVersionInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - expected_version
        - reason
    FormTemplate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 2
          maxLength: 120
        version:
          type: integer
          minimum: 1
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - name
        - version
        - created_by
        - created_at
    FormDraft:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        template_id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        definition:
          $ref: "#/components/schemas/FormDefinition"
        created_by:
          type: string
          format: uuid
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - template_id
        - version
        - definition
        - created_by
        - reason
        - created_at
    FormPublication:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        template_id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        revision_id:
          type: string
          format: uuid
        definition:
          $ref: "#/components/schemas/FormDefinition"
        schema_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        published_by:
          type: string
          format: uuid
        published_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - template_id
        - version
        - revision_id
        - definition
        - schema_hash
        - published_by
        - published_at
    FormTemplateDetail:
      type: object
      additionalProperties: false
      properties:
        template:
          $ref: "#/components/schemas/FormTemplate"
        draft:
          $ref: "#/components/schemas/FormDraft"
        publications:
          type: array
          items:
            $ref: "#/components/schemas/FormPublication"
          maxItems: 50
      required:
        - template
        - draft
        - publications
    FormRecordInput:
      type: object
      additionalProperties: false
      properties:
        publication_id:
          type: string
          format: uuid
        title:
          type: string
          minLength: 2
          maxLength: 200
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        values:
          $ref: "#/components/schemas/FormValues"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - publication_id
        - title
        - site_id
        - department_id
        - values
        - reason
    FormCorrectionInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        title:
          type: string
          minLength: 2
          maxLength: 200
        values:
          $ref: "#/components/schemas/FormValues"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - expected_version
        - title
        - values
        - reason
    FormSubmitInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        values:
          $ref: "#/components/schemas/FormValues"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - expected_version
        - reason
    FormRecordQuery:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
      required:
        - id
    FormRecordVersion:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        record_id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        publication_id:
          type: string
          format: uuid
        schema_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        values_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        ready:
          type: boolean
        actor_id:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - tenant_id
        - record_id
        - version
        - publication_id
        - schema_hash
        - values_hash
        - ready
        - actor_id
        - created_at
        - reason
    FormRecordDetail:
      type: object
      additionalProperties: false
      properties:
        record:
          $ref: "#/components/schemas/IntegrityRecord"
        current_version:
          type: integer
          minimum: 1
        snapshot:
          $ref: "#/components/schemas/FormRecordVersion"
        publication:
          $ref: "#/components/schemas/FormPublication"
        values:
          $ref: "#/components/schemas/FormValues"
        display_values:
          $ref: "#/components/schemas/FormValues"
        redacted_fields:
          type: integer
          minimum: 0
        workflow:
          anyOf:
            - $ref: "#/components/schemas/WorkflowInstance"
            - type: "null"
        signatures:
          type: array
          items:
            $ref: "#/components/schemas/IntegritySignature"
          maxItems: 1000
      required:
        - record
        - current_version
        - snapshot
        - publication
        - values
        - display_values
        - redacted_fields
        - workflow
        - signatures
    FormRecordSummary:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        number:
          type: string
          minLength: 1
          maxLength: 40
        title:
          type: string
          minLength: 2
          maxLength: 200
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        template_id:
          type: string
          format: uuid
        publication_id:
          type: string
          format: uuid
        state:
          enum:
            - draft
            - active
            - approved
            - closed
            - rejected
            - changes_requested
            - withdrawn
            - void
      required:
        - id
        - tenant_id
        - number
        - title
        - site_id
        - department_id
        - version
        - created_by
        - created_at
        - updated_at
        - template_id
        - publication_id
        - state
    FormFilters:
      type: object
      additionalProperties: false
      properties:
        q:
          type: string
          minLength: 0
          maxLength: 100
        template_id:
          type: string
          format: uuid
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        state:
          enum:
            - draft
            - active
            - approved
            - closed
            - rejected
            - changes_requested
            - withdrawn
            - void
      required: []
    FormRecordsQuery:
      type: object
      additionalProperties: false
      properties:
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
        q:
          type: string
          minLength: 0
          maxLength: 100
        template_id:
          type: string
          format: uuid
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        state:
          enum:
            - draft
            - active
            - approved
            - closed
            - rejected
            - changes_requested
            - withdrawn
            - void
      required: []
    FormAttachmentInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        field_id:
          type: string
          pattern: ^[a-z][a-z0-9_]{0,39}$
        filename:
          type: string
          minLength: 1
          maxLength: 180
        mime_type:
          enum:
            - text/plain
            - application/pdf
        size_bytes:
          type: integer
          minimum: 1
          maximum: 10000000
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - expected_version
        - field_id
        - filename
        - mime_type
        - size_bytes
        - sha256
        - reason
    FormHistoryQuery:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        resource:
          enum:
            - template
            - record
            - vocabulary
        kind:
          enum:
            - drafts
            - publications
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
      required:
        - id
        - resource
    FormVocabularyInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 120
        options:
          type: array
          items:
            $ref: "#/components/schemas/FormOption"
          maxItems: 100
          minItems: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - name
        - options
        - reason
    FormVocabularyUpdate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        name:
          type: string
          minLength: 2
          maxLength: 120
        options:
          type: array
          items:
            $ref: "#/components/schemas/FormOption"
          maxItems: 100
          minItems: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - expected_version
        - name
        - options
        - reason
    FormVocabulary:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 2
          maxLength: 120
        version:
          type: integer
          minimum: 1
        options:
          type: array
          items:
            $ref: "#/components/schemas/FormOption"
          maxItems: 100
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - name
        - version
        - options
        - created_at
    FormVocabularyVersion:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        vocabulary_id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        options:
          type: array
          items:
            $ref: "#/components/schemas/FormOption"
          maxItems: 100
        actor_id:
          type: string
          format: uuid
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - vocabulary_id
        - version
        - options
        - actor_id
        - reason
        - created_at
    FormReferenceInput:
      type: object
      additionalProperties: false
      properties:
        kind:
          enum:
            - product
            - material
            - batch
            - equipment
            - supplier
            - document
        code:
          type: string
          minLength: 1
          maxLength: 80
        name:
          type: string
          minLength: 1
          maxLength: 160
        site_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - kind
        - code
        - name
        - site_id
        - reason
    FormReferenceUpdate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        name:
          type: string
          minLength: 1
          maxLength: 160
        active:
          type: boolean
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - expected_version
        - name
        - active
        - reason
    FormReference:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        kind:
          enum:
            - product
            - material
            - batch
            - equipment
            - supplier
            - document
        code:
          type: string
          minLength: 1
          maxLength: 80
        name:
          type: string
          minLength: 1
          maxLength: 160
        site_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        active:
          type: boolean
        version:
          type: integer
          minimum: 1
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - kind
        - code
        - name
        - site_id
        - active
        - version
        - created_at
    FormReferencesQuery:
      type: object
      additionalProperties: false
      properties:
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
        kind:
          enum:
            - product
            - material
            - batch
            - equipment
            - supplier
            - document
        site_id:
          type: string
          format: uuid
      required: []
    FormOptionsQuery:
      type: object
      additionalProperties: false
      properties:
        publication_id:
          type: string
          format: uuid
        field_id:
          type: string
          pattern: ^[a-z][a-z0-9_]{0,39}$
        site_id:
          type: string
          format: uuid
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
      required:
        - publication_id
        - field_id
        - site_id
    FormSelection:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        label:
          type: string
          minLength: 1
          maxLength: 250
      required:
        - id
        - label
    FormViewInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 80
        filters:
          $ref: "#/components/schemas/FormFilters"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - name
        - filters
        - reason
    FormViewUpdate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        name:
          type: string
          minLength: 2
          maxLength: 80
        filters:
          $ref: "#/components/schemas/FormFilters"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - expected_version
        - name
        - filters
        - reason
    FormView:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        user_id:
          type: string
          format: uuid
        name:
          type: string
          minLength: 2
          maxLength: 80
        filters:
          $ref: "#/components/schemas/FormFilters"
        version:
          type: integer
          minimum: 1
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - user_id
        - name
        - filters
        - version
        - created_at
    FormExportInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        format:
          enum:
            - pdf
            - json
            - csv
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - format
        - reason
    FormExport:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        record_id:
          type: string
          format: uuid
        record_version:
          type: integer
          minimum: 1
        requested_by:
          type: string
          format: uuid
        session_id:
          type: string
          format: uuid
        aal:
          enum:
            - aal1
            - aal2
        format:
          enum:
            - pdf
            - json
            - csv
        status:
          enum:
            - pending
            - inflight
            - complete
            - dead
        access_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        object_path:
          type: string
          minLength: 1
          maxLength: 250
        sha256:
          anyOf:
            - type: string
              pattern: ^[a-f0-9]{64}$
            - type: "null"
        size_bytes:
          anyOf:
            - type: integer
              minimum: 1
              maximum: 10000000
            - type: "null"
        attempts:
          type: integer
          minimum: 0
        next_attempt_at:
          type: string
          format: date-time
        last_error:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
            - type: "null"
        created_at:
          type: string
          format: date-time
        completed_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
      required:
        - id
        - tenant_id
        - record_id
        - record_version
        - requested_by
        - session_id
        - aal
        - format
        - status
        - access_hash
        - object_path
        - sha256
        - size_bytes
        - attempts
        - next_attempt_at
        - last_error
        - created_at
        - completed_at
    FormDownload:
      type: object
      additionalProperties: false
      properties:
        url:
          type: string
          format: uri
        expires_at:
          type: string
          format: date-time
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        size_bytes:
          type: integer
          minimum: 1
          maximum: 10000000
      required:
        - url
        - expires_at
        - sha256
        - size_bytes
    FormTemplatesPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/FormTemplate"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    FormPublicationsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/FormPublication"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    FormRecordsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/FormRecordSummary"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    FormVocabulariesPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/FormVocabulary"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    FormReferencesPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/FormReference"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    FormOptionsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/FormSelection"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    FormViewsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/FormView"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    FormExportsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/FormExport"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    FormHistoryPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            anyOf:
              - $ref: "#/components/schemas/FormDraft"
              - $ref: "#/components/schemas/FormPublication"
              - $ref: "#/components/schemas/FormVocabularyVersion"
              - $ref: "#/components/schemas/FormRecordVersion"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    FormAccess:
      type: object
      additionalProperties: false
      properties:
        role_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 50
          uniqueItems: true
        can_manage:
          type: boolean
      required:
        - role_ids
        - can_manage
    FormLocationsQuery:
      type: object
      additionalProperties: false
      properties:
        kind:
          enum:
            - site
            - department
        site_id:
          type: string
          format: uuid
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
      required:
        - kind
    FormLocation:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        label:
          type: string
          minLength: 1
          maxLength: 120
        site_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - id
        - label
        - site_id
    FormLocationsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/FormLocation"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    ControlledVersionInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - expected_version
        - reason
    DocumentDefinition:
      type: object
      additionalProperties: false
      properties:
        title:
          type: string
          minLength: 2
          maxLength: 200
        kind:
          enum:
            - sop
            - policy
            - work_instruction
            - specification
            - test_method
            - protocol
            - form
            - manual
            - external
        owner_id:
          type: string
          format: uuid
        change_summary:
          type: string
          minLength: 3
          maxLength: 2000
        effective_at:
          type: string
          format: date-time
        review_on:
          anyOf:
            - type: string
              format: date
            - type: "null"
        expires_on:
          anyOf:
            - type: string
              format: date
            - type: "null"
        workflow_template_id:
          type: string
          format: uuid
        training_rule:
          enum:
            - none
            - all_required
        external_reference:
          anyOf:
            - type: string
              minLength: 3
              maxLength: 1000
            - type: "null"
      required:
        - title
        - kind
        - owner_id
        - change_summary
        - effective_at
        - review_on
        - expires_on
        - workflow_template_id
        - training_rule
        - external_reference
    DocumentCreate:
      type: object
      additionalProperties: false
      properties:
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        definition:
          $ref: "#/components/schemas/DocumentDefinition"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - site_id
        - department_id
        - definition
        - reason
    DocumentRevisionCreate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        definition:
          $ref: "#/components/schemas/DocumentDefinition"
      required:
        - id
        - expected_version
        - reason
        - definition
    DocumentPolicy:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        allow_download:
          type: boolean
        allow_print:
          type: boolean
      required:
        - id
        - expected_version
        - reason
        - allow_download
        - allow_print
    ControlledDocument:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        number:
          type: string
          minLength: 1
          maxLength: 40
        title:
          type: string
          minLength: 2
          maxLength: 200
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        current_revision_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        status:
          enum:
            - draft
            - effective
            - obsolete
        allow_download:
          type: boolean
        allow_print:
          type: boolean
        version:
          type: integer
          minimum: 1
        usable:
          type: boolean
      required:
        - id
        - tenant_id
        - created_by
        - created_at
        - number
        - title
        - site_id
        - department_id
        - current_revision_id
        - status
        - allow_download
        - allow_print
        - version
        - usable
    DocumentRevision:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        document_id:
          type: string
          format: uuid
        revision:
          type: integer
          minimum: 1
        record_id:
          type: string
          format: uuid
        definition:
          $ref: "#/components/schemas/DocumentDefinition"
        source_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        ready_version:
          anyOf:
            - type: integer
              minimum: 1
            - type: "null"
        status:
          enum:
            - draft
            - in_review
            - approved_pending
            - effective
            - superseded
            - obsolete
        required_assignment_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 1000
        issued_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        effective_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        superseded_by:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        version:
          type: integer
          minimum: 1
        review_notified_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
      required:
        - id
        - tenant_id
        - created_by
        - created_at
        - document_id
        - revision
        - record_id
        - definition
        - source_id
        - ready_version
        - status
        - required_assignment_ids
        - issued_at
        - effective_at
        - superseded_by
        - version
        - review_notified_at
    DocumentSource:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        record_id:
          type: string
          format: uuid
        record_version:
          type: integer
          minimum: 1
        filename:
          type: string
          minLength: 1
          maxLength: 180
        mime_type:
          enum:
            - text/plain
            - application/pdf
        size_bytes:
          type: integer
          minimum: 1
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        state:
          enum:
            - quarantined
            - clean
            - rejected
        scanner:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 200
            - type: "null"
        scanned_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - record_id
        - record_version
        - filename
        - mime_type
        - size_bytes
        - sha256
        - state
        - scanner
        - scanned_at
        - created_by
        - created_at
    DocumentDetail:
      type: object
      additionalProperties: false
      properties:
        document:
          $ref: "#/components/schemas/ControlledDocument"
        revisions:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              revision:
                $ref: "#/components/schemas/DocumentRevision"
              record:
                $ref: "#/components/schemas/IntegrityRecord"
              source:
                anyOf:
                  - $ref: "#/components/schemas/DocumentSource"
                  - type: "null"
              workflow:
                anyOf:
                  - $ref: "#/components/schemas/WorkflowInstance"
                  - type: "null"
            required:
              - revision
              - record
              - source
              - workflow
          maxItems: 1000
        obsolescence:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              request:
                $ref: "#/components/schemas/DocumentObsolescence"
              workflow:
                anyOf:
                  - $ref: "#/components/schemas/WorkflowInstance"
                  - type: "null"
            required:
              - request
              - workflow
          maxItems: 1000
      required:
        - document
        - revisions
        - obsolescence
    DocumentPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/ControlledDocument"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    ControlledAttachmentInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        filename:
          type: string
          minLength: 1
          maxLength: 180
        mime_type:
          enum:
            - text/plain
            - application/pdf
        size_bytes:
          type: integer
          minimum: 1
          maximum: 10485760
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
      required:
        - id
        - expected_version
        - reason
        - filename
        - mime_type
        - size_bytes
        - sha256
    AssessmentQuestion:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          pattern: ^[a-z][a-z0-9_]{0,39}$
        text:
          type: string
          minLength: 1
          maxLength: 500
        options:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 300
          maxItems: 10
          minItems: 2
          uniqueItems: true
        correct_index:
          type: integer
          minimum: 0
          maximum: 9
      required:
        - id
        - text
        - options
        - correct_index
    PublicAssessmentQuestion:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          pattern: ^[a-z][a-z0-9_]{0,39}$
        text:
          type: string
          minLength: 1
          maxLength: 500
        options:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 300
          maxItems: 10
          minItems: 2
          uniqueItems: true
      required:
        - id
        - text
        - options
    TrainingDefinition:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 160
        mode:
          enum:
            - document
            - instructor
            - external
        document_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        requires_verification:
          type: boolean
        valid_days:
          anyOf:
            - type: integer
              minimum: 1
              maximum: 3650
            - type: "null"
        pass_mark:
          type: integer
          minimum: 0
          maximum: 100
        max_attempts:
          type: integer
          minimum: 1
          maximum: 5
        questions:
          type: array
          items:
            $ref: "#/components/schemas/AssessmentQuestion"
          maxItems: 20
      required:
        - name
        - mode
        - document_id
        - requires_verification
        - valid_days
        - pass_mark
        - max_attempts
        - questions
    TrainingPublicDefinition:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 160
        mode:
          enum:
            - document
            - instructor
            - external
        document_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        requires_verification:
          type: boolean
        valid_days:
          anyOf:
            - type: integer
              minimum: 1
              maximum: 3650
            - type: "null"
        pass_mark:
          type: integer
          minimum: 0
          maximum: 100
        max_attempts:
          type: integer
          minimum: 1
          maximum: 5
        questions:
          type: array
          items:
            $ref: "#/components/schemas/PublicAssessmentQuestion"
          maxItems: 20
      required:
        - name
        - mode
        - document_id
        - requires_verification
        - valid_days
        - pass_mark
        - max_attempts
        - questions
    TrainingCourseCreate:
      type: object
      additionalProperties: false
      properties:
        definition:
          $ref: "#/components/schemas/TrainingDefinition"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - definition
        - reason
    TrainingCourseRevise:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        definition:
          $ref: "#/components/schemas/TrainingDefinition"
      required:
        - id
        - expected_version
        - reason
        - definition
    TrainingPublication:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        course_id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        definition:
          $ref: "#/components/schemas/TrainingPublicDefinition"
        definition_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
      required:
        - id
        - tenant_id
        - created_by
        - created_at
        - course_id
        - version
        - definition
        - definition_hash
    TrainingCoursesPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/TrainingPublication"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    TrainingAssign:
      type: object
      additionalProperties: false
      properties:
        course_version_id:
          type: string
          format: uuid
        document_revision_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        assignee_id:
          type: string
          format: uuid
        supervisor_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        due_at:
          type: string
          format: date-time
        grace_days:
          type: integer
          minimum: 0
          maximum: 90
        required:
          type: boolean
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - course_version_id
        - document_revision_id
        - assignee_id
        - supervisor_id
        - site_id
        - department_id
        - due_at
        - grace_days
        - required
        - reason
    TrainingAssignment:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        course_version_id:
          type: string
          format: uuid
        curriculum_version_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        document_revision_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        record_id:
          type: string
          format: uuid
        assignee_id:
          type: string
          format: uuid
        supervisor_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        required:
          type: boolean
        due_at:
          type: string
          format: date-time
        grace_days:
          type: integer
          minimum: 0
          maximum: 90
        extra_attempts:
          type: integer
          minimum: 0
          maximum: 10
        status:
          enum:
            - assigned
            - awaiting_verification
            - qualified
            - failed
        score:
          anyOf:
            - type: integer
              minimum: 0
              maximum: 100
            - type: "null"
        completed_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        verified_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        valid_until:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        ack_signature_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        verification_signature_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        overdue_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        escalated_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        expiry_notified_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        version:
          type: integer
          minimum: 1
      required:
        - id
        - tenant_id
        - created_by
        - created_at
        - course_version_id
        - curriculum_version_id
        - document_revision_id
        - record_id
        - assignee_id
        - supervisor_id
        - required
        - due_at
        - grace_days
        - extra_attempts
        - status
        - score
        - completed_at
        - verified_at
        - valid_until
        - ack_signature_id
        - verification_signature_id
        - overdue_at
        - escalated_at
        - expiry_notified_at
        - version
    TrainingAssignmentsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/TrainingAssignmentSummary"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    TrainingAttempt:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        assignment_id:
          type: string
          format: uuid
        sequence:
          type: integer
          minimum: 1
        score:
          type: integer
          minimum: 0
          maximum: 100
        passed:
          type: boolean
        answers_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        actor_id:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - assignment_id
        - sequence
        - score
        - passed
        - answers_hash
        - actor_id
        - created_at
    TrainingDetail:
      type: object
      additionalProperties: false
      properties:
        assignment:
          $ref: "#/components/schemas/TrainingAssignment"
        course:
          $ref: "#/components/schemas/TrainingPublication"
        record:
          $ref: "#/components/schemas/IntegrityRecord"
        attempts:
          type: array
          items:
            $ref: "#/components/schemas/TrainingAttempt"
          maxItems: 15
        signatures:
          type: array
          items:
            $ref: "#/components/schemas/IntegritySignature"
          maxItems: 50
        material:
          anyOf:
            - type: object
              additionalProperties: false
              properties:
                revision_id:
                  type: string
                  format: uuid
                number:
                  type: string
                  minLength: 1
                  maxLength: 40
                revision:
                  type: integer
                  minimum: 1
                title:
                  type: string
                  minLength: 2
                  maxLength: 200
                status:
                  enum:
                    - draft
                    - in_review
                    - approved_pending
                    - effective
                    - superseded
                    - obsolete
              required:
                - revision_id
                - number
                - revision
                - title
                - status
            - type: "null"
      required:
        - assignment
        - course
        - record
        - attempts
        - signatures
        - material
    TrainingComplete:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        password:
          type: string
          minLength: 1
          maxLength: 1024
        mfa_code:
          type: string
          pattern: ^[0-9]{6}$
        consent:
          type: boolean
          const: true
        answers:
          type: object
          maxProperties: 20
          propertyNames:
            type: string
            pattern: ^[a-z][a-z0-9_]{0,39}$
          additionalProperties:
            type: integer
            minimum: 0
            maximum: 9
        activity:
          type: object
          additionalProperties: false
          properties:
            completed_on:
              type: string
              format: date
            instructor:
              type: string
              minLength: 2
              maxLength: 300
            provider:
              type: string
              minLength: 2
              maxLength: 300
            certificate_reference:
              type: string
              minLength: 1
              maxLength: 300
          required: []
      required:
        - id
        - expected_version
        - reason
        - password
        - consent
        - answers
        - activity
    TrainingVerify:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        password:
          type: string
          minLength: 1
          maxLength: 1024
        mfa_code:
          type: string
          pattern: ^[0-9]{6}$
        consent:
          type: boolean
          const: true
      required:
        - id
        - expected_version
        - reason
        - password
        - consent
    TrainingExtend:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        extra_attempts:
          type: integer
          minimum: 0
          maximum: 10
        due_at:
          type: string
          format: date-time
        grace_days:
          type: integer
          minimum: 0
          maximum: 90
      required:
        - id
        - expected_version
        - reason
        - extra_attempts
        - due_at
        - grace_days
    ControlledReasonInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - reason
    ControlledCopyRequest:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        purpose:
          enum:
            - view
            - download
            - print
            - inspection
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - purpose
        - reason
    ControlledCopy:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        revision_id:
          type: string
          format: uuid
        assignment_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        requested_by:
          type: string
          format: uuid
        session_id:
          type: string
          format: uuid
        aal:
          enum:
            - aal1
            - aal2
        purpose:
          enum:
            - view
            - download
            - print
            - inspection
        source_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        access_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        state_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        object_path:
          type: string
          minLength: 1
          maxLength: 250
        status:
          enum:
            - pending
            - inflight
            - complete
            - dead
        attempts:
          type: integer
          minimum: 0
        next_attempt_at:
          type: string
          format: date-time
        last_error:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
            - type: "null"
        sha256:
          anyOf:
            - type: string
              pattern: ^[a-f0-9]{64}$
            - type: "null"
        size_bytes:
          anyOf:
            - type: integer
              minimum: 1
              maximum: 20000000
            - type: "null"
        created_at:
          type: string
          format: date-time
        completed_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        retrieved_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
      required:
        - id
        - tenant_id
        - revision_id
        - assignment_id
        - requested_by
        - session_id
        - aal
        - purpose
        - source_hash
        - access_hash
        - state_hash
        - object_path
        - status
        - attempts
        - next_attempt_at
        - last_error
        - sha256
        - size_bytes
        - created_at
        - completed_at
        - retrieved_at
    ControlledCopiesPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/ControlledCopy"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    ControlledChoices:
      type: object
      additionalProperties: false
      properties:
        kind:
          enum:
            - site
            - department
            - person
            - workflow
            - obsolescence
            - role
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
      required:
        - kind
    TrainingCurriculumDefinition:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 160
        role_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 50
        site_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 50
        department_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 50
        course_version_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 10
          minItems: 1
          uniqueItems: true
        due_days:
          type: integer
          minimum: 1
          maximum: 3650
        grace_days:
          type: integer
          minimum: 0
          maximum: 90
        required:
          type: boolean
        supervisor_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - name
        - role_ids
        - site_ids
        - department_ids
        - course_version_ids
        - due_days
        - grace_days
        - required
        - supervisor_id
    TrainingCurriculumPublication:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        curriculum_id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        definition:
          $ref: "#/components/schemas/TrainingCurriculumDefinition"
      required:
        - id
        - tenant_id
        - created_by
        - created_at
        - curriculum_id
        - version
        - definition
    TrainingCurriculaPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/TrainingCurriculumPublication"
          maxItems: 100
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    TrainingCurriculumCreate:
      type: object
      additionalProperties: false
      properties:
        definition:
          $ref: "#/components/schemas/TrainingCurriculumDefinition"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - definition
        - reason
    TrainingCurriculumRevise:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        definition:
          $ref: "#/components/schemas/TrainingCurriculumDefinition"
      required:
        - id
        - expected_version
        - reason
        - definition
    TrainingEnroll:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        revision_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - id
        - revision_id
        - reason
    TrainingEnrollment:
      type: object
      additionalProperties: false
      properties:
        assigned:
          type: integer
          minimum: 0
          maximum: 25
      required:
        - assigned
    DocumentObsoleteRequest:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        workflow_template_id:
          type: string
          format: uuid
      required:
        - id
        - expected_version
        - reason
        - workflow_template_id
    DocumentObsolescence:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        document_id:
          type: string
          format: uuid
        revision_id:
          type: string
          format: uuid
        record_id:
          type: string
          format: uuid
        workflow_template_id:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - document_id
        - revision_id
        - record_id
        - workflow_template_id
        - created_at
    TrainingAssignmentSummary:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        course_version_id:
          type: string
          format: uuid
        curriculum_version_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        document_revision_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        record_id:
          type: string
          format: uuid
        assignee_id:
          type: string
          format: uuid
        supervisor_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        required:
          type: boolean
        due_at:
          type: string
          format: date-time
        grace_days:
          type: integer
          minimum: 0
          maximum: 90
        extra_attempts:
          type: integer
          minimum: 0
          maximum: 10
        status:
          enum:
            - assigned
            - awaiting_verification
            - qualified
            - failed
        score:
          anyOf:
            - type: integer
              minimum: 0
              maximum: 100
            - type: "null"
        completed_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        verified_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        valid_until:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        ack_signature_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        verification_signature_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        overdue_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        escalated_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        expiry_notified_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        version:
          type: integer
          minimum: 1
        assignee_name:
          type: string
          minLength: 1
          maxLength: 200
        course_name:
          type: string
          minLength: 2
          maxLength: 160
      required:
        - id
        - tenant_id
        - created_by
        - created_at
        - course_version_id
        - curriculum_version_id
        - document_revision_id
        - record_id
        - assignee_id
        - supervisor_id
        - required
        - due_at
        - grace_days
        - extra_attempts
        - status
        - score
        - completed_at
        - verified_at
        - valid_until
        - ack_signature_id
        - verification_signature_id
        - overdue_at
        - escalated_at
        - expiry_notified_at
        - version
        - assignee_name
        - course_name
    QualityMasterDefinition:
      type: object
      additionalProperties: false
      properties:
        code:
          type: string
          pattern: ^[A-Z0-9][A-Z0-9._-]{0,49}$
        name:
          type: string
          minLength: 2
          maxLength: 200
        active:
          type: boolean
        source_system:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
            - type: "null"
        external_id:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 200
            - type: "null"
        source_uri:
          anyOf:
            - type: string
              format: uri
              pattern: ^https://
              maxLength: 1000
            - type: "null"
        related_version_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 30
          minItems: 0
        manufactured_on:
          anyOf:
            - type: string
              format: date
            - type: "null"
        expires_on:
          anyOf:
            - type: string
              format: date
            - type: "null"
      required:
        - code
        - name
        - active
        - source_system
        - external_id
        - source_uri
        - related_version_ids
        - manufactured_on
        - expires_on
    QualityMaster:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        kind:
          type: string
          enum:
            - product
            - material
            - batch
            - process
        code:
          type: string
          pattern: ^[A-Z0-9][A-Z0-9._-]{0,49}$
        name:
          type: string
          minLength: 2
          maxLength: 200
        site_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        department_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        version:
          type: integer
          minimum: 1
        active:
          type: boolean
        source_system:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
            - type: "null"
        external_id:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 200
            - type: "null"
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - kind
        - code
        - name
        - site_id
        - department_id
        - version
        - active
        - source_system
        - external_id
        - created_by
        - created_at
    QualityMasterPublication:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        kind:
          type: string
          enum:
            - product
            - material
            - batch
            - process
        code:
          type: string
          pattern: ^[A-Z0-9][A-Z0-9._-]{0,49}$
        name:
          type: string
          minLength: 2
          maxLength: 200
        site_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        department_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        version:
          type: integer
          minimum: 1
        active:
          type: boolean
        source_system:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
            - type: "null"
        external_id:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 200
            - type: "null"
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        publication_id:
          type: string
          format: uuid
        definition:
          $ref: "#/components/schemas/QualityMasterDefinition"
        definition_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
      required:
        - id
        - tenant_id
        - kind
        - code
        - name
        - site_id
        - department_id
        - version
        - active
        - source_system
        - external_id
        - created_by
        - created_at
        - publication_id
        - definition
        - definition_hash
    QualityMasterVersion:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        master_id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        definition:
          $ref: "#/components/schemas/QualityMasterDefinition"
        definition_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        actor_id:
          type: string
          format: uuid
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - master_id
        - version
        - definition
        - definition_hash
        - actor_id
        - reason
        - created_at
    QualityMasterDetail:
      type: object
      additionalProperties: false
      properties:
        master:
          $ref: "#/components/schemas/QualityMaster"
        versions:
          type: array
          items:
            $ref: "#/components/schemas/QualityMasterVersion"
          maxItems: 10000
          minItems: 0
      required:
        - master
        - versions
    QualityMastersPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/QualityMasterPublication"
          maxItems: 100
          minItems: 0
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    QualityMasterQuery:
      type: object
      additionalProperties: false
      properties:
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
        kind:
          type: string
          enum:
            - product
            - material
            - batch
            - process
      required: []
    QualityMasterCreate:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          enum:
            - product
            - material
            - batch
            - process
        site_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        department_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        definition:
          $ref: "#/components/schemas/QualityMasterDefinition"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - kind
        - site_id
        - department_id
        - definition
        - reason
    QualityMasterRevise:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        definition:
          $ref: "#/components/schemas/QualityMasterDefinition"
      required:
        - id
        - expected_version
        - reason
        - definition
    QualityModelDefinition:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 2
          maxLength: 120
        method:
          type: string
          enum:
            - matrix
            - fmea
            - hazard_analysis
        severity_max:
          type: integer
          minimum: 2
          maximum: 10
        probability_max:
          type: integer
          minimum: 2
          maximum: 10
        detection_max:
          type: integer
          minimum: 1
          maximum: 10
        tiers:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              label:
                type: string
                minLength: 2
                maxLength: 50
              max_score:
                type: integer
                minimum: 1
                maximum: 1000
              acceptance_required:
                type: boolean
            required:
              - label
              - max_score
              - acceptance_required
          maxItems: 5
          minItems: 2
      required:
        - name
        - method
        - severity_max
        - probability_max
        - detection_max
        - tiers
    QualityRiskModel:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        family_id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        definition:
          $ref: "#/components/schemas/QualityModelDefinition"
        definition_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        published_by:
          type: string
          format: uuid
        published_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - family_id
        - version
        - definition
        - definition_hash
        - published_by
        - published_at
    QualityModelsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/QualityRiskModel"
          maxItems: 100
          minItems: 0
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    QualityModelCreate:
      type: object
      additionalProperties: false
      properties:
        family_id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 0
        definition:
          $ref: "#/components/schemas/QualityModelDefinition"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - expected_version
        - definition
        - reason
    QualityRiskData:
      type: object
      additionalProperties: false
      properties:
        model_id:
          type: string
          format: uuid
        hazards:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
                minLength: 1
                maxLength: 40
              hazard:
                type: string
                minLength: 3
                maxLength: 1000
              controls:
                type: string
                minLength: 0
                maxLength: 1000
              mitigation:
                type: string
                minLength: 0
                maxLength: 1000
              initial_severity:
                type: integer
                minimum: 1
                maximum: 10
              initial_probability:
                type: integer
                minimum: 1
                maximum: 10
              initial_detection:
                type: integer
                minimum: 1
                maximum: 10
              residual_severity:
                type: integer
                minimum: 1
                maximum: 10
              residual_probability:
                type: integer
                minimum: 1
                maximum: 10
              residual_detection:
                type: integer
                minimum: 1
                maximum: 10
            required:
              - id
              - hazard
              - controls
              - mitigation
              - initial_severity
              - initial_probability
              - initial_detection
              - residual_severity
              - residual_probability
              - residual_detection
          maxItems: 30
          minItems: 0
        acceptance_rationale:
          type: string
          minLength: 0
          maxLength: 2000
        review_on:
          type: string
          format: date
      required:
        - model_id
        - hazards
        - acceptance_rationale
        - review_on
    QualityDeviationData:
      type: object
      additionalProperties: false
      properties:
        event_at:
          type: string
          format: date-time
        discovered_at:
          type: string
          format: date-time
        containment:
          type: string
          minLength: 0
          maxLength: 2000
        severity:
          type: string
          enum:
            - minor
            - major
            - critical
        repeat_review:
          type: string
          minLength: 0
          maxLength: 2000
        investigation:
          type: string
          minLength: 0
          maxLength: 2000
        root_cause_method:
          type: string
          enum:
            - five_why
            - fishbone
            - human_factors
        root_cause:
          type: string
          minLength: 0
          maxLength: 2000
        root_cause_category:
          type: string
          enum:
            - equipment
            - material
            - method
            - environment
            - personnel
            - undetermined
        impact:
          type: string
          minLength: 0
          maxLength: 2000
        batch_disposition:
          type: string
          minLength: 0
          maxLength: 2000
        capa_required:
          type: boolean
        capa_rationale:
          type: string
          minLength: 0
          maxLength: 2000
      required:
        - event_at
        - discovered_at
        - containment
        - severity
        - repeat_review
        - investigation
        - root_cause_method
        - root_cause
        - root_cause_category
        - impact
        - batch_disposition
        - capa_required
        - capa_rationale
    QualityCapaData:
      type: object
      additionalProperties: false
      properties:
        source:
          type: string
          enum:
            - deviation
            - audit
            - complaint
            - oos
            - risk
            - supplier
            - management
            - standalone
        problem:
          type: string
          minLength: 0
          maxLength: 2000
        root_cause:
          type: string
          minLength: 0
          maxLength: 2000
        priority:
          type: string
          enum:
            - low
            - medium
            - high
            - critical
        effectiveness_plan:
          type: string
          minLength: 0
          maxLength: 2000
        effectiveness_criteria:
          type: string
          minLength: 0
          maxLength: 2000
        effectiveness_due_at:
          type: string
          format: date-time
        verifier_id:
          type: string
          format: uuid
      required:
        - source
        - problem
        - root_cause
        - priority
        - effectiveness_plan
        - effectiveness_criteria
        - effectiveness_due_at
        - verifier_id
    QualityChangeData:
      type: object
      additionalProperties: false
      properties:
        current_state:
          type: string
          minLength: 0
          maxLength: 2000
        proposed_state:
          type: string
          minLength: 0
          maxLength: 2000
        justification:
          type: string
          minLength: 0
          maxLength: 2000
        change_type:
          type: string
          enum:
            - temporary
            - permanent
            - emergency
        emergency_justification:
          type: string
          minLength: 0
          maxLength: 2000
        impacts:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              domain:
                type: string
                enum:
                  - regulatory
                  - validation
                  - training
                  - document
                  - stability
                  - supplier
                  - inventory_batch
                  - csv
              assessment:
                type: string
                minLength: 0
                maxLength: 1000
              required:
                type: boolean
            required:
              - domain
              - assessment
              - required
          maxItems: 8
          minItems: 8
        effective_at:
          type: string
          format: date-time
        expires_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        verification_plan:
          type: string
          minLength: 0
          maxLength: 2000
        verifier_id:
          type: string
          format: uuid
      required:
        - current_state
        - proposed_state
        - justification
        - change_type
        - emergency_justification
        - impacts
        - effective_at
        - expires_at
        - verification_plan
        - verifier_id
    QualityCaseData:
      type: object
      additionalProperties: false
      properties:
        title:
          type: string
          minLength: 2
          maxLength: 200
        description:
          type: string
          minLength: 3
          maxLength: 3000
        master_version_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 30
          minItems: 0
        reference_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 30
          minItems: 0
        required_dependencies:
          type: array
          items:
            type: string
            enum:
              - risk
              - capa
              - change
              - document
              - training
              - validation
              - regulatory
          maxItems: 7
          minItems: 0
        details:
          anyOf:
            - $ref: "#/components/schemas/QualityRiskData"
            - $ref: "#/components/schemas/QualityDeviationData"
            - $ref: "#/components/schemas/QualityCapaData"
            - $ref: "#/components/schemas/QualityChangeData"
      required:
        - title
        - description
        - master_version_ids
        - reference_ids
        - required_dependencies
        - details
    QualityCaseCreate:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          enum:
            - risk
            - deviation
            - capa
            - change
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        owner_id:
          type: string
          format: uuid
        due_at:
          type: string
          format: date-time
        data:
          $ref: "#/components/schemas/QualityCaseData"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
      required:
        - kind
        - site_id
        - department_id
        - owner_id
        - due_at
        - data
        - reason
    QualityCaseUpdate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        data:
          $ref: "#/components/schemas/QualityCaseData"
      required:
        - id
        - expected_version
        - reason
        - data
    QualityCase:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        kind:
          type: string
          enum:
            - risk
            - deviation
            - capa
            - change
        record_id:
          type: string
          format: uuid
        number:
          type: string
          minLength: 1
          maxLength: 60
        state:
          type: string
          enum:
            - draft
            - triage
            - investigation
            - assessment
            - planning
            - authorization
            - implementation
            - effectiveness
            - verification
            - qa_review
            - closed
        data:
          $ref: "#/components/schemas/QualityCaseData"
        owner_id:
          type: string
          format: uuid
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        due_at:
          type: string
          format: date-time
        version:
          type: integer
          minimum: 1
        authorization_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        closure_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        closed_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        overdue_notified_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        review_notified_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        expiry_notified_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
      required:
        - id
        - tenant_id
        - kind
        - record_id
        - number
        - state
        - data
        - owner_id
        - site_id
        - department_id
        - due_at
        - version
        - authorization_id
        - closure_id
        - closed_at
        - created_by
        - created_at
        - updated_at
    QualityCasesPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/QualityCase"
          maxItems: 100
          minItems: 0
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    QualityCasesQuery:
      type: object
      additionalProperties: false
      properties:
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
        kind:
          type: string
          enum:
            - risk
            - deviation
            - capa
            - change
        state:
          type: string
          enum:
            - draft
            - triage
            - investigation
            - assessment
            - planning
            - authorization
            - implementation
            - effectiveness
            - verification
            - qa_review
            - closed
        search:
          type: string
          minLength: 1
          maxLength: 120
      required: []
    QualityAction:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        case_id:
          type: string
          format: uuid
        kind:
          type: string
          enum:
            - correction
            - corrective
            - preventive
            - mitigation
            - implementation
            - validation
            - regulatory
            - disposition
        title:
          type: string
          minLength: 3
          maxLength: 500
        assignee_id:
          type: string
          format: uuid
        verifier_id:
          type: string
          format: uuid
        due_at:
          type: string
          format: date-time
        status:
          type: string
          enum:
            - assigned
            - completed
            - verified
        result:
          anyOf:
            - type: string
              minLength: 3
              maxLength: 3000
            - type: "null"
        attachment_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 20
          minItems: 0
        signature_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        completed_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        verified_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        version:
          type: integer
          minimum: 1
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - case_id
        - kind
        - title
        - assignee_id
        - verifier_id
        - due_at
        - status
        - result
        - attachment_ids
        - signature_id
        - completed_at
        - verified_at
        - version
        - created_by
        - created_at
    QualityActionCreate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        kind:
          type: string
          enum:
            - correction
            - corrective
            - preventive
            - mitigation
            - implementation
            - validation
            - regulatory
            - disposition
        title:
          type: string
          minLength: 3
          maxLength: 500
        assignee_id:
          type: string
          format: uuid
        verifier_id:
          type: string
          format: uuid
        due_at:
          type: string
          format: date-time
      required:
        - id
        - expected_version
        - reason
        - kind
        - title
        - assignee_id
        - verifier_id
        - due_at
    QualityActionComplete:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        result:
          type: string
          minLength: 3
          maxLength: 3000
        attachment_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 20
          minItems: 1
      required:
        - id
        - expected_version
        - reason
        - result
        - attachment_ids
    QualityVerify:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        password:
          type: string
          minLength: 8
          maxLength: 128
        mfa_code:
          type: string
          pattern: ^[0-9]{6}$
        consent:
          const: true
          type: boolean
      required:
        - id
        - expected_version
        - reason
        - password
        - consent
    QualityEvaluate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        password:
          type: string
          minLength: 8
          maxLength: 128
        mfa_code:
          type: string
          pattern: ^[0-9]{6}$
        consent:
          const: true
          type: boolean
        passed:
          type: boolean
        result:
          type: string
          minLength: 3
          maxLength: 3000
      required:
        - id
        - expected_version
        - reason
        - password
        - consent
        - passed
        - result
    QualityDependency:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        case_id:
          type: string
          format: uuid
        target_record_id:
          type: string
          format: uuid
        link_id:
          type: string
          format: uuid
        required:
          type: boolean
        retired_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - case_id
        - target_record_id
        - link_id
        - required
        - retired_at
        - created_by
        - created_at
    QualityDependencyCreate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        target_record_id:
          type: string
          format: uuid
        required:
          type: boolean
      required:
        - id
        - expected_version
        - reason
        - target_record_id
        - required
    QualityDependencyRetire:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        target_record_id:
          type: string
          format: uuid
      required:
        - id
        - expected_version
        - reason
        - target_record_id
    QualityEvaluation:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        case_id:
          type: string
          format: uuid
        kind:
          type: string
          enum:
            - effectiveness
            - verification
        passed:
          type: boolean
        result:
          type: string
          minLength: 3
          maxLength: 3000
        fingerprint:
          type: string
          pattern: ^[a-f0-9]{64}$
        actor_id:
          type: string
          format: uuid
        signature_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - case_id
        - kind
        - passed
        - result
        - fingerprint
        - actor_id
        - signature_id
        - created_at
    QualityScore:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          minLength: 1
          maxLength: 40
        initial_score:
          type: integer
          minimum: 1
        residual_score:
          type: integer
          minimum: 1
        tier:
          type: string
          minLength: 2
          maxLength: 50
        acceptance_required:
          type: boolean
      required:
        - id
        - initial_score
        - residual_score
        - tier
        - acceptance_required
    QualitySnapshot:
      type: object
      additionalProperties: false
      properties:
        case:
          $ref: "#/components/schemas/QualityCase"
        actions:
          type: array
          items:
            $ref: "#/components/schemas/QualityAction"
          maxItems: 10000
          minItems: 0
        dependencies:
          type: array
          items:
            $ref: "#/components/schemas/QualityDependency"
          maxItems: 10000
          minItems: 0
        scores:
          type: array
          items:
            $ref: "#/components/schemas/QualityScore"
          maxItems: 30
          minItems: 0
        evaluations:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
                format: uuid
              tenant_id:
                type: string
                format: uuid
              case_id:
                type: string
                format: uuid
              kind:
                type: string
                enum:
                  - effectiveness
                  - verification
              passed:
                type: boolean
              result:
                type: string
                minLength: 3
                maxLength: 3000
              fingerprint:
                type: string
                pattern: ^[a-f0-9]{64}$
              actor_id:
                type: string
                format: uuid
              created_at:
                type: string
                format: date-time
            required:
              - id
              - tenant_id
              - case_id
              - kind
              - passed
              - result
              - fingerprint
              - actor_id
              - created_at
          maxItems: 10000
          minItems: 0
      required:
        - case
        - actions
        - dependencies
        - scores
        - evaluations
    QualityCaseVersion:
      type: object
      additionalProperties: false
      properties:
        tenant_id:
          type: string
          format: uuid
        case_id:
          type: string
          format: uuid
        version:
          type: integer
          minimum: 1
        record_version:
          type: integer
          minimum: 1
        snapshot:
          $ref: "#/components/schemas/QualitySnapshot"
        data_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        record_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        actor_id:
          type: string
          format: uuid
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        created_at:
          type: string
          format: date-time
      required:
        - tenant_id
        - case_id
        - version
        - record_version
        - snapshot
        - data_hash
        - record_hash
        - actor_id
        - reason
        - created_at
    QualityApprovalRequest:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
        stage:
          type: string
          enum:
            - triage
            - authorization
            - closure
            - extension
        workflow_template_id:
          type: string
          format: uuid
        due_at:
          type: string
          format: date-time
        action_id:
          type: string
          format: uuid
      required:
        - id
        - expected_version
        - reason
        - stage
        - workflow_template_id
    QualityApproval:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        case_id:
          type: string
          format: uuid
        stage:
          type: string
          enum:
            - triage
            - authorization
            - closure
            - extension
        record_id:
          type: string
          format: uuid
        workflow_template_id:
          type: string
          format: uuid
        case_version:
          type: integer
          minimum: 1
        fingerprint:
          type: string
          pattern: ^[a-f0-9]{64}$
        payload:
          type: object
          additionalProperties: false
          properties:
            due_at:
              anyOf:
                - type: string
                  format: date-time
                - type: "null"
            action_id:
              anyOf:
                - type: string
                  format: uuid
                - type: "null"
          required:
            - due_at
            - action_id
        applied_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        workflow:
          anyOf:
            - $ref: "#/components/schemas/WorkflowInstance"
            - type: "null"
      required:
        - id
        - tenant_id
        - case_id
        - stage
        - record_id
        - workflow_template_id
        - case_version
        - fingerprint
        - payload
        - applied_at
        - created_by
        - created_at
        - workflow
    QualityDetail:
      type: object
      additionalProperties: false
      properties:
        case:
          $ref: "#/components/schemas/QualityCase"
        actions:
          type: array
          items:
            $ref: "#/components/schemas/QualityAction"
          maxItems: 10000
          minItems: 0
        dependencies:
          type: array
          items:
            $ref: "#/components/schemas/QualityDependency"
          maxItems: 10000
          minItems: 0
        scores:
          type: array
          items:
            $ref: "#/components/schemas/QualityScore"
          maxItems: 30
          minItems: 0
        evaluations:
          type: array
          items:
            $ref: "#/components/schemas/QualityEvaluation"
          maxItems: 10000
          minItems: 0
        record:
          $ref: "#/components/schemas/IntegrityRecord"
        versions:
          type: array
          items:
            $ref: "#/components/schemas/QualityCaseVersion"
          maxItems: 10000
          minItems: 0
        approvals:
          type: array
          items:
            $ref: "#/components/schemas/QualityApproval"
          maxItems: 10000
          minItems: 0
        links:
          type: array
          items:
            $ref: "#/components/schemas/IntegrityLink"
          maxItems: 10000
          minItems: 0
        master_references:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              publication_id:
                type: string
                format: uuid
              kind:
                type: string
                enum:
                  - product
                  - material
                  - batch
                  - process
              code:
                type: string
                pattern: ^[A-Z0-9][A-Z0-9._-]{0,49}$
              name:
                type: string
                minLength: 2
                maxLength: 200
              version:
                type: integer
                minimum: 1
            required:
              - publication_id
              - kind
              - code
              - name
              - version
          maxItems: 30
          minItems: 0
        dependency_status:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
                format: uuid
              title:
                anyOf:
                  - type: string
                    minLength: 2
                    maxLength: 200
                  - type: "null"
              complete:
                anyOf:
                  - type: boolean
                  - type: "null"
            required:
              - id
              - title
              - complete
          maxItems: 10000
          minItems: 0
        linked_records:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
                format: uuid
              title:
                type: string
                minLength: 2
                maxLength: 200
              case_id:
                anyOf:
                  - type: string
                    format: uuid
                  - type: "null"
            required:
              - id
              - title
              - case_id
          maxItems: 10000
          minItems: 0
      required:
        - case
        - actions
        - dependencies
        - scores
        - evaluations
        - record
        - versions
        - approvals
        - links
        - master_references
        - dependency_status
        - linked_records
    QualityChoicesQuery:
      type: object
      additionalProperties: false
      properties:
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
        kind:
          type: string
          enum:
            - site
            - department
            - person
            - workflow
            - reference
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        category:
          type: string
          minLength: 1
          maxLength: 100
      required:
        - kind
    QualitySearchQuery:
      type: object
      additionalProperties: false
      properties:
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
        search:
          type: string
          minLength: 2
          maxLength: 120
      required:
        - search
    QualitySearchItem:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        number:
          type: string
          minLength: 1
          maxLength: 60
        title:
          type: string
          minLength: 2
          maxLength: 200
        status:
          type: string
          enum:
            - draft
            - signed
            - cancelled
            - archived
        created_at:
          type: string
          format: date-time
        category:
          type: string
          minLength: 1
          maxLength: 150
        case_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - id
        - number
        - title
        - status
        - created_at
        - category
        - case_id
    QualitySearchPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/QualitySearchItem"
          maxItems: 100
          minItems: 0
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    QualityDashboard:
      type: object
      additionalProperties: false
      properties:
        open:
          type: integer
          minimum: 0
        overdue:
          type: integer
          minimum: 0
        closed:
          type: integer
          minimum: 0
        awaiting_effectiveness:
          type: integer
          minimum: 0
        risk_reviews_due:
          type: integer
          minimum: 0
        temporary_changes_expired:
          type: integer
          minimum: 0
        failed_evaluations:
          type: integer
          minimum: 0
        monthly:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              month:
                type: string
                pattern: ^\d{4}-\d{2}$
              kind:
                type: string
                enum:
                  - risk
                  - deviation
                  - capa
                  - change
              cases:
                type: integer
                minimum: 0
              closed:
                type: integer
                minimum: 0
            required:
              - month
              - kind
              - cases
              - closed
          maxItems: 48
          minItems: 0
        root_causes:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              category:
                type: string
                enum:
                  - equipment
                  - material
                  - method
                  - environment
                  - personnel
                  - undetermined
              cases:
                type: integer
                minimum: 0
            required:
              - category
              - cases
          maxItems: 6
          minItems: 0
      required:
        - open
        - overdue
        - closed
        - awaiting_effectiveness
        - risk_reviews_due
        - temporary_changes_expired
        - failed_evaluations
        - monthly
        - root_causes
    QualityInspection:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        filename:
          type: string
          minLength: 1
          maxLength: 100
        generated_at:
          type: string
          format: date-time
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        size_bytes:
          type: integer
          minimum: 1
          maximum: 50331648
        content_base64:
          type: string
          minLength: 1
          maxLength: 67108864
      required:
        - id
        - filename
        - generated_at
        - sha256
        - size_bytes
        - content_base64
    QcLaboratory:
      type: object
      additionalProperties: false
      properties:
        kind:
          const: laboratory
          type: string
        location:
          type: string
          minLength: 1
          maxLength: 300
          pattern: \S
        accreditation:
          type: string
          minLength: 0
          maxLength: 300
      required:
        - kind
        - location
        - accreditation
    QcMethod:
      type: object
      additionalProperties: false
      properties:
        kind:
          const: method
          type: string
        laboratory_id:
          type: string
          format: uuid
        revision:
          type: string
          minLength: 1
          maxLength: 50
          pattern: \S
        procedure:
          type: string
          minLength: 3
          maxLength: 4000
          pattern: \S
        document_revision_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - kind
        - laboratory_id
        - revision
        - procedure
        - document_revision_id
    QcSpecification:
      type: object
      additionalProperties: false
      properties:
        kind:
          const: specification
          type: string
        method_id:
          type: string
          format: uuid
        revision:
          type: string
          minLength: 1
          maxLength: 50
          pattern: \S
        test:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        unit:
          type: string
          minLength: 1
          maxLength: 50
          pattern: \S
        lower:
          anyOf:
            - type: number
              minimum: -1000000000000
              maximum: 1000000000000
            - type: "null"
        upper:
          anyOf:
            - type: number
              minimum: -1000000000000
              maximum: 1000000000000
            - type: "null"
      required:
        - kind
        - method_id
        - revision
        - test
        - unit
        - lower
        - upper
    QcEquipment:
      type: object
      additionalProperties: false
      properties:
        kind:
          const: equipment
          type: string
        laboratory_id:
          type: string
          format: uuid
        manufacturer:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        model:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        serial:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        location:
          type: string
          minLength: 1
          maxLength: 300
          pattern: \S
        service_vendor:
          type: string
          minLength: 0
          maxLength: 200
        calibration_days:
          type: integer
          minimum: 1
          maximum: 3650
        maintenance_days:
          type: integer
          minimum: 1
          maximum: 3650
      required:
        - kind
        - laboratory_id
        - manufacturer
        - model
        - serial
        - location
        - service_vendor
        - calibration_days
        - maintenance_days
    QcInvestigation:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          enum:
            - oos
            - oot
        batch_version_id:
          type: string
          format: uuid
        specification_id:
          type: string
          format: uuid
        method_id:
          type: string
          format: uuid
        equipment_id:
          type: string
          format: uuid
        analyst_id:
          type: string
          format: uuid
        result:
          type: number
          minimum: -1000000000000
          maximum: 1000000000000
        observed_at:
          type: string
          format: date-time
        oot_rationale:
          type: string
          minLength: 0
          maxLength: 2000
        due_at:
          type: string
          format: date-time
      required:
        - kind
        - batch_version_id
        - specification_id
        - method_id
        - equipment_id
        - analyst_id
        - result
        - observed_at
        - oot_rationale
        - due_at
    QcDefinition:
      oneOf:
        - $ref: "#/components/schemas/QcLaboratory"
        - $ref: "#/components/schemas/QcMethod"
        - $ref: "#/components/schemas/QcSpecification"
        - $ref: "#/components/schemas/QcEquipment"
        - $ref: "#/components/schemas/QcInvestigation"
    QcCreate:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          enum:
            - laboratory
            - method
            - specification
            - equipment
            - oos
            - oot
        code:
          type: string
          pattern: ^[A-Z0-9][A-Z0-9._-]{0,49}$
        title:
          type: string
          minLength: 3
          maxLength: 180
          pattern: \S
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        owner_id:
          type: string
          format: uuid
        family_id:
          type: string
          format: uuid
        expected_publication:
          type: integer
          minimum: 0
        source_system:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
              pattern: \S
            - type: "null"
        external_id:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 200
              pattern: \S
            - type: "null"
        source_revision:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
              pattern: \S
            - type: "null"
        definition:
          $ref: "#/components/schemas/QcDefinition"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
      required:
        - kind
        - code
        - title
        - site_id
        - department_id
        - owner_id
        - expected_publication
        - source_system
        - external_id
        - source_revision
        - definition
        - reason
    QcPhaseI:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: phase_i
        calculation_review:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        sample_preparation_review:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        system_suitability_review:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        hypothesis:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        conclusion:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        phase_ii_required:
          type: boolean
      required:
        - kind
        - calculation_review
        - sample_preparation_review
        - system_suitability_review
        - hypothesis
        - conclusion
        - phase_ii_required
    QcPhaseII:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: phase_ii
        manufacturing_review:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        root_cause:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        impact:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        batch_disposition:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        capa_record_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        capa_rationale:
          type: string
          minLength: 3
          maxLength: 2000
          pattern: \S
      required:
        - kind
        - manufacturing_review
        - root_cause
        - impact
        - batch_disposition
        - capa_record_id
        - capa_rationale
    QcResult:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: result
        authorization_id:
          type: string
          format: uuid
        value:
          type: number
          minimum: -1000000000000
          maximum: 1000000000000
        observed_at:
          type: string
          format: date-time
        sample_reference:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        assessment:
          type: string
          minLength: 3
          maxLength: 2000
          pattern: \S
      required:
        - kind
        - authorization_id
        - value
        - observed_at
        - sample_reference
        - assessment
    QcQualification:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: qualification
        passed:
          type: boolean
        protocol:
          type: string
          minLength: 3
          maxLength: 2000
          pattern: \S
        certificate_id:
          type: string
          format: uuid
      required:
        - kind
        - passed
        - protocol
        - certificate_id
    QcCalibration:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: calibration
        passed:
          type: boolean
        performed_at:
          type: string
          format: date-time
        next_due_at:
          type: string
          format: date-time
        as_found:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        as_left:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        certificate_id:
          type: string
          format: uuid
        affected_since:
          type: string
          format: date-time
      required:
        - kind
        - passed
        - performed_at
        - next_due_at
        - as_found
        - as_left
        - certificate_id
        - affected_since
    QcMaintenance:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: maintenance
        performed_at:
          type: string
          format: date-time
        next_due_at:
          type: string
          format: date-time
        service_reference:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        work:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        certificate_id:
          type: string
          format: uuid
      required:
        - kind
        - performed_at
        - next_due_at
        - service_reference
        - work
        - certificate_id
    QcImpact:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: impact
        calibration_event_id:
          type: string
          format: uuid
        assessment:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        batch_version_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 200
          minItems: 0
          uniqueItems: true
        test_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 200
          minItems: 0
          uniqueItems: true
        deviation_record_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        disposition:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
      required:
        - kind
        - calibration_event_id
        - assessment
        - batch_version_ids
        - test_ids
        - deviation_record_id
        - disposition
    QcRestriction:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: restriction
        assessment:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
      required:
        - kind
        - assessment
    QcRetirement:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: retirement
        assessment:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
      required:
        - kind
        - assessment
    QcEventData:
      oneOf:
        - $ref: "#/components/schemas/QcPhaseI"
        - $ref: "#/components/schemas/QcPhaseII"
        - $ref: "#/components/schemas/QcResult"
        - $ref: "#/components/schemas/QcQualification"
        - $ref: "#/components/schemas/QcCalibration"
        - $ref: "#/components/schemas/QcMaintenance"
        - $ref: "#/components/schemas/QcImpact"
        - $ref: "#/components/schemas/QcPlan"
        - $ref: "#/components/schemas/QcRestriction"
        - $ref: "#/components/schemas/QcRetirement"
    QcEventCreate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
        data:
          $ref: "#/components/schemas/QcEventData"
      required:
        - id
        - expected_version
        - reason
        - data
    QcApprovalPlan:
      type: object
      additionalProperties: false
      properties:
        assessment:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        sample_count:
          type: integer
          minimum: 0
          maximum: 20
        sampling_plan:
          type: string
          minLength: 0
          maxLength: 3000
        disposition:
          type: string
          enum:
            - pending
            - release
            - reject
            - invalidate
      required:
        - assessment
        - sample_count
        - sampling_plan
        - disposition
    QcApprovalRequest:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
        stage:
          type: string
          enum:
            - retest
            - resample
            - disposition
            - release
        workflow_template_id:
          type: string
          format: uuid
        plan:
          $ref: "#/components/schemas/QcApprovalPlan"
      required:
        - id
        - expected_version
        - reason
        - stage
        - workflow_template_id
        - plan
    QcObject:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        kind:
          type: string
          enum:
            - laboratory
            - method
            - specification
            - equipment
            - oos
            - oot
        code:
          type: string
          pattern: ^[A-Z0-9][A-Z0-9._-]{0,49}$
        title:
          type: string
          minLength: 3
          maxLength: 180
          pattern: \S
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        owner_id:
          type: string
          format: uuid
        family_id:
          type: string
          format: uuid
        publication:
          type: integer
          minimum: 1
        record_id:
          type: string
          format: uuid
        definition:
          $ref: "#/components/schemas/QcDefinition"
        definition_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        state:
          type: string
          enum:
            - published
            - registered
            - restricted
            - released
            - phase_i
            - phase_ii
            - closed
            - retired
        version:
          type: integer
          minimum: 1
        source_system:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
              pattern: \S
            - type: "null"
        external_id:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 200
              pattern: \S
            - type: "null"
        source_revision:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
              pattern: \S
            - type: "null"
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - kind
        - code
        - title
        - site_id
        - department_id
        - owner_id
        - family_id
        - publication
        - record_id
        - definition
        - definition_hash
        - state
        - version
        - source_system
        - external_id
        - source_revision
        - created_by
        - created_at
    QcEvent:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        object_id:
          type: string
          format: uuid
        sequence:
          type: integer
          minimum: 1
        data:
          $ref: "#/components/schemas/QcEventData"
        data_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        actor_id:
          type: string
          format: uuid
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - object_id
        - sequence
        - data
        - data_hash
        - actor_id
        - reason
        - created_at
    QcApproval:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        object_id:
          type: string
          format: uuid
        stage:
          type: string
          enum:
            - retest
            - resample
            - disposition
            - release
        record_id:
          type: string
          format: uuid
        workflow_template_id:
          type: string
          format: uuid
        object_version:
          type: integer
          minimum: 1
        fingerprint:
          type: string
          pattern: ^[a-f0-9]{64}$
        plan:
          $ref: "#/components/schemas/QcApprovalPlan"
        applied_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        workflow:
          anyOf:
            - $ref: "#/components/schemas/WorkflowInstance"
            - type: "null"
      required:
        - id
        - tenant_id
        - object_id
        - stage
        - record_id
        - workflow_template_id
        - object_version
        - fingerprint
        - plan
        - applied_at
        - created_by
        - created_at
        - workflow
    QcUseStatus:
      type: object
      additionalProperties: false
      properties:
        usable:
          type: boolean
        reasons:
          type: array
          items:
            type: string
            enum:
              - not_released
              - unqualified
              - calibration_due
              - maintenance_due
              - impact_pending
              - restricted
              - retired
          maxItems: 10
          minItems: 0
          uniqueItems: true
        calibration_due_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        maintenance_due_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
      required:
        - usable
        - reasons
        - calibration_due_at
        - maintenance_due_at
    QcDetail:
      type: object
      additionalProperties: false
      properties:
        object:
          $ref: "#/components/schemas/QcObject"
        events:
          type: array
          items:
            $ref: "#/components/schemas/QcEvent"
          maxItems: 10000
          minItems: 0
          uniqueItems: true
        approvals:
          type: array
          items:
            $ref: "#/components/schemas/QcApproval"
          maxItems: 10000
          minItems: 0
          uniqueItems: true
        record:
          $ref: "#/components/schemas/IntegrityRecord"
        use_status:
          anyOf:
            - $ref: "#/components/schemas/QcUseStatus"
            - type: "null"
        references:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
                format: uuid
              code:
                type: string
                minLength: 1
                maxLength: 50
                pattern: \S
              title:
                type: string
                minLength: 1
                maxLength: 200
                pattern: \S
              publication:
                type: integer
                minimum: 1
            required:
              - id
              - code
              - title
              - publication
          maxItems: 40
          minItems: 0
          uniqueItems: true
      required:
        - object
        - events
        - approvals
        - record
        - use_status
        - references
    QcPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/QcObject"
          maxItems: 100
          minItems: 0
          uniqueItems: true
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    QcListQuery:
      type: object
      additionalProperties: false
      properties:
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
        kind:
          type: string
          enum:
            - laboratory
            - method
            - specification
            - equipment
            - oos
            - oot
        search:
          type: string
          minLength: 1
          maxLength: 120
          pattern: \S
        due_only:
          type: boolean
      required: []
    QcReconcile:
      type: object
      additionalProperties: false
      properties:
        source_system:
          type: string
          minLength: 1
          maxLength: 100
          pattern: \S
        items:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              external_id:
                type: string
                minLength: 1
                maxLength: 200
                pattern: \S
              source_revision:
                type: string
                minLength: 1
                maxLength: 100
                pattern: \S
              definition_hash:
                type: string
                pattern: ^[a-f0-9]{64}$
            required:
              - external_id
              - source_revision
              - definition_hash
          maxItems: 100
          minItems: 1
          uniqueItems: true
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
      required:
        - source_system
        - items
        - reason
    QcReconciliation:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              external_id:
                type: string
                minLength: 1
                maxLength: 200
                pattern: \S
              status:
                type: string
                enum:
                  - matched
                  - missing
                  - mismatch
              id:
                anyOf:
                  - type: string
                    format: uuid
                  - type: "null"
            required:
              - external_id
              - status
              - id
          maxItems: 100
          minItems: 0
          uniqueItems: true
      required:
        - items
    QcPlan:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: plan
        calibration_days:
          type: integer
          minimum: 1
          maximum: 3650
        maintenance_days:
          type: integer
          minimum: 1
          maximum: 3650
        service_vendor:
          type: string
          minLength: 0
          maxLength: 200
        assessment:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
      required:
        - kind
        - calibration_days
        - maintenance_days
        - service_vendor
        - assessment
    OversightProgram:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: program
        year:
          type: integer
          minimum: 2020
          maximum: 2100
        scope:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        objectives:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
      required:
        - kind
        - year
        - scope
        - objectives
    OversightChecklist:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: checklist
        revision:
          type: string
          minLength: 1
          maxLength: 50
          pattern: \S
        questions:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
                pattern: ^[A-Z0-9][A-Z0-9._-]{0,49}$
              prompt:
                type: string
                minLength: 3
                maxLength: 1000
                pattern: \S
              required:
                type: boolean
            required:
              - id
              - prompt
              - required
          maxItems: 50
          minItems: 1
      required:
        - kind
        - revision
        - questions
    OversightQuestionnaire:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: questionnaire
        revision:
          type: string
          minLength: 1
          maxLength: 50
          pattern: \S
        questions:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
                pattern: ^[A-Z0-9][A-Z0-9._-]{0,49}$
              prompt:
                type: string
                minLength: 3
                maxLength: 1000
                pattern: \S
              required:
                type: boolean
            required:
              - id
              - prompt
              - required
          maxItems: 50
          minItems: 1
      required:
        - kind
        - revision
        - questions
    OversightSupplier:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: supplier
        legal_name:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        sites:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              name:
                type: string
                minLength: 1
                maxLength: 200
                pattern: \S
              address:
                type: string
                minLength: 1
                maxLength: 1000
                pattern: \S
              country:
                type: string
                pattern: ^[A-Z]{2}$
            required:
              - name
              - address
              - country
          maxItems: 20
          minItems: 1
        material_version_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 30
          minItems: 0
        services:
          type: string
          minLength: 0
          maxLength: 2000
        criticality:
          type: string
          enum:
            - low
            - medium
            - high
            - critical
        questionnaire_id:
          type: string
          format: uuid
        audit_required:
          type: boolean
        required_evidence:
          type: array
          items:
            type: string
            enum:
              - certificate
              - license
              - quality_agreement
          maxItems: 3
          minItems: 1
        requalification_days:
          type: integer
          minimum: 1
          maximum: 1825
      required:
        - kind
        - legal_name
        - sites
        - material_version_ids
        - services
        - criticality
        - questionnaire_id
        - audit_required
        - required_evidence
        - requalification_days
    OversightAudit:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: audit
        program_id:
          type: string
          format: uuid
        checklist_id:
          type: string
          format: uuid
        supplier_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        audit_type:
          type: string
          enum:
            - internal
            - supplier
            - mock_inspection
            - corporate
            - external_inspection
        scope:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        scheduled_start:
          type: string
          format: date-time
        scheduled_end:
          type: string
          format: date-time
        auditor_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 20
          minItems: 1
        auditee_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 20
          minItems: 1
      required:
        - kind
        - program_id
        - checklist_id
        - supplier_id
        - audit_type
        - scope
        - scheduled_start
        - scheduled_end
        - auditor_ids
        - auditee_ids
    OversightComplaint:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: complaint
        product_version_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 30
          minItems: 1
        batch_version_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 30
          minItems: 0
        customer_reference:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        country:
          type: string
          pattern: ^[A-Z]{2}$
        received_at:
          type: string
          format: date-time
        description:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        safety_flag:
          type: boolean
        regulatory_reporting_required:
          type: boolean
      required:
        - kind
        - product_version_ids
        - batch_version_ids
        - customer_reference
        - country
        - received_at
        - description
        - safety_flag
        - regulatory_reporting_required
    OversightDefinition:
      oneOf:
        - $ref: "#/components/schemas/OversightProgram"
        - $ref: "#/components/schemas/OversightChecklist"
        - $ref: "#/components/schemas/OversightQuestionnaire"
        - $ref: "#/components/schemas/OversightSupplier"
        - $ref: "#/components/schemas/OversightAudit"
        - $ref: "#/components/schemas/OversightComplaint"
    OversightCreate:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          enum:
            - program
            - checklist
            - questionnaire
            - supplier
            - audit
            - complaint
        code:
          type: string
          pattern: ^[A-Z0-9][A-Z0-9._-]{0,49}$
        title:
          type: string
          minLength: 3
          maxLength: 180
          pattern: \S
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        owner_id:
          type: string
          format: uuid
        due_at:
          type: string
          format: date-time
        family_id:
          type: string
          format: uuid
        expected_publication:
          type: integer
          minimum: 0
        source_system:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
              pattern: \S
            - type: "null"
        external_id:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 200
              pattern: \S
            - type: "null"
        source_revision:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
              pattern: \S
            - type: "null"
        definition:
          $ref: "#/components/schemas/OversightDefinition"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
      required:
        - kind
        - code
        - title
        - site_id
        - department_id
        - owner_id
        - due_at
        - expected_publication
        - source_system
        - external_id
        - source_revision
        - definition
        - reason
    OversightAnswers:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: answers
        publication_id:
          type: string
          format: uuid
        answers:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              question_id:
                type: string
                pattern: ^[A-Z0-9][A-Z0-9._-]{0,49}$
              answer:
                type: string
                minLength: 3
                maxLength: 2000
                pattern: \S
              evidence_ids:
                type: array
                items:
                  type: string
                  format: uuid
                maxItems: 10
                minItems: 0
            required:
              - question_id
              - answer
              - evidence_ids
          maxItems: 50
          minItems: 1
      required:
        - kind
        - publication_id
        - answers
    OversightMeeting:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: meeting
        meeting:
          type: string
          enum:
            - opening
            - closing
        held_at:
          type: string
          format: date-time
        attendees:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 30
          minItems: 1
        minutes:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
      required:
        - kind
        - meeting
        - held_at
        - attendees
        - minutes
    OversightSupplierEvidence:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: supplier_evidence
        evidence_kind:
          type: string
          enum:
            - certificate
            - license
            - quality_agreement
        attachment_id:
          type: string
          format: uuid
        expires_at:
          type: string
          format: date-time
        reference:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
      required:
        - kind
        - evidence_kind
        - attachment_id
        - expires_at
        - reference
    OversightScorecard:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: scorecard
        period:
          type: string
          minLength: 1
          maxLength: 50
          pattern: \S
        quality:
          type: integer
          minimum: 0
          maximum: 100
        delivery:
          type: integer
          minimum: 0
          maximum: 100
        responsiveness:
          type: integer
          minimum: 0
          maximum: 100
        assessment:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
      required:
        - kind
        - period
        - quality
        - delivery
        - responsiveness
        - assessment
    OversightRestriction:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: restriction
        status:
          type: string
          enum:
            - suspended
            - disqualified
        assessment:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
      required:
        - kind
        - status
        - assessment
    OversightRequalification:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: requalification
        assessment:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
      required:
        - kind
        - assessment
    OversightAssessment:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: assessment
        assessment:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        risk:
          type: string
          enum:
            - low
            - medium
            - high
            - critical
        regulatory_reference:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 200
              pattern: \S
            - type: "null"
      required:
        - kind
        - assessment
        - risk
        - regulatory_reference
    OversightSample:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: sample
        status:
          type: string
          enum:
            - requested
            - received
            - analyzed
        sample_reference:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        observed_at:
          type: string
          format: date-time
        assessment:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        attachment_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 20
          minItems: 0
      required:
        - kind
        - status
        - sample_reference
        - observed_at
        - assessment
        - attachment_ids
    OversightInvestigation:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: investigation
        investigation:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        root_cause:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        batch_review:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        impact:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        capa_record_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        capa_rationale:
          type: string
          minLength: 3
          maxLength: 2000
          pattern: \S
      required:
        - kind
        - investigation
        - root_cause
        - batch_review
        - impact
        - capa_record_id
        - capa_rationale
    OversightResponse:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: response
        response:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        sent_at:
          type: string
          format: date-time
        attachment_id:
          type: string
          format: uuid
      required:
        - kind
        - response
        - sent_at
        - attachment_id
    OversightEscalation:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          const: safety_escalation
        assessment:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
      required:
        - kind
        - assessment
    OversightEventData:
      oneOf:
        - $ref: "#/components/schemas/OversightAnswers"
        - $ref: "#/components/schemas/OversightMeeting"
        - $ref: "#/components/schemas/OversightSupplierEvidence"
        - $ref: "#/components/schemas/OversightScorecard"
        - $ref: "#/components/schemas/OversightRestriction"
        - $ref: "#/components/schemas/OversightRequalification"
        - $ref: "#/components/schemas/OversightAssessment"
        - $ref: "#/components/schemas/OversightSample"
        - $ref: "#/components/schemas/OversightInvestigation"
        - $ref: "#/components/schemas/OversightResponse"
        - $ref: "#/components/schemas/OversightEscalation"
    OversightEventCreate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
        data:
          $ref: "#/components/schemas/OversightEventData"
      required:
        - id
        - expected_version
        - reason
        - data
    OversightFindingCreate:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
        question_id:
          anyOf:
            - type: string
              pattern: ^[A-Z0-9][A-Z0-9._-]{0,49}$
            - type: "null"
        classification:
          type: string
          enum:
            - minor
            - major
            - critical
            - observation
        observation:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        criterion:
          type: string
          minLength: 3
          maxLength: 2000
          pattern: \S
        assignee_id:
          type: string
          format: uuid
        due_at:
          type: string
          format: date-time
        repeat_finding_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        capa_required:
          type: boolean
      required:
        - id
        - expected_version
        - reason
        - question_id
        - classification
        - observation
        - criterion
        - assignee_id
        - due_at
        - repeat_finding_id
        - capa_required
    OversightFindingResponse:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
        response:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        attachment_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 20
          minItems: 1
        capa_record_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - id
        - expected_version
        - reason
        - response
        - attachment_ids
        - capa_record_id
    OversightFindingCapa:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
        details:
          $ref: "#/components/schemas/QualityCapaData"
      required:
        - id
        - expected_version
        - reason
        - details
    OversightApprovalRequest:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
        stage:
          type: string
          enum:
            - closure
            - qualification
        workflow_template_id:
          type: string
          format: uuid
        assessment:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        supplier_status:
          type: string
          enum:
            - approved
            - conditionally_approved
        conditions:
          type: string
          minLength: 0
          maxLength: 2000
        valid_until:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
      required:
        - id
        - expected_version
        - reason
        - stage
        - workflow_template_id
        - assessment
        - supplier_status
        - conditions
        - valid_until
    OversightReporter:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        contact:
          type: string
          minLength: 1
          maxLength: 1000
          pattern: \S
        organization:
          type: string
          minLength: 0
          maxLength: 200
        details:
          type: string
          minLength: 0
          maxLength: 3000
      required:
        - name
        - contact
        - organization
        - details
    OversightReporterInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        expected_version:
          type: integer
          minimum: 1
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
        reporter:
          $ref: "#/components/schemas/OversightReporter"
      required:
        - id
        - expected_version
        - reason
        - reporter
    OversightReporterVersion:
      type: object
      additionalProperties: false
      properties:
        version:
          type: integer
          minimum: 1
        reporter:
          $ref: "#/components/schemas/OversightReporter"
        actor_id:
          type: string
          format: uuid
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
        created_at:
          type: string
          format: date-time
      required:
        - version
        - reporter
        - actor_id
        - reason
        - created_at
    OversightReporterHistory:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/OversightReporterVersion"
          maxItems: 10000
          minItems: 0
      required:
        - items
    OversightObject:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        kind:
          type: string
          enum:
            - program
            - checklist
            - questionnaire
            - supplier
            - audit
            - complaint
        code:
          type: string
          pattern: ^[A-Z0-9][A-Z0-9._-]{0,49}$
        title:
          type: string
          minLength: 3
          maxLength: 180
          pattern: \S
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        owner_id:
          type: string
          format: uuid
        due_at:
          type: string
          format: date-time
        family_id:
          type: string
          format: uuid
        publication:
          type: integer
          minimum: 1
        record_id:
          type: string
          format: uuid
        definition:
          $ref: "#/components/schemas/OversightDefinition"
        definition_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        state:
          type: string
          enum:
            - published
            - planned
            - in_progress
            - prospective
            - qualification
            - approved
            - conditionally_approved
            - suspended
            - disqualified
            - open
            - closed
        version:
          type: integer
          minimum: 1
        valid_until:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        conditions:
          anyOf:
            - type: string
              minLength: 0
              maxLength: 2000
            - type: "null"
        source_system:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
              pattern: \S
            - type: "null"
        external_id:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 200
              pattern: \S
            - type: "null"
        source_revision:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
              pattern: \S
            - type: "null"
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - kind
        - code
        - title
        - site_id
        - department_id
        - owner_id
        - due_at
        - family_id
        - publication
        - record_id
        - definition
        - definition_hash
        - state
        - version
        - valid_until
        - conditions
        - source_system
        - external_id
        - source_revision
        - created_by
        - created_at
    OversightEvent:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        object_id:
          type: string
          format: uuid
        sequence:
          type: integer
          minimum: 1
        data:
          $ref: "#/components/schemas/OversightEventData"
        data_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        actor_id:
          type: string
          format: uuid
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - object_id
        - sequence
        - data
        - data_hash
        - actor_id
        - reason
        - created_at
    OversightFinding:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        object_id:
          type: string
          format: uuid
        question_id:
          anyOf:
            - type: string
              pattern: ^[A-Z0-9][A-Z0-9._-]{0,49}$
            - type: "null"
        classification:
          type: string
          enum:
            - minor
            - major
            - critical
            - observation
        observation:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        criterion:
          type: string
          minLength: 3
          maxLength: 2000
          pattern: \S
        assignee_id:
          type: string
          format: uuid
        due_at:
          type: string
          format: date-time
        repeat_finding_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        capa_required:
          type: boolean
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - object_id
        - question_id
        - classification
        - observation
        - criterion
        - assignee_id
        - due_at
        - repeat_finding_id
        - capa_required
        - created_by
        - created_at
    OversightFindingReply:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        finding_id:
          type: string
          format: uuid
        object_id:
          type: string
          format: uuid
        response:
          type: string
          minLength: 3
          maxLength: 3000
          pattern: \S
        attachment_ids:
          type: array
          items:
            type: string
            format: uuid
          maxItems: 20
          minItems: 0
        capa_record_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        actor_id:
          type: string
          format: uuid
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - finding_id
        - object_id
        - response
        - attachment_ids
        - capa_record_id
        - actor_id
        - reason
        - created_at
    OversightFindingCheck:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        finding_id:
          type: string
          format: uuid
        response_id:
          type: string
          format: uuid
        actor_id:
          type: string
          format: uuid
        signature_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - finding_id
        - response_id
        - actor_id
        - signature_id
        - reason
        - created_at
    OversightApproval:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        object_id:
          type: string
          format: uuid
        stage:
          type: string
          enum:
            - closure
            - qualification
        record_id:
          type: string
          format: uuid
        workflow_template_id:
          type: string
          format: uuid
        object_version:
          type: integer
          minimum: 1
        fingerprint:
          type: string
          pattern: ^[a-f0-9]{64}$
        plan:
          type: object
          additionalProperties: false
          properties:
            assessment:
              type: string
              minLength: 3
              maxLength: 3000
              pattern: \S
            supplier_status:
              type: string
              enum:
                - approved
                - conditionally_approved
            conditions:
              type: string
              minLength: 0
              maxLength: 2000
            valid_until:
              anyOf:
                - type: string
                  format: date-time
                - type: "null"
          required:
            - assessment
            - supplier_status
            - conditions
            - valid_until
        applied_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        workflow:
          anyOf:
            - $ref: "#/components/schemas/WorkflowInstance"
            - type: "null"
      required:
        - id
        - tenant_id
        - object_id
        - stage
        - record_id
        - workflow_template_id
        - object_version
        - fingerprint
        - plan
        - applied_at
        - created_by
        - created_at
        - workflow
    OversightEligibility:
      type: object
      additionalProperties: false
      properties:
        eligible:
          type: boolean
        reasons:
          type: array
          items:
            type: string
            enum:
              - not_qualified
              - suspended
              - disqualified
              - requalification_due
              - evidence_expired
              - audit_required
          maxItems: 10
          minItems: 0
        valid_until:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        score:
          anyOf:
            - type: number
              minimum: 0
              maximum: 100
            - type: "null"
      required:
        - eligible
        - reasons
        - valid_until
        - score
    OversightHandoff:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        object_id:
          type: string
          format: uuid
        status:
          type: string
          enum:
            - pending
            - leased
            - failed
            - acknowledged
        attempts:
          type: integer
          minimum: 0
        available_at:
          type: string
          format: date-time
        last_error:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
              pattern: \S
            - type: "null"
        external_id:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 200
              pattern: \S
            - type: "null"
        receipt_id:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 200
              pattern: \S
            - type: "null"
        acknowledged_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - object_id
        - status
        - attempts
        - available_at
        - last_error
        - external_id
        - receipt_id
        - acknowledged_at
        - created_at
    OversightAttempt:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        handoff_id:
          type: string
          format: uuid
        attempt:
          type: integer
          minimum: 1
        status:
          anyOf:
            - type: integer
              minimum: 100
              maximum: 599
            - type: "null"
        error:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 100
              pattern: \S
            - type: "null"
        acknowledged:
          type: boolean
        created_at:
          type: string
          format: date-time
      required:
        - id
        - handoff_id
        - attempt
        - status
        - error
        - acknowledged
        - created_at
    OversightDetail:
      type: object
      additionalProperties: false
      properties:
        object:
          $ref: "#/components/schemas/OversightObject"
        events:
          type: array
          items:
            $ref: "#/components/schemas/OversightEvent"
          maxItems: 10000
          minItems: 0
        findings:
          type: array
          items:
            $ref: "#/components/schemas/OversightFinding"
          maxItems: 10000
          minItems: 0
        responses:
          type: array
          items:
            $ref: "#/components/schemas/OversightFindingReply"
          maxItems: 10000
          minItems: 0
        verifications:
          type: array
          items:
            $ref: "#/components/schemas/OversightFindingCheck"
          maxItems: 10000
          minItems: 0
        approvals:
          type: array
          items:
            $ref: "#/components/schemas/OversightApproval"
          maxItems: 10000
          minItems: 0
        record:
          $ref: "#/components/schemas/IntegrityRecord"
        eligibility:
          anyOf:
            - $ref: "#/components/schemas/OversightEligibility"
            - type: "null"
        handoffs:
          type: array
          items:
            $ref: "#/components/schemas/OversightHandoff"
          maxItems: 10000
          minItems: 0
        handoff_attempts:
          type: array
          items:
            $ref: "#/components/schemas/OversightAttempt"
          maxItems: 10000
          minItems: 0
      required:
        - object
        - events
        - findings
        - responses
        - verifications
        - approvals
        - record
        - eligibility
        - handoffs
        - handoff_attempts
    OversightQuery:
      type: object
      additionalProperties: false
      properties:
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
        kind:
          type: string
          enum:
            - program
            - checklist
            - questionnaire
            - supplier
            - audit
            - complaint
        search:
          type: string
          minLength: 1
          maxLength: 120
          pattern: \S
        eligible_only:
          type: boolean
        due_only:
          type: boolean
      required: []
    OversightPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/OversightObject"
          maxItems: 100
          minItems: 0
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    OversightReportInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        include_reporter:
          type: boolean
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
      required:
        - id
        - include_reporter
        - reason
    OversightReport:
      type: object
      additionalProperties: false
      properties:
        generated_at:
          type: string
          format: date-time
        manifest:
          $ref: "#/components/schemas/OversightDetail"
        reporter:
          anyOf:
            - $ref: "#/components/schemas/OversightReporterHistory"
            - type: "null"
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
      required:
        - generated_at
        - manifest
        - reporter
        - sha256
    OversightDashboard:
      type: object
      additionalProperties: false
      properties:
        open_audits:
          type: integer
          minimum: 0
        overdue_findings:
          type: integer
          minimum: 0
        eligible_suppliers:
          type: integer
          minimum: 0
        open_complaints:
          type: integer
          minimum: 0
        unacknowledged_safety:
          type: integer
          minimum: 0
        complaint_trends:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              month:
                type: string
                pattern: ^\d{4}-\d{2}$
              country:
                type: string
                pattern: ^[A-Z]{2}$
              count:
                type: integer
                minimum: 0
            required:
              - month
              - country
              - count
          maxItems: 300
          minItems: 0
      required:
        - open_audits
        - overdue_findings
        - eligible_suppliers
        - open_complaints
        - unacknowledged_safety
        - complaint_trends
    AnalyticsFilter:
      type: object
      additionalProperties: false
      properties:
        from:
          type: string
          format: date-time
        to:
          type: string
          format: date-time
        modules:
          type: array
          items:
            type: string
            enum:
              - risk
              - deviation
              - capa
              - change
              - oos
              - oot
              - equipment
              - audit
              - supplier
              - complaint
              - training
              - document
              - form
              - integrity
          maxItems: 14
          minItems: 1
        site_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        department_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - from
        - to
        - modules
        - site_id
        - department_id
    AnalyticsKpi:
      type: object
      additionalProperties: false
      properties:
        kind:
          const: kpi
          type: string
        code:
          type: string
          pattern: ^[A-Z][A-Z0-9._-]{0,49}$
        label:
          type: string
          minLength: 1
          maxLength: 120
          pattern: \S
        effective_from:
          type: string
          format: date-time
        effective_until:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        closed_states:
          type: array
          items:
            type: string
            minLength: 1
            maxLength: 50
            pattern: \S
          maxItems: 20
          minItems: 1
      required:
        - kind
        - code
        - label
        - effective_from
        - effective_until
        - closed_states
    AnalyticsReportDefinition:
      type: object
      additionalProperties: false
      properties:
        kind:
          const: report
          type: string
        filters:
          $ref: "#/components/schemas/AnalyticsFilter"
        kpi_id:
          type: string
          format: uuid
      required:
        - kind
        - filters
        - kpi_id
    AnalyticsLayout:
      type: object
      additionalProperties: false
      properties:
        kind:
          const: layout
          type: string
        heading:
          type: string
          minLength: 1
          maxLength: 150
          pattern: \S
        footer:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        columns:
          type: array
          items:
            type: string
            enum:
              - number
              - title
              - module
              - state
              - created_at
              - due_at
              - closed_at
              - age_days
              - site_id
              - department_id
              - signals
          maxItems: 10
          minItems: 1
        orientation:
          type: string
          enum:
            - portrait
            - landscape
      required:
        - kind
        - heading
        - footer
        - columns
        - orientation
    AnalyticsDefinitionInput:
      type: object
      additionalProperties: false
      properties:
        name:
          type: string
          minLength: 3
          maxLength: 150
          pattern: \S
        family_id:
          type: string
          format: uuid
        expected_publication:
          type: integer
          minimum: 0
        definition:
          oneOf:
            - $ref: "#/components/schemas/AnalyticsKpi"
            - $ref: "#/components/schemas/AnalyticsReportDefinition"
            - $ref: "#/components/schemas/AnalyticsLayout"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
      required:
        - name
        - expected_publication
        - definition
        - reason
    AnalyticsDefinition:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        family_id:
          type: string
          format: uuid
        publication:
          type: integer
          minimum: 1
        kind:
          type: string
          enum:
            - kpi
            - report
            - layout
        name:
          type: string
          minLength: 1
          maxLength: 150
          pattern: \S
        definition:
          type: object
          additionalProperties: true
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - family_id
        - publication
        - kind
        - name
        - definition
        - sha256
        - created_by
        - created_at
    AnalyticsListQuery:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          enum:
            - kpi
            - report
            - layout
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
      required: []
    AnalyticsRecordsQuery:
      type: object
      additionalProperties: false
      properties:
        from:
          type: string
          format: date-time
        to:
          type: string
          format: date-time
        module:
          type: string
          enum:
            - risk
            - deviation
            - capa
            - change
            - oos
            - oot
            - equipment
            - audit
            - supplier
            - complaint
            - training
            - document
            - form
            - integrity
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
      required:
        - from
        - to
    AnalyticsRow:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        number:
          type: string
          minLength: 1
          maxLength: 100
          pattern: \S
        title:
          type: string
          minLength: 1
          maxLength: 200
          pattern: \S
        module:
          type: string
          enum:
            - risk
            - deviation
            - capa
            - change
            - oos
            - oot
            - equipment
            - audit
            - supplier
            - complaint
            - training
            - document
            - form
            - integrity
        state:
          type: string
          minLength: 1
          maxLength: 50
          pattern: \S
        site_id:
          type: string
          format: uuid
        department_id:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        due_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        closed_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        age_days:
          type: integer
          minimum: 0
        version:
          type: integer
          minimum: 1
        content_hash:
          type: string
          pattern: ^[a-f0-9]{64}$
        href:
          type: string
          minLength: 1
          maxLength: 300
          pattern: \S
        signals:
          type: object
          additionalProperties: true
      required:
        - id
        - number
        - title
        - module
        - state
        - site_id
        - department_id
        - created_at
        - due_at
        - closed_at
        - age_days
        - version
        - content_hash
        - href
        - signals
    AnalyticsSnapshotSummary:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        title:
          type: string
          minLength: 1
          maxLength: 180
          pattern: \S
        kind:
          type: string
          enum:
            - management
            - inspection
            - access
            - configuration
            - signatures
            - audit
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        retain_until:
          type: string
          format: date-time
        legal_hold:
          type: boolean
      required:
        - id
        - tenant_id
        - title
        - kind
        - sha256
        - created_by
        - created_at
        - retain_until
        - legal_hold
    AnalyticsSnapshot:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        title:
          type: string
          minLength: 1
          maxLength: 180
          pattern: \S
        kind:
          type: string
          enum:
            - management
            - inspection
            - access
            - configuration
            - signatures
            - audit
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
        retain_until:
          type: string
          format: date-time
        legal_hold:
          type: boolean
        payload:
          type: object
          additionalProperties: true
        signatures:
          type: array
          items:
            type: object
            additionalProperties: false
            properties:
              id:
                type: string
                format: uuid
              snapshot_id:
                type: string
                format: uuid
              signer_id:
                type: string
                format: uuid
              signer_name:
                type: string
                minLength: 1
                maxLength: 120
                pattern: \S
              sha256:
                type: string
                pattern: ^[a-f0-9]{64}$
              meaning:
                const: review
                type: string
              reason:
                type: string
                minLength: 3
                maxLength: 1000
                pattern: \S
              signed_at:
                type: string
                format: date-time
              authentication_method:
                type: string
                minLength: 1
                maxLength: 30
                pattern: \S
            required:
              - id
              - snapshot_id
              - signer_id
              - signer_name
              - sha256
              - meaning
              - reason
              - signed_at
              - authentication_method
          maxItems: 100
          minItems: 0
      required:
        - id
        - tenant_id
        - title
        - kind
        - sha256
        - created_by
        - created_at
        - retain_until
        - legal_hold
        - payload
        - signatures
    AnalyticsSnapshotInput:
      type: object
      additionalProperties: false
      properties:
        definition_id:
          type: string
          format: uuid
        title:
          type: string
          minLength: 3
          maxLength: 180
          pattern: \S
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
      required:
        - definition_id
        - title
        - reason
    AnalyticsInspectionInput:
      type: object
      additionalProperties: false
      properties:
        root_id:
          type: string
          format: uuid
        title:
          type: string
          minLength: 3
          maxLength: 180
          pattern: \S
        depth:
          type: integer
          minimum: 0
          maximum: 4
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
      required:
        - root_id
        - title
        - depth
        - reason
    AnalyticsReviewInput:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          enum:
            - access
            - configuration
            - signatures
            - audit
        from:
          type: string
          format: date-time
        to:
          type: string
          format: date-time
        title:
          type: string
          minLength: 3
          maxLength: 180
          pattern: \S
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
      required:
        - kind
        - from
        - to
        - title
        - reason
    AnalyticsSignInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        consent:
          type: boolean
          const: true
        password:
          type: string
          minLength: 1
          maxLength: 128
          pattern: \S
        mfa_code:
          type: string
          pattern: ^[0-9]{6}$
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
      required:
        - id
        - sha256
        - consent
        - password
        - reason
    AnalyticsRetentionInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        retain_until:
          type: string
          format: date-time
        legal_hold:
          type: boolean
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
      required:
        - id
        - retain_until
        - legal_hold
        - reason
    AnalyticsExportInput:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        format:
          type: string
          enum:
            - json
            - pdf
            - csv
            - xlsx
            - bundle
        layout_id:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
      required:
        - id
        - format
        - layout_id
        - reason
    AnalyticsExport:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        snapshot_id:
          type: string
          format: uuid
        format:
          type: string
          enum:
            - json
            - pdf
            - csv
            - xlsx
            - bundle
        status:
          type: string
          enum:
            - pending
            - inflight
            - complete
            - dead
        attempts:
          type: integer
          minimum: 0
        last_error:
          anyOf:
            - type: string
              minLength: 1
              maxLength: 80
              pattern: \S
            - type: "null"
        sha256:
          anyOf:
            - type: string
              pattern: ^[a-f0-9]{64}$
            - type: "null"
        size_bytes:
          anyOf:
            - type: integer
              minimum: 1
            - type: "null"
        created_at:
          type: string
          format: date-time
        completed_at:
          anyOf:
            - type: string
              format: date-time
            - type: "null"
        expires_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - snapshot_id
        - format
        - status
        - attempts
        - last_error
        - sha256
        - size_bytes
        - created_at
        - completed_at
        - expires_at
    AnalyticsReleaseInput:
      type: object
      additionalProperties: false
      properties:
        release:
          type: string
          minLength: 1
          maxLength: 50
          pattern: \S
        commit:
          type: string
          pattern: ^[a-f0-9]{40}$
        record_id:
          type: string
          format: uuid
        attachment_id:
          type: string
          format: uuid
        artifact_sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        reason:
          type: string
          minLength: 3
          maxLength: 1000
          pattern: \S
      required:
        - release
        - commit
        - record_id
        - attachment_id
        - artifact_sha256
        - reason
    AnalyticsRelease:
      type: object
      additionalProperties: false
      properties:
        id:
          type: string
          format: uuid
        tenant_id:
          type: string
          format: uuid
        release:
          type: string
          minLength: 1
          maxLength: 50
          pattern: \S
        commit:
          type: string
          pattern: ^[a-f0-9]{40}$
        record_id:
          type: string
          format: uuid
        attachment_id:
          type: string
          format: uuid
        artifact_sha256:
          type: string
          pattern: ^[a-f0-9]{64}$
        created_by:
          type: string
          format: uuid
        created_at:
          type: string
          format: date-time
      required:
        - id
        - tenant_id
        - release
        - commit
        - record_id
        - attachment_id
        - artifact_sha256
        - created_by
        - created_at
    AnalyticsDefinitionsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/AnalyticsDefinition"
          maxItems: 100
          minItems: 0
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    AnalyticsRowsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/AnalyticsRow"
          maxItems: 100
          minItems: 0
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    AnalyticsSnapshotsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/AnalyticsSnapshotSummary"
          maxItems: 100
          minItems: 0
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    AnalyticsExportsPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/AnalyticsExport"
          maxItems: 100
          minItems: 0
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    AnalyticsReleasesPage:
      type: object
      additionalProperties: false
      properties:
        items:
          type: array
          items:
            $ref: "#/components/schemas/AnalyticsRelease"
          maxItems: 100
          minItems: 0
        next_cursor:
          anyOf:
            - type: string
              format: uuid
            - type: "null"
      required:
        - items
        - next_cursor
    AnalyticsChoicesQuery:
      type: object
      additionalProperties: false
      properties:
        kind:
          type: string
          enum:
            - site
            - department
        site_id:
          type: string
          format: uuid
        cursor:
          type: string
          format: uuid
        limit:
          type: integer
          minimum: 1
          maximum: 100
      required:
        - kind
  responses:
    ValidationProblem:
      description: Request contains unsupported query parameters.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/Problem"
          example:
            type: urn:eqms:problem:validation-error
            title: Invalid request
            status: 422
            detail: This operation does not accept query parameters.
            code: VALIDATION_ERROR
            request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            errors:
              - field: query
                message: Remove query parameters.
    InternalProblem:
      description: Unexpected server failure. No sensitive diagnostics are returned.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/Problem"
          example:
            type: urn:eqms:problem:internal-error
            title: Internal server error
            status: 500
            detail: The request could not be completed.
            code: INTERNAL_ERROR
            request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FoundationTenantContext:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/TenantContext"
          example:
            user:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              email: reader@example.test
              display_name: Example
            tenant:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              name: Example
              slug: example-organization
              timezone: UTC
              locale: en-GB
              accent: blue
              mfa_required: false
              version: 1
              created_at: 2026-10-18T10:00:00.000Z
            permissions: []
            mfa_satisfied: false
            profile:
              user_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              display_name: Example
              timezone: UTC
              locale: en-GB
              version: 1
    FoundationError401:
      description: Missing/invalid identity or revoked session.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/ApiProblem"
          example:
            type: urn:eqms:problem:request-failed
            title: Request could not be completed
            status: 401
            detail: Missing/invalid identity or revoked session.
            code: UNAUTHENTICATED
            request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FoundationError403:
      description: Permission, tenant, scope, account or MFA policy denied.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/ApiProblem"
          example:
            type: urn:eqms:problem:request-failed
            title: Request could not be completed
            status: 403
            detail: Permission, tenant, scope, account or MFA policy denied.
            code: FORBIDDEN
            request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FoundationError404:
      description: Resource unavailable in the authorized tenant.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/ApiProblem"
          example:
            type: urn:eqms:problem:request-failed
            title: Request could not be completed
            status: 404
            detail: Resource unavailable in the authorized tenant.
            code: NOT_FOUND
            request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FoundationError409:
      description: Domain/idempotency or last-administrator conflict.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/ApiProblem"
          example:
            type: urn:eqms:problem:request-failed
            title: Request could not be completed
            status: 409
            detail: Domain/idempotency or last-administrator conflict.
            code: CONFLICT
            request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FoundationError412:
      description: Expected version no longer current.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/ApiProblem"
          example:
            type: urn:eqms:problem:request-failed
            title: Request could not be completed
            status: 412
            detail: Expected version no longer current.
            code: STALE_VERSION
            request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FoundationError422:
      description: Invalid body, query, identifiers or missing idempotency key.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/ApiProblem"
          example:
            type: urn:eqms:problem:request-failed
            title: Request could not be completed
            status: 422
            detail: Invalid body, query, identifiers or missing idempotency key.
            code: VALIDATION_ERROR
            request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FoundationError429:
      description: Request quota exceeded.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/ApiProblem"
          example:
            type: urn:eqms:problem:request-failed
            title: Request could not be completed
            status: 429
            detail: Request quota exceeded.
            code: RATE_LIMITED
            request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FoundationError500:
      description: Sanitized unexpected failure.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/ApiProblem"
          example:
            type: urn:eqms:problem:request-failed
            title: Request could not be completed
            status: 500
            detail: Sanitized unexpected failure.
            code: INTERNAL_ERROR
            request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FoundationError503:
      description: Identity/database dependency unavailable.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/ApiProblem"
          example:
            type: urn:eqms:problem:request-failed
            title: Request could not be completed
            status: 503
            detail: Identity/database dependency unavailable.
            code: DEPENDENCY_UNAVAILABLE
            request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FoundationProfile:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Profile"
          example:
            user_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            display_name: Example
            timezone: UTC
            locale: en-GB
            version: 1
    FoundationOrganization:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Organization"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            name: Example
            slug: example-organization
            timezone: UTC
            locale: en-GB
            accent: blue
            mfa_required: false
            version: 1
            created_at: 2026-10-18T10:00:00.000Z
    FoundationSitesPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/SitesPage"
          example:
            items: []
            next_cursor: Example
    FoundationSite:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Site"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            name: Example
            code: EXAMPLE
            active: false
            created_at: 2026-10-18T10:00:00.000Z
    FoundationDepartmentsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/DepartmentsPage"
          example:
            items: []
            next_cursor: Example
    FoundationDepartment:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Department"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            name: Example
            code: EXAMPLE
            active: false
            created_at: 2026-10-18T10:00:00.000Z
    FoundationRolesPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/RolesPage"
          example:
            items: []
            next_cursor: Example
    FoundationRole:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Role"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            name: Example
            version: 1
            permissions: []
    FoundationPermissionsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/PermissionsPage"
          example:
            items: []
            next_cursor: Example
    FoundationUsersPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/UsersPage"
          example:
            items: []
            next_cursor: Example
    FoundationMembership:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Membership"
          example:
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            user_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            status: active
            all_sites: false
            all_departments: false
            version: 1
    FoundationInvitationsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/InvitationsPage"
          example:
            items: []
            next_cursor: Example
    FoundationInvitationIssued:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/InvitationIssued"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            email: reader@example.test
            role_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            status: pending
            expires_at: 2026-10-18T10:00:00.000Z
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-18T10:00:00.000Z
    FoundationInvitation:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Invitation"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            email: reader@example.test
            role_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            status: pending
            expires_at: 2026-10-18T10:00:00.000Z
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-18T10:00:00.000Z
    FoundationAccepted:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Accepted"
          example:
            accepted: true
    FoundationClientsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ClientsPage"
          example:
            items: []
            next_cursor: Example
    FoundationClientIssued:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ClientIssued"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            name: Example
            scopes: []
            expires_at: 2026-10-18T10:00:00.000Z
            revoked_at: 2026-10-18T10:00:00.000Z
            created_at: 2026-10-18T10:00:00.000Z
            rotated_at: 2026-10-18T10:00:00.000Z
            last_used_at: 2026-10-18T10:00:00.000Z
    FoundationClient:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Client"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            name: Example
            scopes: []
            expires_at: 2026-10-18T10:00:00.000Z
            revoked_at: 2026-10-18T10:00:00.000Z
            created_at: 2026-10-18T10:00:00.000Z
            rotated_at: 2026-10-18T10:00:00.000Z
            last_used_at: 2026-10-18T10:00:00.000Z
    FoundationEventsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/EventsPage"
          example:
            items: []
            next_cursor: Example
    FoundationAuthResult:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AuthResult"
          example:
            message: Example
            signed_in: false
    FoundationMfaStatus:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/MfaStatus"
          example:
            factors: []
    FoundationMfaEnrollment:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/MfaEnrollment"
          example:
            factor_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            qr_code: Example
            secret: Example
    IntegrityResponseIntegrityRecordsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityRecordsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    IntegrityResponseIntegrityRecord:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityRecord"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            number: Example
            title: Example
            content: Example
            version: 1
            status: draft
            content_hash: "0000000000000000000000000000000000000000000000000000000000000000"
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-18T10:00:00Z
            updated_at: 2026-10-18T10:00:00Z
            retain_until: 2026-10-18T10:00:00Z
            legal_hold: false
    IntegrityResponseIntegrityDetail:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityDetail"
          example:
            record:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              number: Example
              title: Example
              content: Example
              version: 1
              status: draft
              content_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-18T10:00:00Z
              updated_at: 2026-10-18T10:00:00Z
              retain_until: 2026-10-18T10:00:00Z
              legal_hold: false
            versions: []
            signatures: []
            comments: []
            links: []
            attachments: []
    IntegrityResponseIntegritySignature:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegritySignature"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            version: 1
            content_hash: "0000000000000000000000000000000000000000000000000000000000000000"
            signer_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            signer_name: Example
            meaning: authorship
            reason: Example
            signed_at: 2026-10-18T10:00:00Z
            authentication_method: password
            request_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    IntegrityResponseIntegrityComment:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityComment"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            body: Example
            actor_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-18T10:00:00Z
    IntegrityResponseIntegrityLink:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityLink"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            target_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            relation: related
            created_at: 2026-10-18T10:00:00Z
    IntegrityResponseIntegrityAttachment:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityAttachment"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_version: 1
            filename: Example
            mime_type: text/plain
            size_bytes: 1
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            object_path: Example
            state: quarantined
            scanner: Example
            scanned_at: 2026-10-18T10:00:00Z
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-18T10:00:00Z
    IntegrityResponseIntegrityDownload:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityDownload"
          example:
            url: https://example.test/evidence
            expires_at: 2026-10-18T10:00:00Z
    IntegrityResponseIntegritySettings:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegritySettings"
          example:
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            prefix: TEST
            retention_years: 1
            vocabulary:
              - Example
            version: 1
    IntegrityResponseIntegrityAuditPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityAuditPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    IntegrityResponseIntegrityNotificationsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityNotificationsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    IntegrityResponseIntegrityNotification:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityNotification"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            event_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            recipient_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            message: Example
            read_at: 2026-10-18T10:00:00Z
            created_at: 2026-10-18T10:00:00Z
    IntegrityResponseAccepted:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Accepted"
          example:
            accepted: true
    IntegrityResponseIntegrityHistoryPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityHistoryPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    WorkflowResponseWorkflowCalendarsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowCalendarsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    WorkflowResponseWorkflowCalendar:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowCalendar"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            name: Example
            timezone: UTC
            weekdays:
              - 1
            start_minute: 0
            end_minute: 1
            holidays: []
            version: 1
    WorkflowResponseWorkflowTemplatesPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowTemplatesPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    WorkflowResponseWorkflowTemplate:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowTemplate"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            family_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            version: 1
            name: Example
            site_ids: []
            categories: []
            stages: []
            calendar_snapshot:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              name: Example
              timezone: UTC
              weekdays:
                - 1
              start_minute: 0
              end_minute: 1
              holidays: []
              version: 1
            published_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            published_at: 2026-10-18T10:00:00Z
    WorkflowResponseWorkflowInstancesPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowInstancesPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    WorkflowResponseWorkflowInstance:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowInstance"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            template_snapshot:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              family_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              version: 1
              name: Example
              site_ids: []
              categories: []
              stages: []
              calendar_snapshot:
                id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                name: Example
                timezone: UTC
                weekdays:
                  - 1
                start_minute: 0
                end_minute: 1
                holidays: []
                version: 1
              published_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              published_at: 2026-10-18T10:00:00Z
            record_version: 1
            content_hash: "0000000000000000000000000000000000000000000000000000000000000000"
            submitter_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            status: active
            version: 1
            round: 1
            stage_index: 0
            resolved: []
            created_at: 2026-10-18T10:00:00Z
            updated_at: 2026-10-18T10:00:00Z
    WorkflowResponseWorkflowDetail:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowDetail"
          example:
            instance:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              template_snapshot:
                id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                family_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                version: 1
                name: Example
                site_ids: []
                categories: []
                stages: []
                calendar_snapshot:
                  id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                  tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                  name: Example
                  timezone: UTC
                  weekdays:
                    - 1
                  start_minute: 0
                  end_minute: 1
                  holidays: []
                  version: 1
                published_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                published_at: 2026-10-18T10:00:00Z
              record_version: 1
              content_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              submitter_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              status: active
              version: 1
              round: 1
              stage_index: 0
              resolved: []
              created_at: 2026-10-18T10:00:00Z
              updated_at: 2026-10-18T10:00:00Z
            tasks: []
            rounds: []
    WorkflowResponseWorkflowEventsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowEventsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    WorkflowResponseWorkflowTasksPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowTasksPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    WorkflowResponseWorkflowWebhooksPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowWebhooksPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    WorkflowResponseWorkflowWebhookIssued:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowWebhookIssued"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            name: Example
            url: https://example.test/eqms
            event_types: []
            enabled: false
            version: 1
            created_at: 2026-10-18T10:00:00Z
    WorkflowResponseWorkflowWebhook:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowWebhook"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            name: Example
            url: https://example.test/eqms
            event_types: []
            enabled: false
            version: 1
            created_at: 2026-10-18T10:00:00Z
    WorkflowResponseWorkflowDeliveriesPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowDeliveriesPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    WorkflowResponseWorkflowDelivery:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowDelivery"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            subscription_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            event_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            status: pending
            attempts: 0
            replay_count: 0
            next_attempt_at: 2026-10-18T10:00:00Z
            last_status: 1
            last_error: Example
            completed_at: 2026-10-18T10:00:00Z
            created_at: 2026-10-18T10:00:00Z
    WorkflowResponseWorkflowHistoryPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/WorkflowHistoryPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FormResponseFormTemplatesPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormTemplatesPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FormResponseFormTemplate:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormTemplate"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            name: Example
            version: 1
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-18T10:00:00Z
    FormResponseFormTemplateDetail:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormTemplateDetail"
          example:
            template:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              name: Example
              version: 1
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-18T10:00:00Z
            draft:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              version: 1
              definition:
                name: Example
                schema:
                  schemaVersion: 1
                  sections:
                    - id: main
                      title: Example
                      columns: 1
                  fields: []
                  rules: []
                site_ids: []
                department_ids: []
                workflow_template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              reason: Example
              created_at: 2026-10-18T10:00:00Z
            publications: []
    FormResponseFormPublication:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormPublication"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            version: 1
            revision_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            definition:
              name: Example
              schema:
                schemaVersion: 1
                sections:
                  - id: main
                    title: Example
                    columns: 1
                fields: []
                rules: []
              site_ids: []
              department_ids: []
              workflow_template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            schema_hash: "0000000000000000000000000000000000000000000000000000000000000000"
            published_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            published_at: 2026-10-18T10:00:00Z
    FormResponseFormPublicationsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormPublicationsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FormResponseFormRecordsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormRecordsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FormResponseFormRecordDetail:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormRecordDetail"
          example:
            record:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              number: Example
              title: Example
              content: Example
              version: 1
              status: draft
              content_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-18T10:00:00Z
              updated_at: 2026-10-18T10:00:00Z
              retain_until: 2026-10-18T10:00:00Z
              legal_hold: false
            current_version: 1
            snapshot:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              version: 1
              publication_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              schema_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              values_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              ready: false
              actor_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-18T10:00:00Z
              reason: Example
            publication:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              version: 1
              revision_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              definition:
                name: Example
                schema:
                  schemaVersion: 1
                  sections:
                    - id: main
                      title: Example
                      columns: 1
                  fields: []
                  rules: []
                site_ids: []
                department_ids: []
                workflow_template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              schema_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              published_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              published_at: 2026-10-18T10:00:00Z
            values: {}
            display_values: {}
            redacted_fields: 1
            workflow:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              template_snapshot:
                id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                family_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                version: 1
                name: Example
                site_ids: []
                categories: []
                stages: []
                calendar_snapshot:
                  id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                  tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                  name: Example
                  timezone: Example
                  weekdays:
                    - 1
                  start_minute: 1
                  end_minute: 1
                  holidays: []
                  version: 1
                published_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                published_at: 2026-10-18T10:00:00Z
              record_version: 1
              content_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              submitter_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              status: active
              version: 1
              round: 1
              stage_index: 1
              resolved: []
              created_at: 2026-10-18T10:00:00Z
              updated_at: 2026-10-18T10:00:00Z
            signatures: []
    FormResponseIntegrityAttachment:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityAttachment"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_version: 1
            filename: Example
            mime_type: text/plain
            size_bytes: 1
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            object_path: Example
            state: quarantined
            scanner: Example
            scanned_at: 2026-10-18T10:00:00Z
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-18T10:00:00Z
    FormResponseFormHistoryPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormHistoryPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FormResponseFormVocabulariesPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormVocabulariesPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FormResponseFormVocabulary:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormVocabulary"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            name: Example
            version: 1
            options: []
            created_at: 2026-10-18T10:00:00Z
    FormResponseFormReferencesPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormReferencesPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FormResponseFormReference:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormReference"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            kind: product
            code: Example
            name: Example
            site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            active: false
            version: 1
            created_at: 2026-10-18T10:00:00Z
    FormResponseFormOptionsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormOptionsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FormResponseFormViewsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormViewsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FormResponseFormView:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormView"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            user_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            name: Example
            filters: {}
            version: 1
            created_at: 2026-10-18T10:00:00Z
    FormResponseFormExportsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormExportsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    FormResponseFormExport:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormExport"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_version: 1
            requested_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            session_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            aal: aal1
            format: pdf
            status: pending
            access_hash: "0000000000000000000000000000000000000000000000000000000000000000"
            object_path: Example
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            size_bytes: 1
            attempts: 1
            next_attempt_at: 2026-10-18T10:00:00Z
            last_error: Example
            created_at: 2026-10-18T10:00:00Z
            completed_at: 2026-10-18T10:00:00Z
    FormResponseFormDownload:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormDownload"
          example:
            url: https://example.test/export
            expires_at: 2026-10-18T10:00:00Z
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            size_bytes: 1
    FormResponseFormAccess:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormAccess"
          example:
            role_ids: []
            can_manage: false
    FormResponseFormLocationsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormLocationsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    ControlledResponseDocumentPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/DocumentPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    ControlledResponseDocumentDetail:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/DocumentDetail"
          example:
            document:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-18T10:00:00Z
              number: Example
              title: Example
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              current_revision_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              status: draft
              allow_download: false
              allow_print: false
              version: 1
              usable: false
            revisions: []
            obsolescence: []
    ControlledResponseIntegrityAttachment:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityAttachment"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_version: 1
            filename: Example
            mime_type: text/plain
            size_bytes: 1
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            object_path: Example
            state: quarantined
            scanner: Example
            scanned_at: 2026-10-18T10:00:00Z
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-18T10:00:00Z
    ControlledResponseTrainingCoursesPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/TrainingCoursesPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    ControlledResponseTrainingPublication:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/TrainingPublication"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-18T10:00:00Z
            course_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            version: 1
            definition:
              name: Example
              mode: document
              document_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              requires_verification: false
              valid_days: 1
              pass_mark: 1
              max_attempts: 1
              questions: []
            definition_hash: "0000000000000000000000000000000000000000000000000000000000000000"
    ControlledResponseTrainingDefinition:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/TrainingDefinition"
          example:
            name: Example
            mode: document
            document_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            requires_verification: false
            valid_days: 1
            pass_mark: 1
            max_attempts: 1
            questions: []
    ControlledResponseTrainingAssignmentsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/TrainingAssignmentsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    ControlledResponseTrainingAssignment:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/TrainingAssignment"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-18T10:00:00Z
            course_version_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            curriculum_version_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            document_revision_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            assignee_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            supervisor_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            required: false
            due_at: 2026-10-18T10:00:00Z
            grace_days: 1
            extra_attempts: 1
            status: assigned
            score: 1
            completed_at: 2026-10-18T10:00:00Z
            verified_at: 2026-10-18T10:00:00Z
            valid_until: 2026-10-18T10:00:00Z
            ack_signature_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            verification_signature_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            overdue_at: 2026-10-18T10:00:00Z
            escalated_at: 2026-10-18T10:00:00Z
            expiry_notified_at: 2026-10-18T10:00:00Z
            version: 1
    ControlledResponseTrainingDetail:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/TrainingDetail"
          example:
            assignment:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-18T10:00:00Z
              course_version_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              curriculum_version_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              document_revision_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              assignee_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              supervisor_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              required: false
              due_at: 2026-10-18T10:00:00Z
              grace_days: 1
              extra_attempts: 1
              status: assigned
              score: 1
              completed_at: 2026-10-18T10:00:00Z
              verified_at: 2026-10-18T10:00:00Z
              valid_until: 2026-10-18T10:00:00Z
              ack_signature_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              verification_signature_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              overdue_at: 2026-10-18T10:00:00Z
              escalated_at: 2026-10-18T10:00:00Z
              expiry_notified_at: 2026-10-18T10:00:00Z
              version: 1
            course:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-18T10:00:00Z
              course_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              version: 1
              definition:
                name: Example
                mode: document
                document_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                requires_verification: false
                valid_days: 1
                pass_mark: 1
                max_attempts: 1
                questions: []
              definition_hash: "0000000000000000000000000000000000000000000000000000000000000000"
            record:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              number: Example
              title: Example
              content: Example
              version: 1
              status: draft
              content_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-18T10:00:00Z
              updated_at: 2026-10-18T10:00:00Z
              retain_until: 2026-10-18T10:00:00Z
              legal_hold: false
            attempts: []
            signatures: []
            material:
              revision_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              number: Example
              revision: 1
              title: Example
              status: draft
    ControlledResponseControlledCopy:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ControlledCopy"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            revision_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            assignment_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            requested_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            session_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            aal: aal1
            purpose: view
            source_hash: "0000000000000000000000000000000000000000000000000000000000000000"
            access_hash: "0000000000000000000000000000000000000000000000000000000000000000"
            state_hash: "0000000000000000000000000000000000000000000000000000000000000000"
            object_path: Example
            status: pending
            attempts: 1
            next_attempt_at: 2026-10-18T10:00:00Z
            last_error: Example
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            size_bytes: 1
            created_at: 2026-10-18T10:00:00Z
            completed_at: 2026-10-18T10:00:00Z
            retrieved_at: 2026-10-18T10:00:00Z
    ControlledResponseControlledCopiesPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/ControlledCopiesPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    ControlledResponseFormDownload:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormDownload"
          example:
            url: https://example.test/copy
            expires_at: 2026-10-18T10:00:00Z
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            size_bytes: 1
    ControlledResponseFormLocationsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormLocationsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    ControlledResponseTrainingCurriculaPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/TrainingCurriculaPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    ControlledResponseTrainingCurriculumPublication:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/TrainingCurriculumPublication"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-18T10:00:00Z
            curriculum_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            version: 1
            definition:
              name: Example
              role_ids: []
              site_ids: []
              department_ids: []
              course_version_ids:
                - 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              due_days: 1
              grace_days: 1
              required: false
              supervisor_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    ControlledResponseTrainingEnrollment:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/TrainingEnrollment"
          example:
            assigned: 1
    ControlledResponseDocumentObsolescence:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/DocumentObsolescence"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            document_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            revision_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            workflow_template_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-18T10:00:00Z
    QualityResponseQualityMastersPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/QualityMastersPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    QualityResponseQualityMasterDetail:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/QualityMasterDetail"
          example:
            master:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              kind: product
              code: EXAMPLE-1
              name: Example
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              version: 1
              active: false
              source_system: Example
              external_id: Example
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-18T10:00:00Z
            versions: []
    QualityResponseQualityMasterPublication:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/QualityMasterPublication"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            kind: product
            code: EXAMPLE-1
            name: Example
            site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            version: 1
            active: false
            source_system: Example
            external_id: Example
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-18T10:00:00Z
            publication_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            definition:
              code: EXAMPLE-1
              name: Example
              active: false
              source_system: Example
              external_id: Example
              source_uri: https://example.test/reference
              related_version_ids: []
              manufactured_on: 2027-10-18
              expires_on: 2027-10-18
            definition_hash: "0000000000000000000000000000000000000000000000000000000000000000"
    QualityResponseQualityModelsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/QualityModelsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    QualityResponseQualityRiskModel:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/QualityRiskModel"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            family_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            version: 1
            definition:
              name: Example
              method: matrix
              severity_max: 2
              probability_max: 2
              detection_max: 1
              tiers:
                - label: Example
                  max_score: 1
                  acceptance_required: false
                - label: Example
                  max_score: 1
                  acceptance_required: false
            definition_hash: "0000000000000000000000000000000000000000000000000000000000000000"
            published_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            published_at: 2026-10-18T10:00:00Z
    QualityResponseQualityCasesPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/QualityCasesPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    QualityResponseQualityDetail:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/QualityDetail"
          example:
            case:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              kind: risk
              record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              number: Example
              state: draft
              data:
                title: Example
                description: Example
                master_version_ids: []
                reference_ids: []
                required_dependencies: []
                details:
                  model_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                  hazards: []
                  acceptance_rationale: Example
                  review_on: 2027-10-18
              owner_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              due_at: 2026-10-18T10:00:00Z
              version: 1
              authorization_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              closure_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              closed_at: 2026-10-18T10:00:00Z
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-18T10:00:00Z
              updated_at: 2026-10-18T10:00:00Z
            actions: []
            dependencies: []
            scores: []
            evaluations: []
            record:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              number: Example
              title: Example
              content: Example
              version: 1
              status: draft
              content_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-18T10:00:00Z
              updated_at: 2026-10-18T10:00:00Z
              retain_until: 2026-10-18T10:00:00Z
              legal_hold: false
            versions: []
            approvals: []
            links: []
            master_references: []
            dependency_status: []
            linked_records: []
    QualityResponseIntegrityAttachment:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityAttachment"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_version: 1
            filename: Example
            mime_type: text/plain
            size_bytes: 1
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            object_path: Example
            state: quarantined
            scanner: Example
            scanned_at: 2026-10-18T10:00:00Z
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-18T10:00:00Z
    QualityResponseFormLocationsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormLocationsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    QualityResponseQualitySearchPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/QualitySearchPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    QualityResponseQualityDashboard:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/QualityDashboard"
          example:
            open: 1
            overdue: 1
            closed: 1
            awaiting_effectiveness: 1
            risk_reviews_due: 1
            temporary_changes_expired: 1
            failed_evaluations: 1
            monthly: []
            root_causes: []
    QualityResponseQualityInspection:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/QualityInspection"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            filename: Example
            generated_at: 2026-10-18T10:00:00Z
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            size_bytes: 1
            content_base64: Example
    QcResponseQcPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/QcPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    QcResponseQcDetail:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/QcDetail"
          example:
            object:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              kind: laboratory
              code: EXAMPLE-1
              title: Example
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              owner_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              family_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              publication: 1
              record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              definition:
                kind: laboratory
                location: Example
                accreditation: Example
              definition_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              state: published
              version: 1
              source_system: Example
              external_id: Example
              source_revision: Example
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-19T10:00:00Z
            events: []
            approvals: []
            record:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              number: Example
              title: Example
              content: Example
              version: 1
              status: draft
              content_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-19T10:00:00Z
              updated_at: 2026-10-19T10:00:00Z
              retain_until: 2026-10-19T10:00:00Z
              legal_hold: false
            use_status:
              usable: false
              reasons: []
              calibration_due_at: 2026-10-19T10:00:00Z
              maintenance_due_at: 2026-10-19T10:00:00Z
            references: []
    QcResponseIntegrityAttachment:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityAttachment"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_version: 1
            filename: Example
            mime_type: text/plain
            size_bytes: 1
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            object_path: Example
            state: quarantined
            scanner: Example
            scanned_at: 2026-10-19T10:00:00Z
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-19T10:00:00Z
    QcResponseQcReconciliation:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/QcReconciliation"
          example:
            items: []
    QcResponseFormLocationsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormLocationsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    OversightResponseFormLocationsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormLocationsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    OversightResponseOversightPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/OversightPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    OversightResponseOversightDetail:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/OversightDetail"
          example:
            object:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              kind: program
              code: EXAMPLE-1
              title: Example
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              owner_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              due_at: 2026-10-19T10:00:00Z
              family_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              publication: 1
              record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              definition:
                kind: program
                year: 2020
                scope: Example
                objectives: Example
              definition_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              state: published
              version: 1
              valid_until: 2026-10-19T10:00:00Z
              conditions: Example
              source_system: Example
              external_id: Example
              source_revision: Example
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-19T10:00:00Z
            events: []
            findings: []
            responses: []
            verifications: []
            approvals: []
            record:
              id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              number: Example
              title: Example
              content: Example
              version: 1
              status: draft
              content_hash: "0000000000000000000000000000000000000000000000000000000000000000"
              created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
              created_at: 2026-10-19T10:00:00Z
              updated_at: 2026-10-19T10:00:00Z
              retain_until: 2026-10-19T10:00:00Z
              legal_hold: false
            eligibility:
              eligible: false
              reasons: []
              valid_until: 2026-10-19T10:00:00Z
              score: 1
            handoffs: []
            handoff_attempts: []
    OversightResponseIntegrityAttachment:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/IntegrityAttachment"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            record_version: 1
            filename: Example
            mime_type: text/plain
            size_bytes: 1
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            object_path: Example
            state: quarantined
            scanner: Example
            scanned_at: 2026-10-19T10:00:00Z
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-19T10:00:00Z
    OversightResponseOversightReporterHistory:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/OversightReporterHistory"
          example:
            items: []
    OversightResponseOversightReport:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/OversightReport"
          example:
            generated_at: 2026-10-19T10:00:00Z
            manifest:
              object:
                id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                kind: program
                code: EXAMPLE-1
                title: Example
                site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                owner_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                due_at: 2026-10-19T10:00:00Z
                family_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                publication: 1
                record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                definition:
                  kind: program
                  year: 2020
                  scope: Example
                  objectives: Example
                definition_hash: "0000000000000000000000000000000000000000000000000000000000000000"
                state: published
                version: 1
                valid_until: 2026-10-19T10:00:00Z
                conditions: Example
                source_system: Example
                external_id: Example
                source_revision: Example
                created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                created_at: 2026-10-19T10:00:00Z
              events: []
              findings: []
              responses: []
              verifications: []
              approvals: []
              record:
                id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                site_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                department_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                number: Example
                title: Example
                content: Example
                version: 1
                status: draft
                content_hash: "0000000000000000000000000000000000000000000000000000000000000000"
                created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
                created_at: 2026-10-19T10:00:00Z
                updated_at: 2026-10-19T10:00:00Z
                retain_until: 2026-10-19T10:00:00Z
                legal_hold: false
              eligibility:
                eligible: false
                reasons: []
                valid_until: 2026-10-19T10:00:00Z
                score: 1
              handoffs: []
              handoff_attempts: []
            reporter:
              items: []
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
    OversightResponseOversightDashboard:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/OversightDashboard"
          example:
            open_audits: 1
            overdue_findings: 1
            eligible_suppliers: 1
            open_complaints: 1
            unacknowledged_safety: 1
            complaint_trends: []
    OversightResponseQcReconciliation:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/QcReconciliation"
          example:
            items: []
    AnalyticsResponseAnalyticsDefinitionsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AnalyticsDefinitionsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    AnalyticsResponseAnalyticsDefinition:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AnalyticsDefinition"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            family_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            publication: 1
            kind: kpi
            name: Example
            definition: {}
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-19T10:00:00Z
    AnalyticsResponseAnalyticsRowsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AnalyticsRowsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    AnalyticsResponseAnalyticsSnapshotsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AnalyticsSnapshotsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    AnalyticsResponseAnalyticsSnapshot:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AnalyticsSnapshot"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            title: Example
            kind: management
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-19T10:00:00Z
            retain_until: 2026-10-19T10:00:00Z
            legal_hold: false
            payload: {}
            signatures: []
    AnalyticsResponseAnalyticsExport:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AnalyticsExport"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            snapshot_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            format: json
            status: pending
            attempts: 1
            last_error: Example
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            size_bytes: 1
            created_at: 2026-10-19T10:00:00Z
            completed_at: 2026-10-19T10:00:00Z
            expires_at: 2026-10-19T10:00:00Z
    AnalyticsResponseAnalyticsExportsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AnalyticsExportsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    AnalyticsResponseFormDownload:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormDownload"
          example:
            url: https://example.test/export
            expires_at: 2026-10-19T10:00:00Z
            sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            size_bytes: 1
    AnalyticsResponseAnalyticsReleasesPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AnalyticsReleasesPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
    AnalyticsResponseAnalyticsRelease:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/AnalyticsRelease"
          example:
            id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            tenant_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            release: Example
            commit: "0000000000000000000000000000000000000000"
            record_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            attachment_id: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            artifact_sha256: "0000000000000000000000000000000000000000000000000000000000000000"
            created_by: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
            created_at: 2026-10-19T10:00:00Z
    AnalyticsResponseFormLocationsPage:
      description: Successful operation.
      headers:
        X-Request-ID:
          $ref: "#/components/headers/RequestId"
        Cache-Control:
          $ref: "#/components/headers/NoStore"
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/FormLocationsPage"
          example:
            items: []
            next_cursor: 70fce739-a85a-4a34-a8a1-9e1f4e0d1f58
  securitySchemes:
    humanBearer:
      type: http
      scheme: bearer
      bearerFormat: Supabase JWT
    sessionCookie:
      type: apiKey
      in: cookie
      name: eqms-session
      description: Server-maintained HttpOnly session cookies; chunking and PKCE managed by Supabase SSR.
    integrationKey:
      type: http
      scheme: bearer
      bearerFormat: eqms_<random-secret>
      description: Tenant-scoped expiring key, restricted to documented read scopes. No human impersonation or signatures.
