## 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
243 lines
10 KiB
Markdown
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. |