openapi: 3.0.3
info:
  title: TenantPilot Tenant Dashboard Productization v1 (Conceptual)
  version: 0.1.0
  description: |
    Conceptual contract for the tenant dashboard productization slice in Spec 266.

    NOTE: These paths describe existing tenant and admin routes reused by the
    implementation. The schemas document expected derived page and view behavior
    for planning purposes only; they do not require a new public REST API.
servers:
  - url: /
paths:
  /admin/t/{tenant}:
    get:
      summary: View the productized tenant dashboard
      description: |
        Existing tenant-scoped dashboard route reused as the canonical tenant
        landing page. The implementation stays read-mostly and reuses existing
        findings, exception, review, evidence, review-pack, permissions,
        recovery, and operation truth.
      parameters:
        - in: path
          name: tenant
          required: true
          schema:
            type: string
          description: Tenant id or external id already accepted by the tenant panel.
      responses:
        '200':
          description: Tenant dashboard rendered
          content:
            text/html:
              schema:
                type: string
            application/json:
              schema:
                $ref: '#/components/schemas/TenantDashboardPageModel'
        '404':
          description: Not found for non-members or out-of-scope tenant requests

  /admin/governance/inbox:
    get:
      summary: Open the canonical governance inbox from the tenant dashboard
      description: |
        Existing admin-plane governance queue reused as a canonical follow-up
        destination. The dashboard may launch it with a tenant prefilter and an
        optional family filter.
      parameters:
        - in: query
          name: tenant_id
          required: false
          schema:
            type: string
        - in: query
          name: family
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Governance inbox rendered
          content:
            text/html:
              schema:
                type: string
        '403':
          description: Forbidden when the current workspace scope has no visible governance family
        '404':
          description: Not found for non-members or out-of-scope tenant filters

  /admin/operations:
    get:
      summary: Open canonical operations from the tenant dashboard
      description: |
        Existing canonical operations surface reused for recent-operation and
        operation follow-up links. The dashboard preserves tenant-prefilter
        continuity with the current query-state contract.
      parameters:
        - in: query
          name: tenant_id
          required: false
          schema:
            type: string
        - in: query
          name: tenant_scope
          required: false
          schema:
            type: string
        - in: query
          name: problemClass
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Operations page rendered
          content:
            text/html:
              schema:
                type: string
        '404':
          description: Not found for non-members or tenant filters outside entitled scope

  /admin/t/{tenant}/findings:
    get:
      summary: Open tenant findings from the dashboard
      description: Existing tenant findings list reused by KPI and recommended-action follow-up links.
      parameters:
        - in: path
          name: tenant
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Findings list rendered
          content:
            text/html:
              schema:
                type: string
        '403':
          description: Forbidden for an in-scope actor missing findings capability
        '404':
          description: Not found for non-members or out-of-scope tenant requests

  /admin/t/{tenant}/finding-exceptions:
    get:
      summary: Open tenant risk exceptions from the dashboard
      description: Existing tenant exception list reused for risk and pending-decision follow-up.
      parameters:
        - in: path
          name: tenant
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Finding exception list rendered
          content:
            text/html:
              schema:
                type: string
        '403':
          description: Forbidden for an in-scope actor missing exception capability
        '404':
          description: Not found for non-members or out-of-scope tenant requests

  /admin/tenants/{tenant}/required-permissions:
    get:
      summary: Open required permissions from the dashboard
      description: Existing required-permissions route reused for provider-health follow-up.
      parameters:
        - in: path
          name: tenant
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Required permissions page rendered
          content:
            text/html:
              schema:
                type: string
        '403':
          description: Forbidden for an in-scope actor missing capability
        '404':
          description: Not found for non-members or out-of-scope tenant requests

  /admin/reviews/workspace:
    get:
      summary: Open customer-safe review workspace from the tenant dashboard
      description: Existing review workspace reused for output-readiness follow-up when the actor is entitled.
      parameters:
        - in: query
          name: tenant
          required: false
          schema:
            type: string
      responses:
        '200':
          description: Customer review workspace rendered
          content:
            text/html:
              schema:
                type: string
        '404':
          description: Not found for non-members or tenants outside current scope

  /admin/t/{tenant}/reviews:
    get:
      summary: Open tenant reviews from the dashboard
      description: Existing tenant review resource reused for review drill-through and current review continuity.
      parameters:
        - in: path
          name: tenant
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Tenant reviews list or detail entry rendered
          content:
            text/html:
              schema:
                type: string
        '403':
          description: Forbidden for an in-scope actor missing review capability
        '404':
          description: Not found for non-members or out-of-scope tenant requests

  /admin/t/{tenant}/review-packs:
    get:
      summary: Open tenant review packs from the dashboard
      description: Existing review-pack resource reused for output-package continuity.
      parameters:
        - in: path
          name: tenant
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Review packs list or detail entry rendered
          content:
            text/html:
              schema:
                type: string
        '403':
          description: Forbidden for an in-scope actor missing review-pack capability
        '404':
          description: Not found for non-members or out-of-scope tenant requests

  /admin/t/{tenant}/evidence:
    get:
      summary: Open tenant evidence snapshots from the dashboard
      description: Existing evidence resource reused for evidence-readiness follow-up.
      parameters:
        - in: path
          name: tenant
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Evidence snapshots list or detail entry rendered
          content:
            text/html:
              schema:
                type: string
        '403':
          description: Forbidden for an in-scope actor missing evidence capability
        '404':
          description: Not found for non-members or out-of-scope tenant requests

components:
  schemas:
    TenantDashboardPageModel:
      type: object
      required:
        - workspace
        - tenant
        - header_actions
        - kpis
        - recommended_actions
        - governance_status_rows
        - recent_operations
      properties:
        workspace:
          $ref: '#/components/schemas/ContextLabel'
        tenant:
          $ref: '#/components/schemas/ContextLabel'
        context_chips:
          type: array
          items:
            $ref: '#/components/schemas/ContextChip'
        arrival_context:
          $ref: '#/components/schemas/ArrivalContext'
          nullable: true
        header_actions:
          type: array
          maxItems: 2
          items:
            $ref: '#/components/schemas/DashboardAction'
        kpis:
          type: array
          maxItems: 4
          items:
            $ref: '#/components/schemas/KpiCard'
        recommended_actions:
          type: array
          maxItems: 3
          items:
            $ref: '#/components/schemas/RecommendedAction'
        governance_status_rows:
          type: array
          items:
            $ref: '#/components/schemas/GovernanceStatusRow'
        recent_operations:
          type: array
          maxItems: 4
          items:
            $ref: '#/components/schemas/RecentOperationRow'
        current_review:
          $ref: '#/components/schemas/SummaryCard'
          nullable: true
        risk_exception_summary:
          $ref: '#/components/schemas/SummaryCard'
          nullable: true
        provider_health_summary:
          $ref: '#/components/schemas/SummaryCard'
          nullable: true
        output_readiness_summary:
          $ref: '#/components/schemas/SummaryCard'
          nullable: true

    ContextLabel:
      type: object
      required:
        - label
        - value
      properties:
        label:
          type: string
        value:
          type: string

    ContextChip:
      type: object
      required:
        - label
      properties:
        label:
          type: string
        value:
          type: string
          nullable: true

    ArrivalContext:
      type: object
      properties:
        title:
          type: string
        body:
          type: string
        action:
          $ref: '#/components/schemas/DashboardAction'
          nullable: true

    DashboardAction:
      type: object
      required:
        - label
        - style
        - availability_state
      properties:
        label:
          type: string
        style:
          type: string
          enum:
            - primary
            - secondary
        availability_state:
          type: string
          enum:
            - available
            - unavailable
            - absent
        url:
          type: string
          nullable: true
        helper_text:
          type: string
          nullable: true

    KpiCard:
      type: object
      required:
        - key
        - label
        - value
        - status_label
      properties:
        key:
          type: string
        label:
          type: string
        value:
          type: string
        supporting_text:
          type: string
          nullable: true
        status_label:
          type: string
        badge_state:
          type: string
          nullable: true
        trend_label:
          type: string
          nullable: true
        primary_link:
          $ref: '#/components/schemas/DashboardAction'
          nullable: true

    RecommendedAction:
      type: object
      required:
        - priority
        - title
        - reason
        - impact
        - cta
      properties:
        priority:
          type: integer
        category:
          type: string
          nullable: true
        title:
          type: string
        reason:
          type: string
        impact:
          type: string
        cta:
          $ref: '#/components/schemas/DashboardAction'

    GovernanceStatusRow:
      type: object
      required:
        - key
        - label
        - description
        - status_label
      properties:
        key:
          type: string
        label:
          type: string
        description:
          type: string
        status_label:
          type: string
        badge_state:
          type: string
          nullable: true
        support_link:
          $ref: '#/components/schemas/DashboardAction'
          nullable: true

    RecentOperationRow:
      type: object
      required:
        - operation_run_id
        - label
        - relative_time
      properties:
        operation_run_id:
          type: integer
        label:
          type: string
        status_label:
          type: string
          nullable: true
        outcome_label:
          type: string
          nullable: true
        relative_time:
          type: string
        summary_text:
          type: string
          nullable: true
        detail_url:
          type: string
          nullable: true

    SummaryCard:
      type: object
      required:
        - title
        - availability_state
      properties:
        title:
          type: string
        headline:
          type: string
          nullable: true
        supporting_lines:
          type: array
          items:
            type: string
        availability_state:
          type: string
          enum:
            - available
            - unavailable
            - absent
        cta:
          $ref: '#/components/schemas/DashboardAction'
          nullable: true
        helper_text:
          type: string
          nullable: true