TenantAtlas/specs/185-workspace-recovery-posture-visibility/contracts/workspace-recovery-posture-visibility.openapi.yaml

306 lines
9.2 KiB
YAML

openapi: 3.1.0
info:
title: Workspace Recovery Posture Visibility Internal Surface Contract
version: 0.1.0
summary: Internal logical contract for backup-health and recovery-evidence visibility on the workspace overview
description: |
This contract is an internal planning artifact for Spec 185. It documents how
the existing workspace overview must derive backup-health and recovery-evidence
metrics, attention items, calmness, and tenant-dashboard drillthroughs from
visible tenant truth. The rendered routes still return HTML. The structured
schemas below describe the internal page and widget models that must be
derivable before rendering. This does not add a public HTTP API.
servers:
- url: /internal
x-overview-consumers:
- surface: workspace.overview.summary_stats
summarySource:
- workspace_overview_builder
- tenant_backup_health_resolver
- restore_safety_resolver_dashboard_recovery_evidence
- existing_governance_metrics
- existing_activity_metrics
guardScope:
- app/Support/Workspaces/WorkspaceOverviewBuilder.php
- app/Filament/Widgets/Workspace/WorkspaceSummaryStats.php
expectedContract:
- backup_attention_and_recovery_attention_are_separate_metrics
- counts_are_visible_tenant_counts_not_raw_issue_totals
- single_tenant_metric_destinations_may_open_that_tenant_dashboard
- multi_tenant_metric_destinations_fall_back_to_choose_tenant
- surface: workspace.overview.needs_attention
summarySource:
- workspace_overview_builder
- tenant_backup_health_resolver
- restore_safety_resolver_dashboard_recovery_evidence
- existing_governance_attention
- existing_operations_attention
guardScope:
- app/Support/Workspaces/WorkspaceOverviewBuilder.php
- app/Filament/Widgets/Workspace/WorkspaceNeedsAttention.php
- resources/views/filament/widgets/workspace/workspace-needs-attention.blade.php
expectedContract:
- backup_health_and_recovery_evidence_items_are_tenant_bound
- new_items_use_tenant_dashboard_as_primary_destination
- backup_and_recovery_items_rank_above_activity_only_signals
- no_item_claims_workspace_recovery_is_proven
- hidden_tenants_never_leak_through_labels_or_reason_text
- surface: workspace.overview.calmness
summarySource:
- workspace_overview_builder
- tenant_backup_health_resolver
- restore_safety_resolver_dashboard_recovery_evidence
- existing_workspace_calmness_inputs
guardScope:
- app/Support/Workspaces/WorkspaceOverviewBuilder.php
- resources/views/filament/pages/workspace-overview.blade.php
expectedContract:
- checked_domains_include_backup_health_and_recovery_evidence
- calmness_is_false_when_any_visible_backup_or_recovery_issue_exists
- calmness_is_explicitly_bounded_to_visible_tenants
paths:
/admin:
get:
summary: Render the workspace overview with backup-health and recovery-evidence visibility
operationId: viewWorkspaceRecoveryPostureOverview
responses:
'200':
description: Workspace overview rendered with visible-tenant backup and recovery metrics, attention, and calmness semantics
content:
text/html:
schema:
type: string
application/vnd.tenantpilot.workspace-recovery-posture-visibility+json:
schema:
$ref: '#/components/schemas/WorkspaceRecoveryOverviewBundle'
'302':
description: No workspace context is active yet, so the request redirects to `/admin/choose-workspace`
'404':
description: Workspace is outside entitlement scope
/admin/choose-tenant:
get:
summary: Deliberate tenant-entry destination used by multi-tenant workspace backup or recovery metrics
operationId: openChooseTenantFromWorkspaceRecoveryOverview
responses:
'200':
description: Choose-tenant page opened inside the current workspace context so the operator can pick a tenant deliberately
/admin/t/{tenant}:
get:
summary: Canonical tenant-dashboard drillthrough for workspace backup or recovery posture items
operationId: openTenantDashboardFromWorkspaceRecoveryOverview
parameters:
- name: tenant
in: path
required: true
schema:
type: string
responses:
'200':
description: Tenant dashboard opened for the visible tenant named by the workspace item
'404':
description: Tenant is outside entitlement scope
components:
schemas:
MetricCategory:
type: string
enum:
- scope
- governance_risk
- backup_health
- recovery_evidence
- activity
- alerts
WorkspaceMetricKey:
type: string
enum:
- accessible_tenants
- governance_attention_tenants
- backup_attention_tenants
- recovery_attention_tenants
- active_operations
- alert_failures
AttentionFamily:
type: string
enum:
- governance
- findings
- compare
- backup_health
- recovery_evidence
- operations
- alerts
- evidence
- review
AttentionUrgency:
type: string
enum:
- critical
- high
- medium
- supporting
DestinationKind:
type: string
enum:
- choose_tenant
- switch_workspace
- tenant_dashboard
- tenant_findings
- baseline_compare_landing
- operations_index
- alerts_overview
- tenant_evidence
- tenant_reviews
CalmnessCheckedDomain:
type: string
enum:
- tenant_access
- governance
- findings
- compare
- backup_health
- recovery_evidence
- operations
- alerts
WorkspaceRecoveryOverviewBundle:
type: object
required:
- accessible_tenant_count
- summary_metrics
- attention_items
- calmness
properties:
accessible_tenant_count:
type: integer
minimum: 0
summary_metrics:
type: array
items:
$ref: '#/components/schemas/WorkspaceSummaryMetric'
attention_items:
type: array
items:
$ref: '#/components/schemas/WorkspaceAttentionItem'
calmness:
$ref: '#/components/schemas/WorkspaceCalmness'
WorkspaceSummaryMetric:
type: object
required:
- key
- label
- value
- category
- description
properties:
key:
$ref: '#/components/schemas/WorkspaceMetricKey'
label:
type: string
value:
type: integer
minimum: 0
category:
$ref: '#/components/schemas/MetricCategory'
description:
type: string
destination:
anyOf:
- $ref: '#/components/schemas/Destination'
- type: 'null'
WorkspaceAttentionItem:
type: object
required:
- key
- tenant_id
- tenant_label
- family
- urgency
- title
- body
- destination
properties:
key:
type: string
tenant_id:
type: integer
tenant_label:
type: string
family:
$ref: '#/components/schemas/AttentionFamily'
urgency:
$ref: '#/components/schemas/AttentionUrgency'
title:
type: string
body:
type: string
supporting_message:
anyOf:
- type: string
- type: 'null'
reason_context:
anyOf:
- $ref: '#/components/schemas/ReasonContext'
- type: 'null'
destination:
$ref: '#/components/schemas/Destination'
ReasonContext:
type: object
required:
- family
- state
properties:
family:
$ref: '#/components/schemas/AttentionFamily'
state:
type: string
enum:
- absent
- stale
- degraded
- weakened
- unvalidated
reason:
anyOf:
- type: string
- type: 'null'
Destination:
type: object
required:
- kind
- label
- disabled
properties:
kind:
$ref: '#/components/schemas/DestinationKind'
label:
type: string
url:
anyOf:
- type: string
- type: 'null'
disabled:
type: boolean
helper_text:
anyOf:
- type: string
- type: 'null'
WorkspaceCalmness:
type: object
required:
- is_calm
- checked_domains
- title
- body
- next_action
properties:
is_calm:
type: boolean
checked_domains:
type: array
items:
$ref: '#/components/schemas/CalmnessCheckedDomain'
title:
type: string
body:
type: string
next_action:
$ref: '#/components/schemas/Destination'