openapi: 3.0.3
info:
  title: TenantPilot Admin — Support Diagnostic Bundle (Conceptual)
  version: 0.1.0
  description: |
    Conceptual HTTP contract for the first support-diagnostics slice.

    NOTE: These flows are implemented as Filament (Livewire) header actions on
    existing pages. The exact Livewire request payload is not part of this
    contract; this file captures the user-visible surfaces, authorization
    semantics, and the derived bundle view model.
servers:
  - url: /admin
paths:
  /t/{tenant}/support-diagnostics/actions/open:
    post:
      summary: Open support diagnostics from the tenant dashboard
      description: |
        Read-only support-diagnostic action on the existing tenant dashboard.

        Authorization:
        - Workspace non-member or non-entitled tenant actor: 404
        - Entitled tenant member without `support_diagnostics.view`: 403
        - Authorized actor: 200 with a derived, redacted support bundle

        Behavior:
        - No persisted support pack is created
        - Rendering stays DB-only for this slice and performs no outbound HTTP
        - No provider-backed work, queue work, or new `OperationRun` is dispatched
        - No raw provider payload or unrestricted log export is returned
        - One redacted audit entry is recorded for bundle-open activity
      parameters:
        - name: tenant
          in: path
          required: true
          schema:
            type: string
          description: Filament tenancy slug (`tenants.external_id`)
      responses:
        '200':
          description: Support diagnostic preview rendered
          content:
            text/html:
              schema:
                type: string
          x-logical-view-model:
            $ref: '#/components/schemas/SupportDiagnosticBundleView'
        '403':
          description: Forbidden (entitled tenant member lacks support-diagnostics capability)
        '404':
          description: Not found (wrong workspace, non-member, or missing tenant entitlement)
  /operations/{run}/support-diagnostics/actions/open:
    post:
      summary: Open support diagnostics from the canonical operation detail page
      description: |
        Read-only support-diagnostic action on the canonical tenantless operation
        detail viewer.

        Authorization:
        - Inaccessible run under `OperationRunPolicy`: 404
        - Authorized member without `support_diagnostics.view`: 403
        - Authorized actor: 200 with a derived, redacted support bundle

        Behavior:
        - The action is only available when the canonical run detail resolves to an entitled tenant scope
        - Reuses existing humanized operation explanation and canonical links
        - Rendering stays DB-only for this slice and performs no outbound HTTP
        - Does not create, update, or complete an `OperationRun`
        - Does not dispatch provider-backed work, queue work, or queued operation UX side effects
        - Records one redacted audit entry for bundle-open activity
      parameters:
        - name: run
          in: path
          required: true
          schema:
            type: integer
          description: Internal `operation_runs.id`
      responses:
        '200':
          description: Support diagnostic preview rendered
          content:
            text/html:
              schema:
                type: string
          x-logical-view-model:
            $ref: '#/components/schemas/SupportDiagnosticBundleView'
        '403':
          description: Forbidden (authorized member lacks support-diagnostics capability)
        '404':
          description: Not found (run inaccessible under workspace or tenant scope)
components:
  schemas:
    SupportDiagnosticBundleView:
      type: object
      required:
        - context
        - summary
        - sections
        - redaction
      properties:
        context:
          $ref: '#/components/schemas/SupportDiagnosticContext'
        summary:
          $ref: '#/components/schemas/SupportDiagnosticSummary'
        sections:
          type: array
          items:
            $ref: '#/components/schemas/SupportDiagnosticSection'
        redaction:
          $ref: '#/components/schemas/SupportDiagnosticRedaction'
        notes:
          type: array
          items:
            type: string
        audit:
          type: object
          required:
            - action
            - outcome
          properties:
            action:
              type: string
            outcome:
              type: string
            tenant_id:
              type: integer
              nullable: true
            operation_run_id:
              type: integer
              nullable: true
    SupportDiagnosticContext:
      type: object
      required:
        - type
        - workspace_id
      properties:
        type:
          type: string
          enum: [tenant, operation_run]
        workspace_id:
          type: integer
        tenant_id:
          type: integer
          nullable: true
        operation_run_id:
          type: integer
          nullable: true
        tenant_label:
          type: string
          nullable: true
        workspace_label:
          type: string
          nullable: true
    SupportDiagnosticSummary:
      type: object
      required:
        - headline
        - dominant_issue
        - freshness_state
        - redaction_note
      properties:
        headline:
          type: string
        dominant_issue:
          type: string
        freshness_state:
          type: string
          enum: [fresh, stale, mixed, missing_context]
        completeness_note:
          type: string
          nullable: true
        redaction_note:
          type: string
        generated_from:
          type: string
          enum: [derived_existing_truth]
    SupportDiagnosticSection:
      type: object
      required:
        - key
        - label
        - availability
        - summary
        - references
      properties:
        key:
          type: string
          enum:
            - overview
            - provider_connection
            - operation_context
            - findings
            - stored_reports
            - tenant_review
            - review_pack
            - audit_history
        label:
          type: string
        availability:
          type: string
          enum: [available, missing, stale, inaccessible, redacted]
        summary:
          type: string
        freshness_note:
          type: string
          nullable: true
        references:
          type: array
          items:
            $ref: '#/components/schemas/SupportDiagnosticReference'
        redaction_markers:
          type: array
          items:
            $ref: '#/components/schemas/RedactionMarker'
    SupportDiagnosticReference:
      type: object
      required:
        - type
        - label
        - action_label
        - availability
      properties:
        type:
          type: string
          enum:
            - tenant
            - operation_run
            - provider_connection
            - finding
            - stored_report
            - tenant_review
            - review_pack
            - audit_log
        record_id:
          type: string
          nullable: true
        label:
          type: string
        action_label:
          type: string
        url:
          type: string
          nullable: true
        availability:
          type: string
          enum: [available, missing, inaccessible]
        freshness_note:
          type: string
          nullable: true
        access_reason:
          type: string
          nullable: true
    SupportDiagnosticRedaction:
      type: object
      required:
        - mode
        - markers
      properties:
        mode:
          type: string
          enum: [default_redacted]
        markers:
          type: array
          items:
            $ref: '#/components/schemas/RedactionMarker'
    RedactionMarker:
      type: object
      required:
        - reason
        - replacement_text
      properties:
        path:
          type: string
          nullable: true
        reason:
          type: string
          enum:
            - secret
            - credential
            - raw_payload
            - restricted_log_excerpt
            - inaccessible_record
        replacement_text:
          type: string