## Summary - centralize all status-like badge semantics via `BadgeCatalog`/`BadgeRenderer` and new per-domain mappings plus coverage for every affected entity - replace ad-hoc badge colors in Filament tables/views with the shared catalog and add a guard test that blocks new inline semantics - stabilize restore views by avoiding `@php(...)` shorthand so Blade compiles cleanly, and document BADGE-001 in the constitution/templates ## Testing - `vendor/bin/sail php vendor/bin/pint --dirty` - `vendor/bin/sail artisan test tests/Unit/Badges tests/Feature/Guards/NoAdHocStatusBadgesTest.php` - `vendor/bin/sail artisan test tests/Feature/Monitoring/OperationsDbOnlyTest.php tests/Feature/Monitoring/OperationsTenantScopeTest.php` - `vendor/bin/sail artisan test tests/Feature/RestoreRunWizardMetadataTest.php tests/Feature/Filament/SettingsCatalogRestoreApplySettingsPatchTest.php` Co-authored-by: Ahmed Darrazi <ahmeddarrazi@adsmac.local> Reviewed-on: #71
151 lines
8.0 KiB
Markdown
151 lines
8.0 KiB
Markdown
# 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
|
|
|
|
<!--
|
|
ACTION REQUIRED: Replace the content in this section with the technical details
|
|
for the project. The structure here is presented in advisory capacity to guide
|
|
the iteration process.
|
|
-->
|
|
|
|
**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)
|
|
|
|
```text
|
|
/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)
|
|
|
|
```text
|
|
/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.
|