openapi: 3.1.0
info:
  title: Managed Tenant Onboarding Lifecycle Logical Contract
  version: 0.1.0
  summary: Logical mutation contract for feature 140
  description: |
    This contract documents the logical onboarding draft read and mutation surface
    required by feature 140. It does not authorize creating new public routes.
    Implementation must continue to use the existing Filament and Livewire wizard
    mounted on /admin/onboarding and /admin/onboarding/{onboardingDraft}.
servers:
  - url: /admin
paths:
  /onboarding/{onboardingDraft}:
    get:
      summary: Read onboarding draft lifecycle state
      operationId: readOnboardingDraftLifecycle
      parameters:
        - $ref: '#/components/parameters/OnboardingDraftId'
      responses:
        '200':
          description: Current draft workflow state
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OnboardingDraftView'
        '403':
          description: Member lacks required capability
        '404':
          description: Draft not found or caller not entitled to workspace scope
  /onboarding/{onboardingDraft}/commands/provider-connection:
    post:
      summary: Commit provider connection selection or change
      operationId: commitOnboardingProviderConnection
      parameters:
        - $ref: '#/components/parameters/OnboardingDraftId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProviderConnectionMutation'
      responses:
        '200':
          description: Draft updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OnboardingDraftMutationResult'
        '403':
          description: Member lacks required capability
        '404':
          description: Draft not found or caller not entitled
        '409':
          description: Optimistic locking conflict
        '422':
          description: Invalid selection or transition
  /onboarding/{onboardingDraft}/commands/verify:
    post:
      summary: Start or rerun Verify Access for the selected provider connection
      operationId: startOnboardingVerification
      parameters:
        - $ref: '#/components/parameters/OnboardingDraftId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VersionedMutationRequest'
      responses:
        '202':
          description: Verification accepted and relevant run queued or reused
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CheckpointRunAccepted'
        '403':
          description: Member lacks required capability
        '404':
          description: Draft not found or caller not entitled
        '409':
          description: Optimistic locking conflict
        '422':
          description: Draft is not in a valid state to start verification
  /onboarding/{onboardingDraft}/commands/bootstrap:
    post:
      summary: Start selected bootstrap operations
      operationId: startOnboardingBootstrap
      parameters:
        - $ref: '#/components/parameters/OnboardingDraftId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/BootstrapMutation'
      responses:
        '202':
          description: Bootstrap accepted and relevant runs queued or reused
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CheckpointRunAccepted'
        '403':
          description: Member lacks required capability
        '404':
          description: Draft not found or caller not entitled
        '409':
          description: Optimistic locking conflict
        '422':
          description: Verification or selection preconditions are not met
  /onboarding/{onboardingDraft}/commands/activate:
    post:
      summary: Activate a ready onboarding draft
      operationId: activateOnboardingDraft
      parameters:
        - $ref: '#/components/parameters/OnboardingDraftId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ActivationMutation'
      responses:
        '200':
          description: Tenant activated and draft completed
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OnboardingDraftMutationResult'
        '403':
          description: Member lacks activation capability
        '404':
          description: Draft not found or caller not entitled
        '409':
          description: Optimistic locking conflict
        '422':
          description: Backend truth no longer permits activation
  /onboarding/{onboardingDraft}/commands/cancel:
    post:
      summary: Cancel an editable onboarding draft
      operationId: cancelOnboardingDraft
      parameters:
        - $ref: '#/components/parameters/OnboardingDraftId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/VersionedMutationRequest'
      responses:
        '200':
          description: Draft cancelled
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OnboardingDraftMutationResult'
        '403':
          description: Member lacks required capability
        '404':
          description: Draft not found or caller not entitled
        '409':
          description: Optimistic locking conflict
        '422':
          description: Draft is already terminal or not cancellable
components:
  parameters:
    OnboardingDraftId:
      name: onboardingDraft
      in: path
      required: true
      schema:
        type: integer
  schemas:
    OnboardingDraftView:
      type: object
      required:
        - id
        - version
        - lifecycle_state
        - current_checkpoint
      properties:
        id:
          type: integer
        version:
          type: integer
          minimum: 1
        lifecycle_state:
          $ref: '#/components/schemas/LifecycleState'
        current_checkpoint:
          oneOf:
            - $ref: '#/components/schemas/Checkpoint'
            - type: 'null'
        last_completed_checkpoint:
          oneOf:
            - $ref: '#/components/schemas/Checkpoint'
            - type: 'null'
        reason_code:
          type:
            - string
            - 'null'
        blocking_reason_code:
          type:
            - string
            - 'null'
        verification_operation_run_id:
          type:
            - integer
            - 'null'
        bootstrap_operation_run_ids:
          type: array
          items:
            type: integer
    VersionedMutationRequest:
      type: object
      required:
        - expected_version
      properties:
        expected_version:
          type: integer
          minimum: 1
    ProviderConnectionMutation:
      allOf:
        - $ref: '#/components/schemas/VersionedMutationRequest'
        - type: object
          required:
            - provider_connection_id
          properties:
            provider_connection_id:
              type: integer
    BootstrapMutation:
      allOf:
        - $ref: '#/components/schemas/VersionedMutationRequest'
        - type: object
          required:
            - bootstrap_operation_types
          properties:
            bootstrap_operation_types:
              type: array
              items:
                type: string
    ActivationMutation:
      allOf:
        - $ref: '#/components/schemas/VersionedMutationRequest'
        - type: object
          properties:
            override_blocked:
              type: boolean
            override_reason:
              type:
                - string
                - 'null'
    CheckpointRunAccepted:
      type: object
      required:
        - draft
        - operation_run_id
      properties:
        draft:
          $ref: '#/components/schemas/OnboardingDraftMutationResult'
        operation_run_id:
          type: integer
    OnboardingDraftMutationResult:
      type: object
      required:
        - id
        - version
        - lifecycle_state
      properties:
        id:
          type: integer
        version:
          type: integer
        lifecycle_state:
          $ref: '#/components/schemas/LifecycleState'
        current_checkpoint:
          oneOf:
            - $ref: '#/components/schemas/Checkpoint'
            - type: 'null'
        last_completed_checkpoint:
          oneOf:
            - $ref: '#/components/schemas/Checkpoint'
            - type: 'null'
        reason_code:
          type:
            - string
            - 'null'
        blocking_reason_code:
          type:
            - string
            - 'null'
    LifecycleState:
      type: string
      enum:
        - draft
        - verifying
        - action_required
        - bootstrapping
        - ready_for_activation
        - completed
        - cancelled
    Checkpoint:
      type: string
      enum:
        - identify
        - connect_provider
        - verify_access
        - bootstrap
        - complete_activate