# Research — Tag Badge Catalog (Neutral, Suite-wide) v1

## Goal
Standardize non-status metadata badges (“tags/chips”) suite-wide so operators can reliably scan the admin UI without confusing metadata with health/status signals.

## Existing Code & Patterns (to reuse)

### Central badge semantics pattern (status-like)
- Status-like badge semantics are centralized in:
  - `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Badges/BadgeCatalog.php`
  - `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/app/Support/Badges/BadgeRenderer.php`

This feature must not mix tag-like semantics into the status-like catalog; it should follow a similar centralization pattern, but remain neutral and separate.

### Filament badge surfaces (current)
- Tables commonly use `TextColumn::badge()` to display chips.
- Blade views sometimes use `<x-filament::badge>` directly for badge-like UI.

### Guard test pattern (current)
- The repo uses Pest “guard” tests that scan the codebase for forbidden patterns, for example:
  - `/Users/ahmeddarrazi/Documents/projects/TenantAtlas/tests/Feature/Guards/NoAdHocStatusBadgesTest.php`

## Key Decisions

### Decision: Centralize tag-like badge semantics behind a dedicated catalog
- **Decision**: Introduce a dedicated tag badge catalog for metadata tags (separate from the status-like `BadgeCatalog`).
- **Rationale**: Prevents per-page drift and makes tag presentation testable and enforceable without changing business semantics.
- **Alternatives considered**:
  - **Inline mappings per resource/widget/view**: rejected (drifts quickly; hard to enforce).
  - **Reusing status-like domains**: rejected (tags must remain neutral and not inherit health semantics).

### Decision: Neutral palette is an explicit allowlist
- **Decision**: Tag badges are restricted to an explicit allowlist: `gray`, `primary`, `info`.
- **Rationale**: Keeps tag chips clearly “metadata” and prevents accidental use of health/status semantics.
- **Alternatives considered**:
  - **“Neutral by convention” without an allowlist**: rejected (too ambiguous; hard to test and enforce).

### Decision: Tag badge colors are assigned per domain (domain → color)
- **Decision**: The tag badge color is chosen by domain, not by individual tag value.
- **Rationale**: Keeps tags scannable (domain is visually recognizable) while avoiding a “rainbow” palette that becomes hard to maintain.
- **Alternatives considered**:
  - **One color for everything**: rejected (loses useful grouping at-a-glance).
  - **Per-tag-value colors**: rejected (too complex; tends to drift and become noisy).

### Decision: v1 migration coverage is discovery-driven but bounded
- **Decision**: v1 migrates the minimum targeted surfaces, plus any additional tag-like badges found during the discovery sweep.
- **Rationale**: Achieves meaningful suite-wide consistency without turning into an unbounded refactor.
- **Alternatives considered**:
  - **Full sweep**: rejected (can sprawl and delay value).
  - **Minimum only**: rejected (leaves too many inconsistent surfaces behind).

### Decision: Unknown/unmapped values are shown as “Other: <value>”
- **Decision**: Unknown/unmapped tag values render as a neutral badge with label “Other: <value>” (normalized).
- **Rationale**: Preserves information for admins while clearly indicating it is not a curated/known tag.
- **Alternatives considered**:
  - **Raw value only**: rejected (can look “official/curated”).
  - **“Unknown” without value**: rejected (hides useful info).
  - **Hide badge**: rejected (drops data).

### Decision: Canonical platform label casing is Title Case
- **Decision**: Platform labels use Title Case: “Windows”, “Android”, “iOS”, “macOS”, “All”.
- **Rationale**: Improves readability and matches common admin UI expectations.

## Initial Domain → Color Mapping (v1)

This mapping is intentionally small and neutral (allowlist only), and is applied consistently suite-wide:

- Policy type → `gray`
- Policy category → `primary`
- Platform → `info`
- Tenant environment → `primary`
- Visibility/lifecycle → `gray`
- Snapshot type → `gray`

## Open Questions

- Discovery may surface additional tag domains/values. v1 will add them as part of the migration sweep while keeping the neutral palette and domain-based color rule.
