TenantAtlas/specs/173-tenant-dashboard-truth-alignment/contracts/tenant-dashboard-truth-alignment.openapi.yaml
2026-04-03 21:15:29 +02:00

553 lines
16 KiB
YAML

openapi: 3.1.0
info:
title: Tenant Dashboard Truth Alignment Internal Surface Contract
version: 0.1.0
summary: Internal logical contract for aligned tenant dashboard KPI, attention, compare, and recency surfaces
description: |
This contract is an internal planning artifact for Spec 173. It documents how
the tenant dashboard's summary and recency surfaces must derive their meaning
from existing tenant truth and how drill-through destinations must preserve
that meaning. 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-dashboard-consumers:
- surface: tenant.dashboard.kpis
summarySource:
- finding_status_helpers
- finding_destination_filters
- canonical_operations_links
guardScope:
- app/Filament/Widgets/Dashboard/DashboardKpis.php
expectedContract:
- each_kpi_label_matches_its_count_universe
- each_kpi_destination_reproduces_or_explicitly_broadens_the_named_subset
- surface: tenant.dashboard.needs_attention
summarySource:
- tenant_governance_aggregate
- operation_run_activity
guardScope:
- app/Filament/Widgets/Dashboard/NeedsAttention.php
expectedContract:
- each_primary_item_has_one_tenant_safe_destination
- healthy_fallback_is_hidden_when_any_attention_condition_exists
- surface: tenant.dashboard.baseline_compare_now
summarySource:
- tenant_governance_aggregate
- baseline_compare_summary_assessment
guardScope:
- app/Filament/Widgets/Dashboard/BaselineCompareNow.php
expectedContract:
- positive_compare_claims_do_not_outvote_stronger_attention_conditions
- primary_compare_destination_uses_existing_baseline_compare_landing
- surface: tenant.dashboard.recent_drift_findings
summarySource:
- recent_drift_query
guardScope:
- app/Filament/Widgets/Dashboard/RecentDriftFindings.php
expectedContract:
- surface_role_is_diagnostic_recency_not_primary_queue
- row_click_uses_canonical_finding_detail
- surface: tenant.dashboard.recent_operations
summarySource:
- recent_operations_query
- canonical_operations_links
guardScope:
- app/Filament/Widgets/Dashboard/RecentOperations.php
expectedContract:
- surface_role_is_diagnostic_recency_not_primary_queue
- row_click_uses_canonical_operation_detail
paths:
/admin/t/{tenant}:
get:
summary: Render the aligned tenant dashboard summary bundle
operationId: viewTenantDashboardAlignedTruth
parameters:
- name: tenant
in: path
required: true
schema:
type: string
responses:
'200':
description: Tenant dashboard rendered with aligned KPI, attention, compare, and recency semantics
content:
text/html:
schema:
type: string
application/vnd.tenantpilot.tenant-dashboard-truth+json:
schema:
$ref: '#/components/schemas/TenantDashboardTruthBundle'
'404':
description: Tenant is outside workspace or tenant entitlement scope
/admin/t/{tenant}/findings:
get:
summary: Tenant findings destination used by KPI and attention drill-throughs
operationId: openTenantFindingsFromDashboard
parameters:
- name: tenant
in: path
required: true
schema:
type: string
- name: tab
in: query
required: false
schema:
$ref: '#/components/schemas/FindingsTab'
- name: high_severity
in: query
required: false
schema:
type: boolean
- name: status
in: query
required: false
schema:
type: string
- name: finding_type
in: query
required: false
schema:
type: string
responses:
'200':
description: Tenant findings list opened with tenant-safe dashboard continuity filters
'403':
description: Actor is in scope but lacks findings inspection capability
'404':
description: Tenant is outside workspace or tenant entitlement scope
/admin/t/{tenant}/baseline-compare-landing:
get:
summary: Tenant baseline compare landing used by compare and attention drill-throughs
operationId: openTenantBaselineCompareLandingFromDashboard
parameters:
- name: tenant
in: path
required: true
schema:
type: string
responses:
'200':
description: Tenant baseline compare landing opened with the same tenant-context compare posture the dashboard summarized
'403':
description: Actor is in scope but lacks baseline compare inspection capability
'404':
description: Tenant is outside workspace or tenant entitlement scope
/admin/t/{tenant}/findings/{record}:
get:
summary: Tenant finding detail opened from recent drift row-click inspection
operationId: openTenantFindingDetailFromDashboardRecency
parameters:
- name: tenant
in: path
required: true
schema:
type: string
- name: record
in: path
required: true
schema:
type: string
responses:
'200':
description: Tenant finding detail opened from the recent drift diagnostic surface
'403':
description: Actor is in scope but lacks finding detail inspection capability
'404':
description: Tenant or finding is outside entitlement scope
/admin/operations:
get:
summary: Canonical operations destination with tenant-prefilter continuity from the tenant dashboard
operationId: openCanonicalOperationsFromDashboard
parameters:
- name: tenant_id
in: query
required: false
schema:
type:
- integer
- string
description: Tenant filter carried forward from tenant-context dashboard navigation.
- name: activeTab
in: query
required: false
description: Uses `active` for healthy queued or running activity, `blocked` for warning, stalled, or unusually long-running follow-up needing review, and `failed` for terminal failure follow-up.
schema:
$ref: '#/components/schemas/OperationsTab'
- name: navigationContext
in: query
required: false
schema:
type: string
description: Optional serialized canonical navigation context carried from tenant dashboard drill-throughs.
responses:
'200':
description: Canonical admin operations list filtered to the originating tenant when opened from the dashboard
'403':
description: Actor is in scope but lacks operations inspection capability
'404':
description: Tenant context is outside entitlement scope
/admin/operations/{run}:
get:
summary: Canonical operation detail opened from recent operations row-click inspection
operationId: openOperationDetailFromDashboardRecency
parameters:
- name: run
in: path
required: true
schema:
type:
- integer
- string
responses:
'200':
description: Canonical operation detail opened from the recent operations diagnostic surface
'403':
description: Actor is in scope but lacks operation detail inspection capability
'404':
description: Operation run is outside entitlement scope
components:
schemas:
FindingsTab:
type: string
enum:
- all
- needs_action
- overdue
- risk_accepted
- resolved
OperationsTab:
type: string
description: Shared canonical operations tab semantics where `active` represents healthy queued or running work, `blocked` reproduces warning, stalled, or unusually long-running follow-up, and `failed` reproduces terminal failure follow-up.
enum:
- all
- active
- blocked
- succeeded
- partial
- failed
ProblemFamily:
type: string
enum:
- findings
- governance
- compare
- operations
FindingUniverse:
type: string
enum:
- new_drift_only
- open_drift
- active_findings
SeverityUniverse:
type: string
enum:
- high_only
- high_and_critical
FindingsDestinationFilterState:
type: object
additionalProperties: false
required:
- tenant
properties:
tenant:
type: string
tab:
oneOf:
- $ref: '#/components/schemas/FindingsTab'
- type: 'null'
status:
type:
- string
- 'null'
high_severity:
type:
- boolean
- 'null'
finding_type:
type:
- string
- 'null'
OperationsDestinationFilterState:
type: object
additionalProperties: false
required:
- workspace_id
- tenant_id
properties:
workspace_id:
type: integer
tenant_id:
type:
- integer
- string
activeTab:
oneOf:
- $ref: '#/components/schemas/OperationsTab'
- type: 'null'
navigationContext:
type:
- string
- 'null'
DestinationKind:
type: string
enum:
- tenant_findings
- baseline_compare_landing
- canonical_operations
- operation_detail
- finding_detail
- none
SurfaceDestination:
type: object
additionalProperties: false
allOf:
- if:
properties:
actionDisabled:
const: true
then:
required:
- helperText
required:
- kind
- tenantScoped
- semanticsLabel
properties:
kind:
$ref: '#/components/schemas/DestinationKind'
tenantScoped:
type: boolean
semanticsLabel:
type: string
filterState:
oneOf:
- $ref: '#/components/schemas/FindingsDestinationFilterState'
- $ref: '#/components/schemas/OperationsDestinationFilterState'
- type: 'null'
actionDisabled:
type:
- boolean
- 'null'
helperText:
type:
- string
- 'null'
ActionableDestinationKind:
type: string
enum:
- tenant_findings
- baseline_compare_landing
- canonical_operations
KpiDestinationKind:
type: string
enum:
- tenant_findings
- canonical_operations
- none
ActionableSurfaceDestination:
allOf:
- $ref: '#/components/schemas/SurfaceDestination'
- type: object
properties:
kind:
$ref: '#/components/schemas/ActionableDestinationKind'
KpiSurfaceDestination:
allOf:
- $ref: '#/components/schemas/SurfaceDestination'
- type: object
properties:
kind:
$ref: '#/components/schemas/KpiDestinationKind'
KpiMetric:
type: object
additionalProperties: false
required:
- key
- label
- count
- problemFamily
- destination
properties:
key:
type: string
label:
type: string
count:
type: integer
minimum: 0
problemFamily:
type: string
enum:
- findings
- operations
findingUniverse:
oneOf:
- $ref: '#/components/schemas/FindingUniverse'
- type: 'null'
severityUniverse:
oneOf:
- type: string
enum:
- high_only
- high_and_critical
- type: 'null'
destination:
$ref: '#/components/schemas/KpiSurfaceDestination'
AttentionItem:
type: object
additionalProperties: false
anyOf:
- required:
- actionLabel
- required:
- nextStepLabel
- properties:
actionDisabled:
const: true
required:
- actionDisabled
- helperText
required:
- key
- title
- body
- badge
- tone
- problemFamily
- destination
properties:
key:
type: string
title:
type: string
body:
type: string
supportingMessage:
type:
- string
- 'null'
badge:
type: string
tone:
type: string
enum:
- success
- warning
- danger
- info
- gray
problemFamily:
$ref: '#/components/schemas/ProblemFamily'
actionLabel:
type:
- string
- 'null'
actionDisabled:
type:
- boolean
- 'null'
helperText:
type:
- string
- 'null'
nextStepLabel:
type:
- string
- 'null'
destination:
$ref: '#/components/schemas/ActionableSurfaceDestination'
CompareSummary:
type: object
additionalProperties: false
required:
- stateFamily
- tone
- headline
- positiveClaimAllowed
- nextAction
properties:
stateFamily:
type: string
enum:
- positive
- caution
- stale
- action_required
- in_progress
- unavailable
tone:
type: string
enum:
- success
- warning
- danger
- info
- gray
headline:
type: string
supportingMessage:
type:
- string
- 'null'
positiveClaimAllowed:
type: boolean
nextAction:
$ref: '#/components/schemas/SurfaceDestination'
DiagnosticSurfaceSummary:
type: object
additionalProperties: false
required:
- heading
- role
- doesNotDefinePosture
- fullRowClick
- detailDestinationKind
properties:
heading:
type: string
role:
type: string
enum:
- diagnostic_recency
doesNotDefinePosture:
type: boolean
fullRowClick:
type: boolean
detailDestinationKind:
type: string
enum:
- finding_detail
- operation_detail
TenantDashboardTruthBundle:
type: object
additionalProperties: false
required:
- tenantId
- workspaceId
- kpis
- attentionItems
- compareSummary
- recentFindings
- recentOperations
properties:
tenantId:
type: integer
workspaceId:
type: integer
kpis:
type: array
items:
$ref: '#/components/schemas/KpiMetric'
attentionItems:
type: array
items:
$ref: '#/components/schemas/AttentionItem'
compareSummary:
$ref: '#/components/schemas/CompareSummary'
recentFindings:
$ref: '#/components/schemas/DiagnosticSurfaceSummary'
recentOperations:
$ref: '#/components/schemas/DiagnosticSurfaceSummary'