TenantAtlas/specs/192-record-header-discipline/data-model.md
ahmido 9f6985291e feat: implement spec 192 record page header discipline (#226)
## Summary
- implement Spec 192 across the targeted Filament record, detail, and edit pages with explicit action-surface inventory and guard coverage
- add the focused Spec 192 browser smoke, feature tests, and spec artifacts under `specs/192-record-header-discipline`
- improve unhandled promise rejection diagnostics by correlating 419s to the underlying Livewire request URL
- disable panel-wide database notification polling on the admin, tenant, and system panels and cover the mitigation with focused tests

## Validation
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/DatabaseNotificationsPollingTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/DatabaseNotificationsPollingTest.php tests/Feature/Filament/UnhandledRejectionLoggerAssetTest.php tests/Feature/Filament/FilamentNotificationsAssetsTest.php tests/Feature/Workspaces/ManagedTenantsLivewireUpdateTest.php tests/Feature/Filament/AdminSmokeTest.php`
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- manual integrated-browser verification of the Spec 192 surfaces and the notification-polling mitigation

## Notes
- Livewire v4 / Filament v5 compliance remains unchanged.
- Provider registration stays in `bootstrap/providers.php`.
- No Global Search behavior was expanded.
- No destructive action confirmation semantics were relaxed.
- The full test suite was not run in this PR.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #226
2026-04-11 21:20:41 +00: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.