openapi: 3.1.0
info:
  title: Tenant Lifecycle, Operability, and Context Semantics Admin Contract
  version: 0.1.0
  summary: Contract for selector, tenant-bound, onboarding, and canonical workspace record semantics in Spec 143.
  description: >-
    This contract documents the expected HTTP-level behavior for the admin-plane routes
    affected by tenant lifecycle, operability, and remembered tenant context semantics.
servers:
  - url: /admin
tags:
  - name: Tenant Context
  - name: Tenant Management
  - name: Onboarding
  - name: Operations
paths:
  /choose-tenant:
    get:
      tags: [Tenant Context]
      summary: Show normal tenant context choices for the current workspace.
      description: >-
        Returns the tenant chooser surface. Only tenants that are eligible for normal active
        operating context may be shown as selectable choices.
      responses:
        '200':
          description: Tenant chooser rendered.
          content:
            text/html:
              schema:
                type: string
        '404':
          description: No valid workspace context or user is not entitled to the workspace.
  /select-tenant:
    post:
      tags: [Tenant Context]
      summary: Persist the remembered tenant context for the current workspace.
      requestBody:
        required: true
        content:
          application/x-www-form-urlencoded:
            schema:
              type: object
              required: [tenant_id]
              properties:
                tenant_id:
                  type: integer
      responses:
        '302':
          description: Tenant context remembered and browser redirected to the tenant dashboard.
        '404':
          description: Tenant not found in current workspace, not entitled, or not eligible for normal active context.
        '403':
          description: User is unauthenticated or otherwise not allowed to execute the selection mutation.
  /clear-tenant-context:
    post:
      tags: [Tenant Context]
      summary: Clear the remembered tenant context for the current workspace.
      responses:
        '302':
          description: Remembered tenant context cleared and browser redirected.
  /tenants/{tenant}:
    get:
      tags: [Tenant Management]
      summary: View a tenant-bound admin page.
      description: >-
        Route legitimacy is based on the route tenant plus workspace and tenant entitlement checks,
        not on the currently remembered tenant context.
      parameters:
        - $ref: '#/components/parameters/TenantExternalId'
      responses:
        '200':
          description: Tenant detail page rendered.
          content:
            text/html:
              schema:
                type: string
        '404':
          description: User lacks workspace membership or tenant entitlement, or tenant is not in scope.
        '403':
          description: User is a member but lacks a capability for a requested mutation action on this page.
  /onboarding:
    get:
      tags: [Onboarding]
      summary: View workspace-scoped managed tenant onboarding.
      responses:
        '200':
          description: Onboarding landing or wizard rendered.
          content:
            text/html:
              schema:
                type: string
        '404':
          description: User lacks workspace membership.
        '403':
          description: User is a workspace member but lacks onboarding capability.
  /onboarding/{onboardingDraft}:
    get:
      tags: [Onboarding]
      summary: View or resume a specific onboarding draft.
      parameters:
        - $ref: '#/components/parameters/OnboardingDraftId'
      responses:
        '200':
          description: Onboarding draft rendered.
          content:
            text/html:
              schema:
                type: string
        '404':
          description: User lacks workspace membership or tenant entitlement for the linked draft context.
        '403':
          description: User is a workspace member but lacks onboarding capability.
  /operations:
    get:
      tags: [Operations]
      summary: View the workspace-scoped operations index.
      description: >-
        Workspace-scoped monitoring route. Tenant context may act as a default filter, but not as a validity requirement.
      responses:
        '200':
          description: Operations index rendered.
          content:
            text/html:
              schema:
                type: string
        '404':
          description: User lacks workspace membership.
  /operations/{run}:
    get:
      tags: [Operations]
      summary: View a canonical workspace-owned operation run.
      description: >-
        Canonical record viewer. If the user is entitled to the workspace and referenced tenant, the page remains valid even when
        the remembered active tenant differs from the run's tenant.
      parameters:
        - $ref: '#/components/parameters/OperationRunId'
      responses:
        '200':
          description: Operation run viewer rendered.
          content:
            text/html:
              schema:
                type: string
        '404':
          description: User lacks workspace membership, lacks referenced tenant entitlement, or the run is not in workspace scope.
        '403':
          description: User is a workspace or tenant member but lacks the capability resolved for the run type.
components:
  parameters:
    TenantExternalId:
      name: tenant
      in: path
      required: true
      schema:
        type: string
      description: Tenant route key external ID.
    OnboardingDraftId:
      name: onboardingDraft
      in: path
      required: true
      schema:
        type: integer
      description: Workspace-scoped onboarding draft identifier.
    OperationRunId:
      name: run
      in: path
      required: true
      schema:
        type: integer
      description: Canonical operation run identifier.
  schemas:
    TenantLifecycleState:
      type: string
      enum: [draft, onboarding, active, archived]
    PageCategory:
      type: string
      enum:
        - workspace_scoped
        - tenant_bound
        - onboarding_workflow
        - canonical_workspace_record_viewer
    AuthorizationOutcome:
      type: object
      required: [membership_scope, capability_scope, response_behavior]
      properties:
        membership_scope:
          type: string
          enum: [workspace, tenant, onboarding_draft, canonical_record]
        capability_scope:
          type: string
        response_behavior:
          type: string
          enum: [allow, deny_as_not_found, forbid]
    TenantOperabilityDecision:
      type: object
      required:
        - lifecycle
        - can_view_tenant_surface
        - can_select_as_context
        - can_operate
        - can_archive
        - can_restore
        - can_resume_onboarding
        - can_reference_in_workspace_monitoring
      properties:
        lifecycle:
          $ref: '#/components/schemas/TenantLifecycleState'
        can_view_tenant_surface:
          type: boolean
        can_select_as_context:
          type: boolean
        can_operate:
          type: boolean
        can_archive:
          type: boolean
        can_restore:
          type: boolean
        can_resume_onboarding:
          type: boolean
        can_reference_in_workspace_monitoring:
          type: boolean
    CanonicalViewerContextMismatch:
      type: object
      required: [selected_tenant_id, referenced_tenant_id, behavior]
      properties:
        selected_tenant_id:
          type: integer
          nullable: true
        referenced_tenant_id:
          type: integer
          nullable: true
        behavior:
          type: string
          enum: [ignore_for_legitimacy, show_context_banner]