TenantAtlas/specs/059-unified-badges/spec.md
ahmido 0b6600b926 059-unified-badges (#71)
## 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
2026-01-22 23:44:51 +00:00

152 lines
12 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Feature Specification: Unified Badge System (Single Source of Truth) v1
**Feature Branch**: `059-unified-badges`
**Created**: 2026-01-22
**Status**: Draft
**Input**: Suite-wide badge/chip standardization so the same underlying value always renders with the same meaning (label + color + optional icon) across tables, dashboards/KPIs, and detail views; tenant-safe and DB-only at render time where required.
## Clarifications
### Session 2026-01-22
- Q: What is the v1 migration coverage target? → A: Status-like badges suite-wide; tag/category chips later.
- Q: What counts as “status-like” for v1 scope? → A: Status/health plus severity/risk signals.
- Q: Should v1 introduce any new severity levels (e.g., “critical”), or standardize the existing severity values only? → A: Standardize existing severity values only (no new levels in v1).
- Q: Should v1 include an automated “no ad-hoc badge semantics” guard beyond mapping tests? → A: Yes — tests plus a lightweight automated guard that flags ad-hoc mappings.
- Q: What is the canonical meaning for drift finding severity (low | medium | high) in v1? → A: low = neutral, medium = warning, high = danger.
## User Scenarios & Testing *(mandatory)*
<!--
IMPORTANT: User stories should be PRIORITIZED as user journeys ordered by importance.
Each user story/journey must be INDEPENDENTLY TESTABLE - meaning if you implement just ONE of them,
you should still have a viable MVP (Minimum Viable Product) that delivers value.
Assign priorities (P1, P2, P3, etc.) to each story, where P1 is the most critical.
Think of each story as a standalone slice of functionality that can be:
- Developed independently
- Tested independently
- Deployed independently
- Demonstrated to users independently
-->
### User Story 1 - Trustworthy status badges everywhere (Priority: P1)
As a tenant admin, I can trust that status/health and severity/risk badges mean the same thing everywhere in the admin panel, so I can scan lists quickly and make the right decision.
**Why this priority**: Inconsistent badge semantics create operational mistakes (false “success”, missed failures) and erode trust in the UI.
**Independent Test**: View a representative set of pages that contain status/health and severity/risk badges (lists + detail views) and confirm the same underlying value always uses the same label and visual meaning across pages.
**Acceptance Scenarios**:
1. **Given** a run is in the “queued” state, **When** I view it in any table, dashboard list, or detail view, **Then** it is clearly shown as “Queued” with a consistent visual meaning that indicates “waiting to start”.
2. **Given** a run is in the “running” state, **When** I view it in any table, dashboard list, or detail view, **Then** it is clearly shown as “Running” with a consistent visual meaning that indicates “in progress”.
3. **Given** a run is in a successful terminal state (“succeeded” / “completed”), **When** I view it anywhere, **Then** it is shown with a consistent “success” meaning and is never shown using warning/attention colors.
4. **Given** a finding has a high-severity value, **When** I view it in any table, dashboard list, or detail view, **Then** it is shown with a consistent “high severity” meaning and is never shown as a neutral or low-attention meaning.
---
### User Story 2 - Readable status badges in dark mode (Priority: P2)
As a tenant admin, I can scan status badges in both light and dark mode without readability regressions.
**Why this priority**: Badges are a high-density UI element; readability and correct “good/bad” signaling reduce cognitive load and prevent mistakes.
**Independent Test**: Open key list pages and dashboards in dark mode and light mode and verify status badges remain readable without relying on fragile per-page styling overrides.
**Acceptance Scenarios**:
1. **Given** I use dark mode, **When** I view status-like badges on common pages, **Then** badge text and any icons remain readable and do not rely on fragile per-page styling overrides.
2. **Given** a status badge includes an icon in a dense list, **When** I view it, **Then** the icon appearance matches the badge meaning and does not appear disabled unless the status is intentionally neutral.
---
### User Story 3 - Consistency stays enforced over time (Priority: P3)
As a maintainer, I can update badge semantics in one place and have the change apply everywhere, and regressions are caught before release.
**Why this priority**: Without enforcement, ad-hoc badge mappings quickly reappear and the UI drifts back into inconsistent meanings.
**Independent Test**: Make a small change to a centralized badge definition and confirm it affects multiple UI surfaces; introduce a deliberately inconsistent mapping and confirm automated validation fails.
**Acceptance Scenarios**:
1. **Given** a new status value is introduced, **When** it is not yet defined in the central badge system, **Then** it displays with a safe “unknown” meaning rather than being misrepresented as success or warning.
2. **Given** a developer attempts to reintroduce an ad-hoc badge mapping, **When** automated validation runs, **Then** it is detected and fails until the centralized definition is used.
---
[Add more user stories as needed, each with an assigned priority]
### Edge Cases
- A record has an unrecognized/legacy status value (null/empty/unknown string).
- A record has an unrecognized/legacy severity/risk value.
- The same status appears on multiple pages (list + detail) and must remain consistent.
- A status value exists across multiple “domains” (e.g., “completed” used in different workflows) and must not be conflated if meanings differ.
- Dark mode and high-contrast settings reduce readability of badge text or icons.
- A page that must remain read-only/DB-only accidentally introduces side effects during render (for example, remote calls or background work).
- Tenant switching occurs mid-session and badges must not leak cross-tenant data.
## Requirements *(mandatory)*
**Constitution alignment (required):** If this feature introduces any Microsoft Graph calls, any write/change behavior,
or any long-running/queued/scheduled work, the spec MUST describe contract registry updates, safety gates
(preview/confirmation/audit), tenant isolation, run observability (`OperationRun` type/identity/visibility), and tests.
If security-relevant DB-only actions intentionally skip `OperationRun`, the spec MUST describe `AuditLog` entries.
<!--
ACTION REQUIRED: The content in this section represents placeholders.
Fill them out with the right functional requirements.
-->
### Functional Requirements
- **FR-001**: The system MUST define badge semantics centrally for each status badge “domain” used in the admin UI, including: label, color meaning, and (when applicable) an icon.
- **FR-002**: The system MUST apply the centralized status badge semantics consistently across all status badge surfaces (tables, dashboards/KPIs, and detail views) so the same underlying value always renders with the same meaning.
- **FR-003**: The system MUST clearly distinguish “status-like” badges (status/health and severity/risk signals) from tag/category chips so scope boundaries are unambiguous; v1 MUST standardize status-like badges suite-wide.
- **FR-004**: The system MUST standardize the canonical meanings for run-like statuses at minimum: queued, running, succeeded/completed, partial, failed.
- **FR-005**: Warning/attention colors (e.g., orange/yellow) MUST be reserved for “queued / needs attention / partial / in progress” meanings and MUST NOT represent success/completed outcomes.
- **FR-006**: Badge rendering MUST remain tenant-safe: it must not display cross-tenant data and must rely only on data already available in the current tenant context.
- **FR-007**: For designated DB-only pages (for example, Monitoring/Operations views), badge rendering MUST NOT trigger outbound network requests, background jobs, or other side effects during render or during automatic refresh/polling.
- **FR-008**: Badge rendering MUST be performant and predictable: it must not require additional data lookups at view time and must not introduce noticeable delays on high-row-count tables.
- **FR-009**: In dense tables, badges MAY include icons for scanability; when icons are shown, they MUST not appear disabled/gray unless the badge itself is intentionally neutral.
- **FR-010**: The system MUST provide a safe default for unrecognized values (neutral + clearly labeled as unknown) to avoid misleading operators.
- **FR-011**: The admin UI MUST be migrated so existing status-like badges/chips use the centralized system across the suite; tag/category chips are explicitly out of scope for v1 migration and may remain unchanged.
- **FR-012**: The delivery MUST include automated regression checks that validate canonical mappings (including “success is never warning”) and prevent reintroducing ad-hoc badge semantics.
- **FR-013**: This change MUST be limited to badge/chip rendering semantics; it MUST NOT change underlying workflow logic, status definitions, or page layouts beyond what is required to standardize badge rendering.
- **FR-014**: Severity/risk badges (for example, findings severity) MUST be standardized and rendered consistently across all in-scope pages.
- **FR-015**: The system MUST NOT introduce new severity levels as part of this feature; it MUST standardize and render existing severity values consistently.
- **FR-016**: The delivery MUST include a lightweight automated guard that detects newly introduced ad-hoc status/health or severity/risk badge semantics and blocks release until the centralized system is used.
- **FR-017**: Drift finding severity MUST have a canonical meaning: low = neutral, medium = warning, high = danger.
### Assumptions & Dependencies
- Existing status values and business meanings are already established; this feature standardizes how they are presented, not what they mean.
- A defined set of status-like badge domains exists across the suite (runs, findings status, tenant status, availability, enabled/disabled, severity/risk); any newly discovered status-like domains will be included in the v1 standardization scope.
- Dark mode is supported and is considered in acceptance for badge readability.
- Tag/category chip standardization (policy type/platform/environment) is deferred to a later version.
- Severity level changes (such as adding “critical”) are deferred to a later version.
### Key Entities *(include if feature involves data)*
- **Badge Domain**: A named category of values that share a consistent badge meaning (for example, “Operation run status”).
- **Badge Definition**: The centralized mapping for a domains values to label + color meaning + optional icon.
- **Status Badge**: A badge that communicates progress/outcome/health or severity/risk (for example, queued/running/succeeded).
- **Tag Badge**: A badge that communicates categorization/metadata (for example, platform/type/environment).
## Success Criteria *(mandatory)*
<!--
ACTION REQUIRED: Define measurable success criteria.
These must be technology-agnostic and measurable.
-->
### Measurable Outcomes
- **SC-001**: For each defined status badge domain, the same value renders with the same label and visual meaning across all in-scope pages in 100% of validation runs.
- **SC-002**: Across the in-scope admin UI, 0 instances exist where a success/completed outcome is presented using a warning/attention badge meaning.
- **SC-003**: Viewing designated DB-only pages triggers 0 outbound network requests and 0 background work as a side effect of badge rendering, in 100% of regression runs.
- **SC-004**: Status-badge-related UI regressions (incorrect label/color/icon meaning) decrease by at least 80% in the 30 days after release compared to the previous 30 days.