openapi: 3.1.0
info:
  title: Tenant Action Taxonomy Internal Admin Contract
  version: 0.1.0
  summary: Internal planning contract for lifecycle-safe tenant action resolution and execution
  description: |
    This contract is an internal design artifact for Spec 145. It models the server-side
    semantics that Filament and Livewire action surfaces must follow. It is not a public API
    commitment and may be implemented through Livewire actions, controller actions, or service calls.
    In this spec slice it is design-only and documents the intended resolver and mutation semantics;
    it does not require adding new public or controller-backed HTTP endpoints.
servers:
  - url: /internal/admin
tags:
  - name: Tenant Action Catalog
  - name: Tenant Lifecycle Actions
  - name: Onboarding Workflow Actions
paths:
  /tenants/{tenant}/actions:
    get:
      tags: [Tenant Action Catalog]
      summary: Resolve lifecycle-safe action catalog for a tenant and surface
      operationId: resolveTenantActions
      parameters:
        - $ref: '#/components/parameters/TenantId'
        - name: surface
          in: query
          required: true
          schema:
            $ref: '#/components/schemas/TenantActionSurface'
      responses:
        '200':
          description: Tenant action catalog resolved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TenantActionCatalogResponse'
        '403':
          description: Actor is in scope but lacks capability for one or more returned action intents
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Tenant is outside workspace or tenant entitlement scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /tenants/{tenant}/archive:
    post:
      tags: [Tenant Lifecycle Actions]
      summary: Archive an active tenant
      operationId: archiveTenant
      parameters:
        - $ref: '#/components/parameters/TenantId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [confirm]
              properties:
                confirm:
                  type: boolean
                  const: true
      responses:
        '200':
          description: Tenant archived
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TenantLifecycleMutationResponse'
        '403':
          description: Actor is entitled to inspect but lacks lifecycle-mutation capability
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Tenant is outside entitlement scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Tenant is not in a lifecycle state that can be archived
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /tenants/{tenant}/restore:
    post:
      tags: [Tenant Lifecycle Actions]
      summary: Restore an archived tenant
      operationId: restoreTenant
      parameters:
        - $ref: '#/components/parameters/TenantId'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required: [confirm]
              properties:
                confirm:
                  type: boolean
                  const: true
      responses:
        '200':
          description: Tenant restored
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TenantLifecycleMutationResponse'
        '403':
          description: Actor is entitled to inspect but lacks lifecycle-mutation capability
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Tenant is outside entitlement scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '409':
          description: Tenant is not archived and cannot be restored
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
  /onboarding/{onboardingDraft}/actions:
    get:
      tags: [Onboarding Workflow Actions]
      summary: Resolve workflow-specific actions for an onboarding draft
      operationId: resolveOnboardingActions
      parameters:
        - $ref: '#/components/parameters/OnboardingDraftId'
      responses:
        '200':
          description: Onboarding actions resolved
          content:
            application/json:
              schema:
                type: object
                required: [draftId, actions]
                properties:
                  draftId:
                    type: integer
                  actions:
                    type: array
                    items:
                      $ref: '#/components/schemas/TenantActionDescriptor'
        '403':
          description: Actor is in scope but lacks onboarding workflow capability
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '404':
          description: Draft is outside workspace or tenant entitlement scope
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  parameters:
    TenantId:
      name: tenant
      in: path
      required: true
      schema:
        type: string
      description: External tenant route key or canonical tenant identifier
    OnboardingDraftId:
      name: onboardingDraft
      in: path
      required: true
      schema:
        type: integer
  schemas:
    TenantActionSurface:
      type: string
      enum:
        - tenant_index_row
        - tenant_view_header
        - tenant_edit_header
        - onboarding_index_row
        - onboarding_detail_header
        - widget
        - context_menu
    TenantActionCatalogResponse:
      type: object
      required:
        - tenantId
        - lifecycle
        - surface
        - actions
      properties:
        tenantId:
          type: string
        lifecycle:
          type: string
          enum: [draft, onboarding, active, archived]
        surface:
          $ref: '#/components/schemas/TenantActionSurface'
        actions:
          type: array
          items:
            $ref: '#/components/schemas/TenantActionDescriptor'
    TenantActionDescriptor:
      type: object
      required:
        - key
        - family
        - label
        - visible
        - enabled
        - destructive
        - requiresConfirmation
      properties:
        key:
          type: string
          enum:
            - view
            - resume_onboarding
            - complete_onboarding
            - archive
            - restore
            - view_operations
            - verify
            - grant_admin_consent
            - view_related_onboarding
        family:
          type: string
          enum:
            - neutral
            - onboarding_workflow
            - lifecycle_management
            - readiness
        label:
          type: string
        visible:
          type: boolean
        enabled:
          type: boolean
        destructive:
          type: boolean
        requiresConfirmation:
          type: boolean
        capability:
          type: string
          nullable: true
        auditActionId:
          type: string
          nullable: true
        reasonCode:
          type: string
          nullable: true
        group:
          type: string
          enum: [primary, secondary, overflow]
          nullable: true
    TenantLifecycleMutationResponse:
      type: object
      required:
        - tenantId
        - beforeLifecycle
        - afterLifecycle
        - auditActionId
      properties:
        tenantId:
          type: string
        beforeLifecycle:
          type: string
          enum: [draft, onboarding, active, archived]
        afterLifecycle:
          type: string
          enum: [draft, onboarding, active, archived]
        auditActionId:
          type: string
        notificationTitle:
          type: string
          nullable: true
    ErrorResponse:
      type: object
      required:
        - code
        - message
      properties:
        code:
          type: string
          enum:
            - not_found
            - forbidden
            - invalid_lifecycle
            - invalid_workflow_state
        message:
          type: string