---
feature: "002-filament-json"
description: "Policy View UI: readable JSON + structured settings using pepperfm/filament-json (Filament v4)"
date: "2025-12-13"
owner: "TenantPilot"
branch: "tenantpilot-v1"
related_features:
  - "001-rbac-onboarding (core v1)"
status: "draft"
---

# Spec: 002 – Filament JSON UI for Policy Views

## Summary

Improve **readability** of policy snapshots/settings in the admin UI by using a JSON viewer/editor-style component (read-only) for places where raw JSON is currently hard to scan (especially `settingsCatalogPolicy` and large snapshots).

This feature is **UI-only**: it does not change sync, backup, restore logic, or the restore matrix. It must not introduce new Graph calls, token storage, or tenant-scope changes.

Primary implementation target:
- **Policies → View Policy** (first)
Secondary (optional in this feature, if low-risk):
- **Policy Versions → View Policy Version** (Raw JSON section only)

We intend to use `pepperfm/filament-json:^4` (Filament 4 compatible) to render JSON blocks elegantly (folding, search, copy, monospace, line wrapping) while keeping tables where tables are clearly better (e.g., flattened settings rows).

---

## Goals

- Make Policy snapshots/settings **human-readable** for admins without scrolling horizontally forever.
- Provide a **JSON viewer** that supports:
  - folding/collapsing
  - search within JSON
  - copy-to-clipboard
  - stable monospace formatting
  - safe truncation or "large payload" handling
- Apply this primarily in **Policy View** (not everywhere), to keep blast radius small.

## Non-Goals

- No new policy types, no changes to supported types, restore matrix, contract registry behavior.
- No new domain behavior (no diff algorithm changes, no restore logic changes).
- No new background jobs, no new persistence of normalized output.
- No replacing tables universally — only where JSON viewer clearly improves UX.

---

## User Scenarios & Testing *(mandatory)*

### User Story 1 - Admin reads policy snapshot quickly (Priority: P1)

As an admin, I can open a policy detail page and view the snapshot/settings in a readable format (foldable JSON + structured highlights), so I can understand what the policy does without digging through raw dumps.

**Why this priority**: Core value proposition of this feature - making existing data readable.

**Independent Test**: Open any policy with a captured snapshot; verify JSON viewer renders with fold/collapse + copy button.

**Acceptance Scenarios**:

1. **Given** a policy with a captured snapshot, **When** admin opens Policy View, **Then** JSON viewer renders the snapshot with fold/collapse controls.
2. **Given** a large policy snapshot, **When** admin opens Policy View, **Then** UI shows "Large payload" warning and collapses by default.

---

### User Story 2 - Admin inspects large settings catalog policies without pain (Priority: P1)

As an admin, I can view `settingsCatalogPolicy` settings with both:
- a **table** view for quick scanning (definition/value)
- an optional **JSON viewer** view for deep inspection (full hydrated snapshot/settings)

**Why this priority**: Settings Catalog policies are the most complex and need both table + JSON representations.

**Independent Test**: Open a Settings Catalog policy; verify both tabs (Settings table + JSON viewer) exist and render correctly.

**Acceptance Scenarios**:

1. **Given** a settingsCatalogPolicy with hydrated settings, **When** admin opens Policy View, **Then** Settings tab shows table AND JSON tab shows full snapshot.
2. **Given** a settingsCatalogPolicy, **When** admin switches between tabs, **Then** no content overflow or layout break occurs.

---

### User Story 3 - Admin copies a relevant JSON fragment (Priority: P2)

As an admin, I can copy JSON (whole snapshot or selected view) to share/debug safely, without secrets.

**Why this priority**: Enables debugging and support workflows.

**Independent Test**: Click copy button in JSON viewer; verify clipboard contains valid JSON.

**Acceptance Scenarios**:

1. **Given** JSON viewer is open, **When** admin clicks "Copy JSON", **Then** clipboard contains the full snapshot JSON.
2. **Given** a large payload with truncation, **When** admin clicks "Copy full JSON", **Then** action completes without freezing browser.

---

### Edge Cases

- Snapshot missing or malformed: show "No snapshot available" or "Malformed snapshot" warning.
- Extremely large payloads (>1 MB): show warning + collapsed by default + optional download.
- Missing settings hydration (settingsCatalogPolicy): show "Settings not hydrated" hint.

## Requirements *(mandatory)*

### Functional Requirements

- **FR-036**: JSON viewer component on Policy View
  - **Policies → View Policy** MUST render the policy's snapshot/settings (where raw JSON is shown) using a **read-only JSON viewer** based on `pepperfm/filament-json`.
  - Viewer MUST support fold/collapse + search + copy.

- **FR-037**: Placement and scope
  - JSON viewer MUST be implemented **only** on **Policy View** for this feature.
  - Policy Versions page changes are OPTIONAL and only apply to the **Raw JSON** block if included.

- **FR-038**: Large payload handling
  - If a JSON payload exceeds thresholds (see NFRs), the UI MUST:
    - show a warning badge ("Large payload – truncated for display")
    - provide a "Copy full JSON" action **only if** it can be done without freezing the browser
    - otherwise "Copy truncated JSON" + "Download JSON" (optional) may be used, but download MUST be access-controlled and tenant-scoped.

- **FR-039**: Preserve existing table UI where it's better
  - Existing structured/tabled settings views (e.g., Settings Catalog table) SHOULD remain.
  - JSON viewer is an additional/alternative representation, preferably behind tabs:
    - Tab A: "Settings" (table/search)
    - Tab B: "JSON" (viewer)

- **FR-040**: No behavioral changes
  - This feature MUST NOT add Graph calls, modify restore behavior, or change snapshot capture logic.
  - No changes to audit logging schema required.

- **FR-041**: Asset publishing safety
  - Installing the plugin MUST NOT accidentally commit massive published assets unless explicitly intended.
  - If assets must be published, the process MUST be documented and repeatable (see NFR + Ops).

### Non-Functional Requirements (Measurable)

- **NFR-036.1 Performance**: UI should remain responsive when rendering JSON up to:
  - 500 KB inline viewer payload (soft limit)
  - Above that: show warning + fallback (collapsed by default + optional download)
- **NFR-036.2 Safety**: Viewer is **read-only** (no editing, no save).
- **NFR-036.3 Tenant isolation**: Any download/copy action must operate only on the current tenant's record.
- **NFR-036.4 Consistency**: Viewer uses the same snapshot source as existing UI (no "different data" between table and JSON).
- **NFR-036.5 Styling**:
  - no horizontal overflow beyond card bounds
  - long keys/values wrap or are truncated with tooltip
  - spacing consistent with Filament sections (padding, max width)

### UX Requirements

- Default view on Policy page:
  - If settings table exists (settings catalog): show table first.
  - Provide "JSON" tab for deep inspection.
- JSON viewer:
  - start collapsed for huge payloads
  - show line numbers (if supported)
  - copy button visible
- For missing settings hydration:
  - show "Settings not hydrated" warning with hint to re-sync/capture.

## Success Criteria *(mandatory)*

### Measurable Outcomes

- **SC-001**: On **Policies → View Policy**, a JSON viewer is visible and readable (fold/search/copy).
- **SC-002**: No content overflows the card/container.
- **SC-003**: For large payloads, UI shows a warning and does not freeze.
- **SC-004**: Existing Settings Catalog table remains usable (search works, values not cut off silently).
- **SC-005**: No changes in backup/restore behavior (same tests pass).
- **SC-006**: Build/CI passes: `./vendor/bin/pest` and `./vendor/bin/pint --dirty`.
- **SC-007**: No unintended committed asset floods (or, if committed, documented and intentional).

## Exclusions *(optional - only if scope needs clarification)*

The following is intentionally excluded from this specification:
- Global refactor of all JSON views across the app.
- Replacing diff UI with a new viewer.
- Introducing a full "policy editor" experience.
- Changing contract registry/hydration/restore payload rules.

## Risks / Notes

- Composer post-update hooks may fail locally if DB is unreachable (e.g., `boost:update` touching cache DB). This must not block the feature conceptually; document a safe local workflow (Sail up first or skip hook locally).
- `filament:upgrade` / asset publishing can overwrite `public/` assets; decide explicitly whether to commit these artifacts or rely on deploy build steps.
- Plugin fit: ensure `pepperfm/filament-json` is compatible with Filament 4 and used in **infolists** / **view pages** (not forms) in read-only mode.

## Traceability

- Implements: US-UI-01, US-UI-02, US-UI-03
- Implements: FR-036, FR-037, FR-038, FR-039, FR-040, FR-041
- NFRs: NFR-036.1, NFR-036.2, NFR-036.3, NFR-036.4, NFR-036.5
