TenantAtlas/specs/225-assignment-hygiene/data-model.md
ahmido 12fb5ebb30
Some checks failed
Main Confidence / confidence (push) Failing after 1m20s
feat: add findings hygiene report and control catalog layering (#264)
## Summary
- add the workspace-scoped findings hygiene report, overview signal, and supporting classification service for broken assignments and stale in-progress work
- add Spec 225 artifacts and focused findings hygiene test coverage alongside the new Filament page and workspace overview wiring
- align product roadmap and spec candidates around the layered canonical control catalog, CIS library, and readiness model
- extend SpecKit constitution and templates with the XCUT-001 shared-pattern reuse guidance

## Notes
- validation commands and implementation close-out notes are documented in `specs/225-assignment-hygiene/plan.md` and `specs/225-assignment-hygiene/quickstart.md`
- this PR targets `dev` from `225-assignment-hygiene`

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #264
2026-04-22 12:26:18 +00:00

5.7 KiB

Data Model: Assignment Hygiene & Stale Work Detection

Overview

This feature introduces no new persisted business entity. Existing finding truth, audit logs, tenant memberships, and user lifecycle truth remain canonical. The new work is one bounded derived hygiene layer over those existing records.

Existing Persistent Entities

Finding

Purpose: Canonical tenant-scoped findings workflow truth for ownership, lifecycle, and timing.

Key fields used by this feature:

  • id
  • workspace_id
  • tenant_id
  • status
  • owner_user_id
  • assignee_user_id
  • due_at
  • in_progress_at
  • reopened_at
  • resolved_at
  • closed_at
  • last_seen_at
  • times_seen

Relationships:

  • belongs to one workspace
  • belongs to one tenant
  • may reference one current owner user
  • may reference one current assignee user

Rules relevant to hygiene:

  • Only non-terminal findings participate in hygiene evaluation.
  • Owner-only findings are not hygiene issues by themselves.
  • Unassigned intake findings are not hygiene issues by themselves.
  • last_seen_at remains observation truth and must not reset the stale operator-work window.

AuditLog

Purpose: Existing audit truth for workflow actions and responsibility changes.

Key fields used by this feature:

  • id
  • workspace_id
  • tenant_id
  • auditable_type
  • auditable_id
  • action
  • created_at

Rules relevant to hygiene:

  • Existing finding workflow audit actions provide one source of workflow-activity timestamps.
  • No new audit action id is required for this feature because the report is read-only.

User

Purpose: Canonical operator identity record.

Key fields used by this feature:

  • id
  • deleted_at

Rules relevant to hygiene:

  • Soft-deleted users are treated as unavailable for current assignment execution.
  • The feature does not add a separate availability state.

Tenant Membership / Tenant Entitlement Truth

Purpose: Current authorization truth for whether an assignee can still work inside the tenant.

Key inputs used by this feature:

  • membership existence for the tenant
  • current tenant visibility
  • current findings-view capability in the referenced tenant

Rules relevant to hygiene:

  • Broken assignment is derived from current workability, not historical assignment legitimacy.
  • Hidden tenants remain excluded from rows, counts, and filters.

Derived Models

FindingHygieneIssue

Purpose: Canonical derived issue envelope used by both the report and the overview signal.

Fields:

  • finding_id
  • workspace_id
  • tenant_id
  • tenant_name
  • finding_summary
  • status
  • owner_user_id
  • owner_name
  • assignee_user_id
  • assignee_name
  • reasons: list of hygiene reasons
  • last_workflow_activity_at
  • due_at
  • is_overdue

Validation rules:

  • The finding must be non-terminal.
  • finding_summary, owner_name, and assignee_name are display-ready values resolved from the current finding and loaded user relationships; they remain derived, not persisted.
  • reasons contains one or more of the allowed hygiene reasons.
  • last_workflow_activity_at is derived from workflow anchors only and must not come from observation freshness.
  • One finding produces one issue row even when multiple reasons apply.

HygieneReason

Purpose: Bounded derived reason vocabulary for this feature.

Allowed values:

  • broken_assignment
  • stale_in_progress

Rules:

  • Reasons are derived labels, not persisted finding status.
  • Reasons exist because they change operator routing and filter behavior on the hygiene surface.

FindingsHygieneOverviewSignal

Purpose: Workspace overview summary projection for fast discovery.

Fields:

  • headline
  • description
  • unique_issue_count
  • broken_assignment_count
  • stale_in_progress_count
  • is_calm
  • cta_label
  • cta_url

Rules:

  • Counts are based on unique visible finding issues, not duplicated reason rows.
  • description is a short operator-facing summary derived from broken-assignment and stale-in-progress counts; no separate severity ordering is introduced.
  • When unique_issue_count = 0, the signal remains visible in a calm state with zero issues, calm descriptive copy, and the canonical CTA into the report.
  • The signal uses the same source query and tenant visibility truth as the canonical report.

Classification Matrix

Reason Trigger Required finding state Required visibility truth Exclusions
broken_assignment Assignee can no longer act non-terminal, assignee_user_id present current user may see the finding and the assigned user is either soft-deleted or no longer tenant-entitled owner-only, unassigned, hidden tenant
stale_in_progress No meaningful workflow movement for 7 days status = in_progress and non-terminal current user may see the finding merely overdue, recently reassigned, recently reopened, or recently moved into progress

Workflow Activity Anchor Rules

  • in_progress_at is the baseline activity anchor for work that actually started.
  • reopened_at can reset the stale window when the finding re-enters active lifecycle.
  • Existing workflow audit rows for finding.assigned, finding.in_progress, and finding.reopened can supersede the baseline anchor when they are newer.
  • last_seen_at and times_seen remain observation truth only and must not reset the stale-work window.

Persistence Boundaries

  • No new table, enum-backed persistence, or report snapshot is introduced.
  • The hygiene report and overview signal are recalculated from current truth at read time.
  • Repair continues through the existing finding detail mutation path and its current audit behavior.