openapi: 3.0.3
info:
  title: TenantPilot Provider-Missing Policy Visibility & Restore Continuity v1 (Conceptual)
  version: 0.1.0
  description: |
    Conceptual contract for the Provider-Missing Policy Visibility & Restore
    Continuity v1 planning package.

    These paths describe existing Filament admin and tenant-scoped routes reused by
    implementation. The schemas document the derived policy-presence, current
    backup-eligibility, and historical restore-continuity contract expected over
    existing policy, backup, and restore truth; they do not define a new public
    REST API.
servers:
  - url: /
paths:
  /admin/t/{tenant}/policies:
    get:
      summary: View tenant policies with distinct local-ignore and provider-missing states
      parameters:
        - in: path
          name: tenant
          required: true
          schema:
            type: integer
        - in: query
          name: visibility
          required: false
          description: |
            `ignored` includes both `ignored_locally` and
            `ignored_locally_provider_missing`. `provider_missing` includes both
            `provider_missing` and `ignored_locally_provider_missing`.
          schema:
            type: string
            enum:
              - active
              - ignored
              - provider_missing
              - all
      responses:
        '200':
          description: Policy list rendered
          content:
            text/html:
              schema:
                type: string
            application/json:
              schema:
                $ref: '#/components/schemas/PolicyIndexPageModel'
        '403':
          description: Forbidden for an in-scope actor missing the existing policy capability
        '404':
          description: Not found for non-members, tenant mismatches, or out-of-scope targets

  /admin/t/{tenant}/policies/{policy}:
    get:
      summary: View one tenant policy with provider-presence continuity context
      parameters:
        - in: path
          name: tenant
          required: true
          schema:
            type: integer
        - in: path
          name: policy
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Policy detail rendered
          content:
            text/html:
              schema:
                type: string
            application/json:
              schema:
                $ref: '#/components/schemas/PolicyDetailModel'
        '403':
          description: Forbidden for an in-scope actor missing the existing policy capability
        '404':
          description: Not found for non-members, tenant mismatches, or inaccessible policy targets

  /admin/t/{tenant}/backup-sets/create:
    get:
      summary: Open current backup selection with provider-missing eligibility rules
      parameters:
        - in: path
          name: tenant
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: Backup-set creation surface rendered
          content:
            text/html:
              schema:
                type: string
            application/json:
              schema:
                $ref: '#/components/schemas/BackupSelectionModel'
        '403':
          description: Forbidden for an in-scope actor missing the existing backup capability
        '404':
          description: Not found for non-members, tenant mismatches, or out-of-scope targets

  /admin/t/{tenant}/restore-runs/create:
    get:
      summary: Open restore item selection with historical continuity for provider-missing policies
      parameters:
        - in: path
          name: tenant
          required: true
          schema:
            type: integer
        - in: query
          name: backup_set_id
          required: false
          schema:
            type: integer
      responses:
        '200':
          description: Restore-run creation surface rendered
          content:
            text/html:
              schema:
                type: string
            application/json:
              schema:
                $ref: '#/components/schemas/RestoreSelectionModel'
        '403':
          description: Forbidden for an in-scope actor missing the existing restore capability
        '404':
          description: Not found for non-members, tenant mismatches, or inaccessible backup targets

components:
  schemas:
    PolicyVisibilityState:
      type: string
      description: |
        Combined state remains explicit as `ignored_locally_provider_missing`.
        List filters continue to expose it through both the `ignored` and
        `provider_missing` filter tokens.
      enum:
        - active
        - ignored_locally
        - provider_missing
        - ignored_locally_provider_missing

    PolicyActionEligibility:
      type: object
      required:
        - can_sync
        - can_export_current
        - can_restore_history
      properties:
        can_sync:
          type: boolean
        can_export_current:
          type: boolean
        can_restore_history:
          type: boolean
        blocked_reason:
          type: string
          nullable: true
          description: |
            Primary current-state action blocker. When both `ignored_at` and
            `missing_from_provider_at` are present, this resolves to
            `provider_missing` because fresh provider-backed capture is not
            possible; local ignore remains secondary context.
          enum:
            - ignored_locally
            - provider_missing

    PolicyListRow:
      type: object
      required:
        - id
        - display_name
        - policy_type
        - visibility_state
        - action_eligibility
      properties:
        id:
          type: integer
        display_name:
          type: string
        policy_type:
          type: string
        visibility_state:
          $ref: '#/components/schemas/PolicyVisibilityState'
        ignored_at:
          type: string
          format: date-time
          nullable: true
        missing_from_provider_at:
          type: string
          format: date-time
          nullable: true
        last_synced_at:
          type: string
          format: date-time
          nullable: true
        action_eligibility:
          $ref: '#/components/schemas/PolicyActionEligibility'

    PolicyIndexPageModel:
      type: object
      required:
        - rows
      properties:
        rows:
          type: array
          items:
            $ref: '#/components/schemas/PolicyListRow'

    PolicyDetailModel:
      type: object
      required:
        - policy
        - historical_restore_available
      properties:
        policy:
          $ref: '#/components/schemas/PolicyListRow'
        historical_restore_available:
          type: boolean
        continuity_message:
          type: string
          nullable: true

    BackupSelectionRow:
      type: object
      required:
        - policy_id
        - label
        - eligible
      properties:
        policy_id:
          type: integer
        label:
          type: string
        eligible:
          type: boolean
        blocked_reason:
          type: string
          nullable: true
          description: |
            Primary current backup blocker. When a policy is both locally ignored
            and provider-missing, this remains `provider_missing` because current
            capture cannot proceed.
          enum:
            - ignored_locally
            - provider_missing
        secondary_local_ignore:
          type: boolean
          description: |
            True when the row is also locally ignored. This remains secondary
            context when `blocked_reason` resolves to `provider_missing`.
        historical_continuity_available:
          type: boolean

    BackupSelectionModel:
      type: object
      required:
        - rows
      properties:
        rows:
          type: array
          items:
            $ref: '#/components/schemas/BackupSelectionRow'

    RestoreSelectionRow:
      type: object
      required:
        - backup_item_id
        - label
        - selectable
      properties:
        backup_item_id:
          type: integer
        label:
          type: string
        selectable:
          type: boolean
        provider_missing_notice:
          type: boolean
        continuity_message:
          type: string
          nullable: true

    RestoreSelectionModel:
      type: object
      required:
        - rows
      properties:
        rows:
          type: array
          items:
            $ref: '#/components/schemas/RestoreSelectionRow'