TenantAtlas/specs/133-detail-page-template/data-model.md
ahmido d4fb886de0 feat: standardize enterprise detail pages (#162)
## Summary
- introduce a shared enterprise-detail composition layer for Filament detail pages
- migrate BackupSet, BaselineSnapshot, EntraGroup, and OperationRun detail screens to the shared summary-first layout
- add regression and unit coverage for section hierarchy, related context, degraded states, and duplicate fact/badge presentation

## Scope
- adds shared support classes under `app/Support/Ui/EnterpriseDetail`
- adds shared enterprise detail Blade partials under `resources/views/filament/infolists/entries/enterprise-detail`
- updates touched Filament resources/pages to use the shared detail shell
- includes Spec 133 artifacts under `specs/133-detail-page-template`

## Notes
- branch: `133-detail-page-template`
- base: `dev`
- commit: `fd294c7`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #162
2026-03-10 23:06:26 +00:00

243 lines
10 KiB
Markdown

# Data Model: View Page Template Standard for Enterprise Detail Screens
**Feature**: 133-detail-page-template | **Date**: 2026-03-10
## Overview
This feature introduces no database tables and no schema migration. It introduces a shared page-composition model for enterprise detail screens and maps four existing targets onto that model.
The core design adds computed read models only:
1. a shared enterprise detail page model,
2. a shared summary-header model,
3. reusable main-section and supporting-card models,
4. a structured related-context model,
5. a secondary technical-detail model,
6. target-specific presenter outputs that populate the shared shell.
## Existing Persistent Entities Used By The Feature
### BaselineSnapshot
| Attribute | Type | Notes |
|-----------|------|-------|
| `id` | int | Snapshot identity |
| `workspace_id` | int | Workspace isolation boundary |
| `baseline_profile_id` | int | Primary governance relationship |
| `captured_at` | timestamp | Key summary timestamp |
| `snapshot_identity_hash` | string nullable | Technical identifier |
**Usage rules**:
- Remains workspace-scoped.
- Summary-first rendering must emphasize capture context, fidelity, and governance relevance ahead of technical metadata.
### BackupSet
| Attribute | Type | Notes |
|-----------|------|-------|
| `id` | int | Record identity |
| `tenant_id` | int | Tenant isolation boundary |
| `name` | string | Primary display label |
| `status` | string | Lifecycle summary signal |
| `metadata` | array/json nullable | Technical or configuration detail |
| `completed_at` | timestamp nullable | High-signal recovery or lifecycle timestamp |
**Usage rules**:
- Remains tenant-scoped.
- Detail rendering must elevate lifecycle state, scope, and recent operational relevance before raw metadata.
### EntraGroup
| Attribute | Type | Notes |
|-----------|------|-------|
| `id` | int | Local record identity |
| `tenant_id` | int | Tenant isolation boundary |
| `display_name` | string | Primary label |
| `entra_id` | string | Provider object identifier |
| `group_types` | array/json nullable | Provider classification detail |
| `security_enabled` | bool | Classification signal |
| `mail_enabled` | bool | Classification signal |
| `last_seen_at` | timestamp nullable | Operational freshness indicator |
**Usage rules**:
- Remains tenant-scoped.
- The page must show identity and classification before raw provider arrays.
### OperationRun
| Attribute | Type | Notes |
|-----------|------|-------|
| `id` | int | Run identity |
| `workspace_id` | int | Workspace-context monitoring boundary |
| `tenant_id` | int nullable | Optional tenant context |
| `type` | string | What ran |
| `status` | string | Current run state |
| `outcome` | string nullable | Terminal result |
| `summary_counts` | array/json nullable | KPI-like operational counts |
| `failure_summary` | array/json nullable | Secondary failure detail |
| `context` | array/json nullable | Target scope and related metadata |
| `created_at`, `started_at`, `completed_at` | timestamps | Operational timing |
**Usage rules**:
- Remains workspace-context by route, with tenant entitlement checks for any tenant-bound related context.
- The page must emphasize run identity, state, target scope, and outcome before failure payloads or context dumps.
## New Computed Read Models
### EnterpriseDetailPageData
| Field | Type | Description |
|------|------|-------------|
| `resource_type` | string enum | `baseline_snapshot`, `backup_set`, `entra_group`, `operation_run` |
| `scope` | string enum | `workspace`, `tenant`, `workspace-context` |
| `header` | SummaryHeaderData | Top-of-page identity and state |
| `main_sections` | list<DetailSectionData> | Primary reading-path content |
| `supporting_cards` | list<SupportingCardData> | Compact aside or supporting content |
| `technical_sections` | list<TechnicalDetailData> | Secondary technical detail blocks |
| `empty_state_notes` | list<SectionEmptyStateData> | Optional explicit empty or degraded-state notes |
**Rules**:
- The page model must always render a valid summary header.
- Technical detail may be omitted entirely when not relevant.
- Empty or degraded sections must communicate intent explicitly rather than disappearing ambiguously.
### SummaryHeaderData
| Field | Type | Description |
|------|------|-------------|
| `title` | string | Primary record label |
| `subtitle` | string nullable | Secondary identifying context |
| `status_badges` | list<StatusBadgeData> | High-signal current-state indicators |
| `key_facts` | list<KeyFactData> | High-signal metadata shown before deep detail |
| `primary_actions` | list<PageActionData> | Header actions available on page load |
| `description_hint` | string nullable | Optional short domain hint |
**Rules**:
- Header content must answer “what is this?” and “what is its current condition?” first.
- Primary actions belong here, not buried in lower sections.
### DetailSectionData
| Field | Type | Description |
|------|------|-------------|
| `id` | string | Stable section key |
| `kind` | string enum | `core_details`, `current_status`, `related_context`, `operational_context`, `recent_activity`, `domain_detail` |
| `title` | string | Operator-facing section label |
| `items` | list<mixed> | Page-specific presentation items |
| `empty_state` | SectionEmptyStateData nullable | Empty or degraded-state copy |
| `action` | PageActionData nullable | Optional section-specific action |
| `visible` | bool | Section visibility |
**Rules**:
- Section titles describe meaning, not implementation.
- Section ordering must follow the shared reading-order contract.
### SupportingCardData
| Field | Type | Description |
|------|------|-------------|
| `kind` | string enum | `status`, `timestamps`, `related_context`, `quick_actions`, `health`, `summary` |
| `title` | string | Compact card title |
| `items` | list<mixed> | Card content |
| `visible` | bool | Card visibility |
**Rules**:
- Supporting cards must remain compact and high-value.
- Raw JSON or deep field tables do not belong here.
### RelatedContextItemData
| Field | Type | Description |
|------|------|-------------|
| `label` | string | Object or relationship label |
| `context_type` | string enum | `parent`, `child`, `source_run`, `tenant`, `workspace`, `artifact`, `linked_record` |
| `value` | string | Visible contextual value |
| `url` | string nullable | Canonical destination when authorized |
| `available` | bool | Permission-aware availability flag |
| `empty_reason` | string nullable | Degraded-state explanation when unavailable |
**Rules**:
- Related context must not reveal inaccessible record identity.
- Missing or unavailable links need explicit copy, not silent omission when the relationship matters.
### TechnicalDetailData
| Field | Type | Description |
|------|------|-------------|
| `title` | string | Technical section title |
| `entries` | list<KeyFactData> | Secondary identifiers or diagnostics |
| `collapsible` | bool | Whether the block is collapsed by default |
| `visible` | bool | Visibility |
**Rules**:
- Technical detail must render after the core reading path.
- Sensitive or privileged technical detail remains subject to existing authorization.
### PageActionData
| Field | Type | Description |
|------|------|-------------|
| `label` | string | Operator-facing action label |
| `placement` | string enum | `header`, `supporting_card`, `section` |
| `url` | string nullable | Navigation target |
| `action_name` | string nullable | Existing action identifier when not purely navigational |
| `destructive` | bool | Whether the action is destructive-like |
| `requires_confirmation` | bool | Confirmation requirement |
| `visible` | bool | Authorization-aware visibility |
**Rules**:
- Similar actions should map to the same placement across aligned pages.
- Existing destructive actions keep their current confirmation and authorization rules.
## Target-Specific View Models
### BaselineSnapshotDetailData
| Field | Type | Description |
|------|------|-------------|
| `capture_summary` | list<KeyFactData> | Capture date, fidelity, evidence mix, gap count |
| `coverage_rows` | list<mixed> | Structured contents overview |
| `governance_context` | list<RelatedContextItemData> | Baseline profile and source-run context |
| `snapshot_technical_detail` | TechnicalDetailData | Identity hash and lower-level metadata |
### BackupSetDetailData
| Field | Type | Description |
|------|------|-------------|
| `lifecycle_summary` | list<KeyFactData> | Status, item count, completion state |
| `scope_summary` | list<KeyFactData> | Type or retention-related signals |
| `recent_related_operations` | list<RelatedContextItemData> | Related operational context |
| `backup_technical_detail` | TechnicalDetailData | Raw metadata and secondary identifiers |
### EntraGroupDetailData
| Field | Type | Description |
|------|------|-------------|
| `identity_summary` | list<KeyFactData> | Name, type, freshness |
| `classification_summary` | list<KeyFactData> | Security-enabled and mail-enabled meaning |
| `governance_usage` | list<RelatedContextItemData> | Related references or policy usage when available |
| `group_technical_detail` | TechnicalDetailData | Provider object IDs and raw provider arrays |
### OperationRunDetailData
| Field | Type | Description |
|------|------|-------------|
| `run_summary` | list<KeyFactData> | Type, status, outcome, initiator, timing |
| `target_scope_summary` | list<KeyFactData> | Target scope and elapsed or expected duration |
| `result_summary` | list<KeyFactData> | Summary counts or outcome highlights |
| `failure_context` | DetailSectionData nullable | Failure details when present |
| `run_technical_detail` | TechnicalDetailData | Identity hash and context payload fragments |
## Visibility and Degraded-State Rules
| Rule | Result |
|------|--------|
| Every aligned page must render a summary header | Required |
| Technical detail may be hidden or collapsed by default | Required |
| Missing related context must show explicit empty or unavailable copy when the relationship is important | Required |
| Supporting cards may be omitted when no compact high-value content exists | Required |
| Pages may omit non-applicable section types without leaving empty shells | Required |
## Schema Impact
No database schema change is expected for this feature.