TenantAtlas/specs/266-tenant-dashboard-productization-v1/data-model.md
Ahmed Darrazi beebbaefbe
Some checks failed
PR Fast Feedback / fast-feedback (pull_request) Failing after 5m58s
chore: commit all local changes
2026-05-03 16:00:44 +02:00

12 KiB

Data Model — Tenant Dashboard Productization v1

Spec: spec.md

No new persisted tables, dashboard aggregates, or productized score artifacts are required. This slice reuses current tenant-owned governance, exception, operations, review, evidence, and output truth, then tightens the derived dashboard composition contract over those seams.

Persisted Truth Reused

Workspace / Tenant Entitlement Context

Purpose: Establish the active workspace boundary and tenant entitlement before any dashboard summary, link, or canonical follow-up route is composed.

Persisted carriers:

  • existing workspace membership rows
  • existing tenant membership pivot rows and role assignments
  • current workspace context and selected tenant context

Relevant fields / contracts:

Validation rules:

  • current actor must be a workspace member or the route resolves as not found
  • current actor must be entitled to the tenant or the tenant dashboard and all tenant follow-up routes resolve as not found
  • canonical admin follow-up routes launched from the dashboard may only reveal the originating tenant when that tenant is still entitled in the current workspace

Finding and Exception Truth

Purpose: Provide active findings pressure, high-priority follow-up, and accepted-risk or exception readiness truth.

Persisted carriers:

Relevant fields / relationships:

  • finding severity, status, due or stale markers, and active workflow state
  • exception status
  • exception current_validity_state
  • exception review_due_at
  • exception expires_at
  • exception owner, approver, and current decision relationships

Validation / usage rules:

  • dashboard pressure and recommended-action logic stays tenant-scoped
  • accepted-risk and exception summaries remain derived from current finding and exception truth
  • no new accepted risk dashboard entity or separate persistence layer is introduced

Tenant Governance Aggregate

Purpose: Existing derived posture truth for compare readiness, governance pressure, and next-action hints.

Carrier: ../../apps/platform/app/Support/Baselines/TenantGovernanceAggregateResolver.php and related derived-state seams

Relevant fields / contracts:

  • aggregate summary assessment
  • active findings counts
  • governance warning counts
  • compare or baseline posture states
  • current next-action hints

Validation / usage rules:

  • remains derived only
  • stays the source for compare or baseline posture, not a new dashboard score
  • dashboard composition may reorder or compress the truth but must not fork it into a second status family

Recovery / Restore Readiness Truth

Purpose: Existing restore-readiness and recovery evidence truth used to summarize whether the tenant can be recovered safely.

Persisted carriers:

  • existing backup metadata and snapshot records
  • existing restore run and recovery evidence records reached through current backup and restore services

Relevant seams:

Validation / usage rules:

  • dashboard recovery and restore status remains derived from current safety evidence
  • no new recovery status persistence or dashboard-only restore state is introduced

OperationRun

Purpose: Canonical truth for recent execution state and follow-up-worthy operations.

Persisted carrier: existing operation_runs rows via ../../apps/platform/app/Models/OperationRun.php

Relevant fields / relationships:

  • id
  • workspace_id
  • tenant_id
  • type
  • status
  • outcome
  • context
  • failure_summary
  • created_at
  • started_at
  • completed_at

Validation / usage rules:

  • recent operation summaries remain tenant-scoped on the dashboard
  • canonical operations collection and detail routes remain the only drill-through path
  • dashboard composition may compress or reorder recent operations, but it does not own lifecycle state

TenantReview

Purpose: Canonical source for current review readiness and review drill-through.

Persisted carrier: existing tenant_reviews rows via ../../apps/platform/app/Models/TenantReview.php

Relevant fields / relationships:

  • id
  • workspace_id
  • tenant_id
  • status
  • generated_at
  • published_at
  • summary
  • evidence_snapshot_id
  • current_export_review_pack_id
  • related tenant, evidence snapshot, and current export review pack

Validation / usage rules:

  • dashboard review readiness remains derived from existing review and publication truth
  • dashboard must not invent a customer-safe output route when no published review or usable pack exists

ReviewPack

Purpose: Existing packaged output artifact for current downloadable review handoff.

Persisted carrier: existing review_packs rows via ../../apps/platform/app/Models/ReviewPack.php

Relevant fields / relationships:

  • id
  • workspace_id
  • tenant_id
  • tenant_review_id
  • status
  • generated_at
  • expires_at
  • operation_run_id
  • related tenant review and evidence snapshot

Validation / usage rules:

  • dashboard output readiness must stay anchored to current pack state
  • if a start-capable review-pack action is reused, it must keep its existing operation and audit behavior

EvidenceSnapshot

Purpose: Existing proof artifact for evidence availability and drill-through.

Persisted carrier: existing evidence_snapshots rows via ../../apps/platform/app/Models/EvidenceSnapshot.php

Relevant fields / relationships:

  • id
  • workspace_id
  • tenant_id
  • status
  • generated_at
  • expires_at
  • summary
  • items

Validation / usage rules:

  • evidence readiness stays optional and lower-priority than the main governance decision
  • raw evidence payloads remain off the default-visible dashboard

Required Permissions Comparison

Purpose: Current provider-blockage truth for missing permissions and freshness.

Carrier: ../../apps/platform/app/Services/Intune/TenantRequiredPermissionsViewModelBuilder.php

Relevant fields / contracts:

  • overview.overall
  • overview.counts.missing_application
  • overview.counts.missing_delegated
  • overview.freshness.last_refreshed_at
  • overview.freshness.is_stale
  • feature_impacts

Validation / usage rules:

  • remains derived only
  • powers the provider-health summary card and required-permissions CTA
  • no new tenant provider-health persistence is introduced

Derived Read Models

TenantDashboardSummary

Purpose: Derived page-level contract for the productized tenant landing surface.

Persistence: none; computed at request time

Fields:

  • workspace
  • tenant
  • context_chips
  • header_actions
  • kpis
  • recommended_actions
  • governance_status_rows
  • recent_operations
  • current_review
  • risk_exception_summary
  • provider_health_summary
  • output_readiness_summary
  • arrival_context (nullable)

Derivation rules:

  • exactly one summary exists per current workspace + tenant pair
  • top-level counts, badges, and actions derive only from existing repo-real truth and explicit fallback states
  • hidden actions are omitted entirely; visible but blocked paths become explicit unavailable states only when the operator still needs the summary context
  • the summary owns ordering, not a new truth family

DashboardHeaderAction

Purpose: Derived contract for the capped page-header CTA set.

Persistence: none

Fields:

  • label
  • url or action_key
  • style (primary or secondary)
  • availability_state
  • helper_text (nullable)

Validation rules:

  • at most 2 visible header actions
  • any unavailable action must be explicit and must not appear as a clickable dead end
  • no destructive action is introduced on the dashboard shell

DashboardKpiCard

Purpose: Derived posture card shown in the first KPI row.

Persistence: none

Fields:

  • key
  • label
  • value
  • supporting_text
  • status_label
  • badge_state
  • trend_label (nullable)
  • primary_link (nullable)

Validation rules:

  • at most 4 cards
  • cards may use honest fallback labels such as Unavailable, Not configured, or No data yet
  • cards must not invent new score semantics or fake trend data

RecommendedDashboardAction

Purpose: Derived next-step record for the central decision card.

Persistence: none

Fields:

  • priority
  • title
  • reason
  • impact
  • category (nullable)
  • cta_label
  • cta_url
  • availability_state
  • helper_text (nullable)

Derivation rules:

  • ordered by bounded priority: governance pressure, provider blockage, pending risk or exception decisions, restore-readiness gaps, evidence or review readiness gaps, operation follow-up
  • hidden actions are omitted from the list entirely

Validation rules:

  • at most 3 actions
  • each action owns exactly 1 dominant CTA
  • if no action is needed, the list becomes a positive empty state rather than an empty shell

GovernanceStatusRow

Purpose: Derived compact status digest row for one readiness family.

Persistence: none

Fields:

  • key
  • label
  • description
  • status_label
  • badge_state
  • support_link (nullable)

Validation rules:

  • rows remain read-only summaries
  • unknown or missing truth becomes Unavailable or equivalent fallback, never green by default

RecentOperationSummary

Purpose: Derived compact recency row for the dashboard operations card.

Persistence: none

Fields:

  • operation_run_id
  • label
  • status_label
  • outcome_label
  • relative_time
  • summary_text
  • detail_url

Validation rules:

  • at most 4 rows
  • remains clearly diagnostic and secondary to the primary decision layer

SummaryCardState

Purpose: Shared derived state for current review, risk-exception, provider-health, and output-readiness cards.

Persistence: none

Fields:

  • title
  • headline
  • supporting_lines
  • cta_label (nullable)
  • cta_url (nullable)
  • availability_state
  • helper_text (nullable)

Validation rules:

  • each card gets at most 1 dominant CTA
  • cards without repo-real follow-up routes remain read-only readiness summaries

Derived Disclosure States

This feature introduces no new persisted lifecycle or enum family. It does require explicit derived action and disclosure states across the dashboard:

  • available: the actor can follow the link or perform the existing reused action now
  • absent: the underlying artifact or condition does not exist yet
  • unavailable: the condition exists conceptually, but the actor cannot act because of capability, readiness, or current state constraints

Hidden actions are omitted from the derived models entirely rather than stored as a visible state.