openapi: 3.1.0
info:
  title: TenantPilot Internal UI Contracts
  version: 1.0.0
  description: |
    This OpenAPI document is used as a schema bundle for internal (non-HTTP) contracts.

    Spec 090 does not introduce public HTTP endpoints; Filament/Livewire actions are
    executed via framework internals. We still publish schemas here so the feature
    has explicit, reviewable contracts under `specs/.../contracts/`.

paths: {}

components:
  schemas:
    ActionSurfaceSlot:
      type: string
      description: Named surface slot required by the constitution Action Surface Contract.
      enum:
        - list.header
        - list.inspect_affordance
        - list.row.more_menu
        - list.bulk.more_group
        - list.empty_state
        - detail.header

    ActionSurfaceInspectAffordance:
      type: string
      description: Accepted inspection affordances for a record list/table.
      enum:
        - clickable_row
        - view_action
        - primary_linked_column

    ActionSurfaceProfile:
      type: string
      description: Profile that determines which slots are required.
      enum:
        - crud_list_and_view
        - list_only_read_only
        - run_log
        - relation_manager

    ActionSurfaceDeclaration:
      type: object
      additionalProperties: false
      required:
        - component
        - profile
        - slots
      properties:
        component:
          type: string
          description: Fully-qualified class name of the Filament Resource/Page/RelationManager.
          examples:
            - App\\Filament\\Resources\\PolicyResource
        profile:
          $ref: '#/components/schemas/ActionSurfaceProfile'
        slots:
          type: object
          description: Declared satisfaction/exemption for each slot.
          additionalProperties:
            type: object
            additionalProperties: false
            properties:
              status:
                type: string
                enum: [satisfy, exempt]
              value:
                type: string
                description: Freeform value (e.g., inspect affordance type).
              reason:
                type: string
                description: Non-empty exemption reason when status=exempt.

    RbacDecision:
      type: object
      additionalProperties: false
      required:
        - is_member
        - has_capability
        - outcome
      properties:
        is_member:
          type: boolean
        has_capability:
          type: boolean
        outcome:
          type: string
          description: Server-side outcome required by RBAC-UX.
          enum:
            - allow
            - deny_as_not_found
            - deny_as_forbidden

    AuditLogEntry:
      type: object
      additionalProperties: false
      required:
        - action
        - status
        - recorded_at
      properties:
        tenant_id:
          type: integer
          nullable: true
        workspace_id:
          type: integer
          nullable: true
        actor_id:
          type: integer
          nullable: true
        actor_email:
          type: string
          nullable: true
        actor_name:
          type: string
          nullable: true
        action:
          type: string
          description: Stable action id string.
          examples:
            - policy.capture_snapshot_dispatched
        resource_type:
          type: string
          nullable: true
        resource_id:
          type: string
          nullable: true
        status:
          type: string
          enum: [success]
        metadata:
          type: object
          description: Sanitized metadata payload.
          additionalProperties: true
        recorded_at:
          type: string
          format: date-time
