TenantAtlas/specs/250-decision-governance-inbox/data-model.md
ahmido 72bfb37ba7
Some checks failed
Main Confidence / confidence (push) Failing after 57s
feat: add decision-based governance inbox (#291)
## Summary
- add a read-first governance inbox page at `/admin/governance/inbox`
- aggregate assigned findings, intake, stale operations, alert-delivery failures, and review follow-up into one canonical routing surface
- add focused coverage for inbox authorization, navigation context, page behavior, and section builder logic
- include the Spec Kit artifacts for spec 250

## Notes
- branch is synced with `dev`
- this PR supersedes #290 for the governance inbox work

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #291
2026-04-28 10:13:09 +00:00

103 lines
4.7 KiB
Markdown

# Data Model: Decision-Based Governance Inbox v1
**Date**: 2026-04-28
**Feature**: [spec.md](spec.md)
## Model Posture
This slice introduces no new persisted entity. Every object below is a derived read model used to compose one decision-first page over existing repo truth.
## Existing Source Truth
| Source Model | Ownership | Relevant Truth Reused |
|---|---|---|
| `Finding` | tenant-owned | assigned work, intake work, severity, due or overdue state, reopened state, tenant entitlement |
| `OperationRun` | tenant-owned with workspace monitoring access | stale or terminal-follow-up attention, canonical run destination |
| `AlertDelivery` | workspace-scoped | failed or otherwise operator-relevant alert delivery outcomes |
| `TenantReview` | tenant-owned | latest review drill-through destination |
| `TenantTriageReview` | tenant-owned | follow-up-needed and changed-since-review attention |
## Derived Read Models
### GovernanceInboxSection
Represents one visible source family on the inbox page.
| Field | Type | Notes |
|---|---|---|
| `key` | string | bounded page-local family key such as `assigned_findings`, `intake_findings`, `stale_operations`, `alert_delivery_failures`, `review_follow_up`; `stale_operations` is the canonical key for both stale and terminal-follow-up operations attention |
| `label` | string | operator-facing section title aligned to the source family |
| `count` | int | visible item count for the current actor and active filters |
| `summary` | string | calm one-line summary of why the family matters |
| `dominant_action_label` | string | primary CTA label, routed to the existing source surface |
| `dominant_action_url` | string | canonical source destination |
| `entries` | list<GovernanceAttentionEntry> | bounded preview list, not a second queue truth |
| `empty_state` | string | optional local empty explanation when the family is selected explicitly |
### GovernanceAttentionEntry
Represents one preview item inside a visible section.
| Field | Type | Notes |
|---|---|---|
| `family_key` | string | matches the owning `GovernanceInboxSection.key` |
| `source_model` | string | `Finding`, `OperationRun`, `AlertDelivery`, `TenantReview`, or `TenantTriageReview` |
| `source_key` | string | stable source identifier for routing only |
| `tenant_id` | int or null | nullable for workspace-scoped alert or run cases |
| `tenant_label` | string or null | only shown when truthful |
| `headline` | string | concise operator-facing summary |
| `subline` | string or null | bounded reason, owner, or due-state context |
| `urgency_rank` | int | derived sort priority within the family |
| `status_label` | string | reused source-family wording |
| `destination_url` | string | existing canonical route |
| `back_label` | string | return label back to the inbox |
## Filter State
### GovernanceInboxFilterState
| Field | Type | Notes |
|---|---|---|
| `tenant_id` | int or null | optional tenant prefilter; explicit out-of-scope values return `404` |
| `family` | string or null | optional family filter for one visible source family; `stale_operations` remains the canonical filter key for stale or terminal-follow-up operations attention |
| `nav` | array or null | optional shared navigation payload used for return continuity |
## Ordering Rules
### Section Order
1. Assigned findings
2. Findings intake
3. Stale or terminal-follow-up operations
4. Alert-delivery failures
5. Review follow-up
This order is deliberately explicit and page-local. It is not a new persisted workflow taxonomy.
### Entry Order
- Findings-based sections reuse their existing queue ordering.
- Operations reuse the current monitoring-attention ordering exposed by the canonical operations surface.
- Alert-delivery failures order newest unresolved operator-relevant failures first.
- Review follow-up orders explicit follow-up-needed states before changed-since-review states.
## Relationships
- One `GovernanceInboxSection` maps to one existing source family.
- One `GovernanceInboxSection` has many derived `GovernanceAttentionEntry` values.
- Each `GovernanceAttentionEntry` points to exactly one existing source record and one existing source destination.
- No derived object owns or mutates source truth.
## Persistence Rules
- No new table.
- No new cache.
- No new inbox-specific audit stream.
- No new acknowledged, snoozed, or assigned state.
## Data Integrity Rules
- Hidden tenants never contribute to derived section counts or entry previews.
- Family visibility is capability-driven; invisible families do not render empty placeholders.
- Tenantless alert or operation entries must not invent tenant labels.
- Source destinations must stay canonical and existing; the inbox must not invent a parallel detail shell.