TenantAtlas/specs/192-record-header-discipline/data-model.md
Ahmed Darrazi 72ddc18743 feat: implement spec 192 header discipline
- land the spec 192 resource, guard, browser smoke, and documentation changes
- add unhandled rejection request correlation for 419 diagnostics
- disable panel-wide database notification polling and cover it with focused tests
2026-04-11 23:09:42 +02:00

155 lines
8.5 KiB
Markdown

# Data Model: Record Page Header Discipline & Contextual Navigation
## Overview
This feature introduces no new persisted entity, table, enum, or long-lived artifact. It reuses existing Filament pages, existing action definitions, and existing authorization helpers, while adding a derived planning model for how record-page headers are classified, rendered, and regression-tested.
## Existing Source Truths Reused Without Change
The following truths remain authoritative and are not redefined by this feature:
- existing resource and page routes
- existing model ownership and scope semantics
- existing capability checks and `UiEnforcement` behavior
- existing confirmation, audit, and `OperationRun` behavior for underlying actions
- existing related-navigation truth from `RelatedNavigationResolver` and related helper methods
This feature changes action hierarchy and placement only.
## New Derived Planning Models
### HeaderSurfaceInventoryEntry
**Type**: spec and guard inventory entry
**Source**: explicit Spec 192 classification matrix + action-surface regression guard
| Field | Type | Notes |
|------|------|-------|
| `surfaceKey` | string | Stable identifier such as `baseline_profile_view` or `tenant_edit` |
| `pageClass` | string | Concrete Filament page class under review |
| `panelScope` | string | `admin`, `tenant`, or explicit special context |
| `ownerScope` | string | `workspace-owned` or `tenant-owned` |
| `classification` | string | `remediation_required`, `minor_alignment_only`, `compliant_reference`, or `workflow_heavy_special_type` |
| `canonicalNoun` | string | Stable operator-facing object noun |
| `routeKind` | string | `view` or `edit` |
| `requiresHeaderRemediation` | boolean | Whether the page must change under Spec 192 |
| `exceptionReason` | string or null | Required when classification is special-type |
### RecordHeaderLayoutState
**Type**: derived page render contract
**Source**: existing page action methods + page state + explicit Spec 192 rules
| Field | Type | Notes |
|------|------|-------|
| `surfaceKey` | string | Links the render state back to the inventory entry |
| `classification` | string | Same classification used by the inventory |
| `primaryActionKey` | string or null | The one visible primary action, if any |
| `primaryActionLabel` | string or null | Operator-facing label for the visible primary action |
| `primaryActionReason` | string | Why this action is primary for the current page state |
| `secondaryGroupLabel` | string or null | Usually `More`, `Actions`, or equivalent grouped-secondary label |
| `hasContextualNavigation` | boolean | Whether pure navigation moved to contextual placement outside the header |
| `hasSeparatedDangerActions` | boolean | Whether dangerous actions are structurally separated |
| `allowsNoPrimaryAction` | boolean | True for compliant reference pages or special types without one dominant next step |
### HeaderActionDescriptor
**Type**: derived action classification entry
**Source**: existing Filament action definitions on the target page
| Field | Type | Notes |
|------|------|-------|
| `actionKey` | string | Action name such as `capture`, `refresh_review`, or `archive` |
| `label` | string | Visible operator-facing label |
| `actionKind` | string | `navigation`, `mutation`, `external_link`, `lifecycle`, or `danger` |
| `placement` | string | `primary_visible`, `secondary_grouped`, `contextual`, or `danger_grouped` |
| `requiresConfirmation` | boolean | Mirrors existing destructive or governance friction |
| `usesUiEnforcement` | boolean | Whether the action is wrapped with a central enforcement helper |
| `capabilityKey` | string or null | Canonical capability requirement when applicable |
| `writesAuditLog` | boolean | Whether the underlying mutation writes audit truth |
| `operationScope` | string | `TenantPilot only`, `Microsoft tenant`, `simulation only`, or `read-only` |
### ContextualNavigationContract
**Type**: derived related-navigation placement entry
**Source**: existing related-navigation resolver output or page-local related links
| Field | Type | Notes |
|------|------|-------|
| `entryKey` | string | Stable identifier for a related destination |
| `label` | string | Operator-facing related-link label |
| `targetUrl` | string or null | Existing target destination |
| `sourceSection` | string | `summary`, `related_context`, `field_context`, or `status_context` |
| `isAvailable` | boolean | Mirrors existing helper availability logic |
| `leaksScopeIfMisplaced` | boolean | True when placing this in the wrong layer could imply broader access |
### WorkflowHeavyHeaderGroup
**Type**: derived grouped-action contract for special-type pages
**Source**: explicit exception handling for `ViewTenant`
| Field | Type | Notes |
|------|------|-------|
| `surfaceKey` | string | Expected to map to the special-type surface |
| `groupLabel` | string | Visible grouped-action label, usually `Actions` |
| `orderedBuckets` | array<string> | Ordered buckets such as `external_links`, `verification`, `setup`, and `lifecycle`; pure navigation remains contextual outside the header |
| `visiblePrimaryActionKey` | string or null | Optional visible primary action when a dominant next step exists |
| `requiresExplicitException` | boolean | Always true for workflow-heavy special types |
### HeaderRegressionExpectation
**Type**: guard and test expectation entry
**Source**: Spec 192 regression-protection requirements
| Field | Type | Notes |
|------|------|-------|
| `surfaceKey` | string | The page under regression protection |
| `maxVisiblePrimaryActions` | integer | `1` for standard pages, `0..1` for special types, `0..1` for references as documented |
| `requiresGroupedSecondaryActions` | boolean | Whether secondaries must be grouped |
| `allowsPrimaryNavigation` | boolean | Usually false for remediated standard pages |
| `requiresDangerSeparation` | boolean | True when the page contains destructive or governance-sensitive actions |
| `requiresExplicitExceptionReason` | boolean | True for special-type pages |
| `browserSmokeRequired` | boolean | True for remediation-required pages, the explicit special-type exception, and the compliant reference baseline set |
## Resolution Rules
### Standard-page rules
1. A remediation-required standard record/detail/edit page resolves to at most one `primary_visible` action.
2. Pure navigation actions resolve to `contextual`, not to `primary_visible` or header-grouped placement.
3. Rare or administrative mutations resolve to `secondary_grouped`.
4. Destructive or governance-sensitive actions resolve to `danger_grouped` and keep confirmation.
### State-sensitive primary-action rules
- `baseline_profile_view` resolves `capture` as primary when no consumable snapshot exists.
- `baseline_profile_view` resolves `compareNow` as primary when a consumable snapshot exists.
- `tenant_review_view` resolves one of `refresh_review`, `publish_review`, or `export_executive_pack` as primary based on lifecycle state.
- `finding_exception_view` may resolve `renew_exception` as primary only when renewal is valid and visible.
- `tenant_edit` does not introduce a second page-header primary because save/cancel remain the true edit-surface primary affordance.
### Special-type rules
1. `tenant_view` may expose zero visible primaries when no single dominant next step exists.
2. If `tenant_view` exposes one visible primary, all remaining actions still stay grouped and internally ordered.
3. `tenant_view` must always carry an explicit exception reason in the inventory and regression expectations.
### Reference-page rules
1. A compliant reference page may keep a single contextual related-record link or single primary safe action without further restructuring.
2. Reference pages must not be rebuilt only to mimic the remediated pages.
## Relationships
- One `HeaderSurfaceInventoryEntry` maps to one `RecordHeaderLayoutState`.
- One `RecordHeaderLayoutState` contains many `HeaderActionDescriptor` entries.
- A page may contain zero or many `ContextualNavigationContract` entries.
- Only special-type pages use a `WorkflowHeavyHeaderGroup`.
- Every in-scope page must map to one `HeaderRegressionExpectation`.
## Safety Rules
- No derived header model may widen tenant or workspace visibility beyond existing route and helper semantics.
- No action may lose `UiEnforcement`, confirmation, audit, or `OperationRun` behavior when it changes placement.
- No grouped secondary structure may become an undocumented exception or empty placeholder.
- No regression expectation may silently exempt a page; every exception must be explicit and justified.