TenantAtlas/specs/059-unified-badges/plan.md
2026-01-23 00:40:52 +01:00

8.0 KiB

Implementation Plan: Unified Badge System (Single Source of Truth) v1

Branch: 059-unified-badges | Date: 2026-01-22 | Spec: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/059-unified-badges/spec.md
Input: Feature specification from /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/059-unified-badges/spec.md

Note: This template is filled in by the /speckit.plan command. See .specify/scripts/ for helper scripts.

Summary

  • Standardize status/health and severity/risk badge semantics suite-wide using a centralized mapping system.
  • Migrate all status-like badge surfaces (tables, dashboards/KPIs, detail views) to use the central semantics.
  • Keep tag/category chips (policy type/platform/environment) out of scope for v1 (planned follow-up).
  • Add automated regression coverage: mapping tests + a lightweight guard that flags reintroduced ad-hoc mappings.

Technical Context

Language/Version: PHP 8.4.15 (Laravel 12)
Primary Dependencies: Filament v5 + Livewire v4
Storage: PostgreSQL
Testing: Pest v4 (PHPUnit v12 runtime via php artisan test)
Target Platform: Web application (Filament admin panel)
Project Type: Web (Laravel monolith)
Performance Goals: Badge mapping is constant-time; no added queries or N+1; typical list pages render <2s for normal tenant sizes.
Constraints: Tenant-scoped; status-like badge rendering must be DB-only and must not trigger outbound HTTP or job dispatch during render/polling/hydration.
Scale/Scope: Suite-wide migration for status/health and severity/risk badges across tables, dashboards/KPIs, and detail views.

Constitution Check

GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.

  • Inventory-first: clarify what is “last observed” vs snapshots/backups
  • Read/write separation: any writes require preview + confirmation + audit + tests
  • Graph contract path: Graph calls only via GraphClientInterface + config/graph_contracts.php
  • Deterministic capabilities: capability derivation is testable (snapshot/golden tests)
  • Tenant isolation: all reads/writes tenant-scoped; cross-tenant views are explicit and access-checked
  • Run observability: long-running/remote/queued work creates/reuses OperationRun; start surfaces enqueue-only; Monitoring is DB-only; DB-only <2s actions may skip runs but security-relevant ones still audit-log
  • Automation: queued/scheduled ops use locks + idempotency; handle 429/503 with backoff+jitter
  • Data minimization: Inventory stores metadata + whitelisted meta; logs contain no secrets/tokens

Status: No constitution violations (UI semantics only; no new Graph calls; no new write behavior; badge mapping is pure and tenant-safe).

Project Structure

Documentation (this feature)

/Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/059-unified-badges/
├── plan.md              # This file (/speckit.plan command output)
├── research.md          # Phase 0 output (/speckit.plan command)
├── data-model.md        # Phase 1 output (/speckit.plan command)
├── quickstart.md        # Phase 1 output (/speckit.plan command)
├── contracts/           # Phase 1 output (/speckit.plan command)
└── tasks.md             # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan)

Source Code (repository root)

/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/
├── Filament/
│   ├── Pages/Monitoring/Operations.php          # Update: migrate status/outcome badges to central mapping
│   ├── Resources/                               # Update: status-like columns/entries across resources
│   └── Widgets/                                 # Update: status-like + severity badges in dashboard widgets
├── Support/
│   └── Badges/                                  # New: central badge semantics (status/health + severity/risk)
└── Models/                                      # Existing: status/severity sources (OperationRun, Finding, etc.)

/Users/ahmeddarrazi/Documents/projects/TenantAtlas/resources/views/
└── filament/                                    # Update: replace any ad-hoc status-like badge colors

/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/
├── Feature/Guards/                              # New: lightweight “no ad-hoc badge semantics” guard
└── Unit/                                        # New/updated: badge mapping tests per domain

Structure Decision: Laravel monolith + Filament v5 conventions. Centralize semantics in app/Support/Badges and consume from Filament resources/pages/widgets + Blade views.

Complexity Tracking

Fill ONLY if Constitution Check has violations that must be justified

None.

Phase 0 — Outline & Research (complete)

  • Output: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/059-unified-badges/research.md
  • Key decisions captured:
    • v1 scope: status/health + severity/risk badges suite-wide; tag/category chips deferred.
    • Drift severity mapping: low = neutral, medium = warning, high = danger.
    • Enforcement: mapping tests + lightweight guard to prevent reintroducing ad-hoc mappings.

Phase 1 — Design & Contracts (complete)

Data model

  • Output: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/059-unified-badges/data-model.md
  • No schema changes required; badge semantics derive from existing fields (status/outcome/severity booleans).

Contracts

  • Output: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/059-unified-badges/contracts/badge-semantics.md
  • Output: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/059-unified-badges/contracts/guardrails.md

Quickstart

  • Output: /Users/ahmeddarrazi/Documents/projects/TenantAtlas/specs/059-unified-badges/quickstart.md

Provider registration (Laravel 11+)

  • Panel providers remain registered in bootstrap/providers.php (no changes required for this feature unless adding a new provider).

Livewire / Filament version safety

  • Livewire v4.0+ (required by Filament v5) is in use.

Asset strategy

  • No new assets expected. If new panel assets are introduced during implementation, ensure deployment runs php artisan filament:assets.

Destructive actions

  • None introduced in this feature.

Constitution re-check (post-design)

  • Inventory-first / Snapshots-second: unaffected (UI-only semantics).
  • Read/write separation: this feature is read-only.
  • Graph contract path: no Graph calls added.
  • Tenant isolation: badge mapping is pure and uses already-available tenant-scoped data.
  • Run observability: only consumes existing run records; does not introduce new long-running work.
  • Data minimization: no new payload storage.

Gate status (post-design): PASS

Phase 2 — Implementation Plan (next)

Story 1 (P1): Trustworthy status/health badges everywhere

  • Introduce a central badge semantics layer for status/health domains (runs, findings status, tenant status, booleans, availability).
  • Migrate all status-like badge surfaces suite-wide to the centralized mapping, prioritizing:
    • Monitoring/Operations list surfaces
    • Inventory sync runs and backup schedule runs
    • Restore runs
    • Findings status
  • Ensure the invariant: success/completed is never presented as warning/attention.

Story 2 (P2): Readable status badges in dark mode

  • Remove fragile per-page color overrides for status-like badges in Blade where present.
  • Ensure status-like badges remain readable in dark mode and icons do not appear disabled unless intentionally neutral.

Story 3 (P3): Consistency stays enforced over time

  • Add mapping tests per domain (including drift severity mapping and “success is never warning” invariants).
  • Add a lightweight guard test to detect newly introduced ad-hoc status/health or severity/risk badge mappings.