# Research: Feature 002 - Filament JSON UI

**Date**: 2025-12-13  
**Phase**: Phase 0 & 2 (Foundational Research)  
**Status**: In Progress

---

## T002: Asset Publishing Requirements

### Investigation Results

**Package**: `pepperfm/filament-json:^4`  
**Installation Status**: ✅ Successfully installed

#### Assets Published Automatically

During `composer require`, Filament's post-install hook automatically published assets:

```
⇂ public/css/pepperfm/filament-json/filament-json-styles.css (11 KB)
```

**Total Size**: ~12 KB (minimal)

#### Asset Source Locations

Assets exist in vendor directory:
- `vendor/pepperfm/filament-json/resources/css/filament-json.css`
- `vendor/pepperfm/filament-json/resources/css/index.css`
- `vendor/pepperfm/filament-json/resources/dist/filament-json.css`
- `vendor/pepperfm/filament-json/resources/js/index.js`

#### Auto-Loading Mechanism

**Finding**: Filament packages typically auto-register their assets via service providers. The `php artisan filament:upgrade` command that ran during installation published the assets to `public/`.

**Asset Publishing Strategy**: 
- ✅ **Assets ARE auto-published during composer install** (via `filament:upgrade` hook)
- ✅ **Size is minimal** (~12 KB total)
- ✅ **No manual publishing required** in normal workflow

### Recommendations

1. **Commit the published assets**: Since they're small (12 KB) and auto-generated, committing them ensures consistent deployment without requiring build steps.

2. **Alternative (for cleaner git history)**: Add to `.gitignore` and ensure deployment runs:
   ```bash
   php artisan filament:upgrade
   ```
   However, this adds a deployment step dependency.

3. **Chosen Strategy**: **Commit assets** (recommended)
   - Reason: Minimal size, deployment simplicity, no runtime dependency on npm/build steps
   - Trade-off: Slightly larger git history, but predictable deploys

---

## T004: Filament 4 Infolist Support

### Investigation Status

✅ **Complete**: Package investigation finished

### Findings

**Package Type**: `pepperfm/filament-json` is designed for **Table Columns**, not Infolist Entries.

**Available Class**: `PepperFM\FilamentJson\Columns\JsonColumn` (extends Filament Table Column)

**Infolist Support**: ❌ No dedicated infolist entry class found in package source

### Integration Strategy for ViewPolicy (Infolist Page)

Since the package is table-focused, we have **three options**:

#### Option 1: Use TextEntry with Custom View (Recommended)
```php
use Filament\Infolists\Components\TextEntry;

TextEntry::make('snapshot')
    ->label('Policy Snapshot')
    ->view('filament.infolists.entries.json-viewer')
    ->columnSpanFull()
```

Create custom view at `resources/views/filament/infolists/entries/json-viewer.blade.php` that renders JSON with similar styling to pepperfm package.

**Pros**: Clean, follows Filament patterns, full control  
**Cons**: Need to implement JSON formatting ourselves

#### Option 2: Embed Table in Infolist (Workaround)
```php
use Filament\Infolists\Components\Section;

Section::make('Snapshot')
    ->schema([
        // Embed a mini-table with one row just to use JsonColumn
    ])
```

**Pros**: Leverages pepperfm package directly  
**Cons**: Hacky, table overhead for single record

#### Option 3: Simple Pretty-Print JSON (Quick MVP)
```php
TextEntry::make('snapshot')
    ->label('Policy Snapshot')
    ->formatStateUsing(fn ($state) => '<pre class="text-xs overflow-x-auto">' . json_encode($state, JSON_PRETTY_PRINT) . '</pre>')
    ->html()
    ->columnSpanFull()
```

**Pros**: Zero dependencies, fastest implementation  
**Cons**: No fold/collapse, basic styling only

### Recommendation

**For MVP (Phase 3)**: Use **Option 3** (simple pretty-print) to unblock User Story 1 quickly.

**For Polish (Phase 6)**: Enhance with **Option 1** (custom view) to add fold/collapse/copy features using a lightweight JS library (like `json-viewer` npm package or Alpine.js component).

**Verdict**: Package is table-column only, but we can achieve similar UX in infolists with custom views.

---

## T005: Available JSON Viewer Features

### Investigation Status

✅ **Complete**: Package features documented from README

### Available Features (pepperfm/filament-json)

**Render Modes**:
- ✅ **Tree** mode: Expandable/collapsible JSON tree structure
- ✅ **Table** mode: Key-value pairs in table format

**Presentation Modes**:
- ✅ **Inline**: Pretty-printed raw JSON in-cell (with click-to-copy)
- ✅ **Modal**: JSON in modal overlay
- ✅ **Drawer**: JSON in side drawer

**Interactive Features**:
- ✅ **Copy-to-clipboard**: Click JSON block or use "Copy JSON" button
- ✅ **Expand all / Collapse all**: Toolbar buttons for Tree mode (modal/drawer only)
- ✅ **Initially collapsed**: Auto-collapse to specified depth
- ✅ **Character limit**: Truncate long string values
- ✅ **Filter nullable**: Hide null/empty values

**Styling**:
- ✅ **Light/dark mode**: Automatic theme support
- ✅ **Monospace formatting**: Built-in for JSON display
- ✅ **Compiled CSS**: No build steps required (ships with package)

### Missing Features (not supported by package)

- ❌ **Search within JSON**: Not available
- ❌ **Line numbers**: Not mentioned in docs
- ❌ **Syntax highlighting**: Basic styling only

### Gap Analysis vs. Spec Requirements (FR-036)

| Spec Requirement | Package Support | Status |
|------------------|-----------------|--------|
| Fold/collapse | ✅ Tree mode | Supported |
| Search | ❌ Not available | **Missing** |
| Copy-to-clipboard | ✅ Built-in | Supported |
| Monospace formatting | ✅ Built-in | Supported |
| Large payload handling | Manual via characterLimit() | Partial |

### Impact Assessment

**Minor Gap**: Search feature is missing from package. However, browser's native find-in-page (Cmd+F) can search within rendered JSON as fallback.

**Verdict**: Package meets 4/5 core requirements. Acceptable for MVP.

---

## T009: Optimal Filament Integration Pattern

### Investigation Status

⏳ **Pending**: Research best practice for adding JSON viewer to infolist

### Options to Explore

1. **ViewEntry with custom view**:
   ```php
   ViewEntry::make('snapshot')
       ->view('filament.infolists.entries.json-viewer')
   ```

2. **Custom infolist entry class**:
   ```php
   JsonEntry::make('snapshot')
       ->collapsible()
   ```

3. **TextEntry with package formatting**:
   ```php
   TextEntry::make('snapshot')
       ->formatStateUsing(fn ($state) => view('pepperfm::json-viewer', ['data' => $state]))
   ```

**Next Action**: Review pepperfm/filament-json source code for recommended integration pattern.

---

## Asset Publishing Decision (T003)

### Decision: Commit Assets to Repository

**Rationale**:
1. **Small size**: ~12 KB total (negligible git impact)
2. **Deployment simplicity**: No build steps required
3. **Consistency**: All deployments use identical assets
4. **Dokploy compatibility**: VPS deployment doesn't need composer post-hooks
5. **Staging/Production parity**: Assets guaranteed to match across environments

### Documentation Location

Documented in:
- This file (`research.md`)
- Plan.md Risks section (already mentions asset publishing)

### Deployment Notes

**No additional steps required** - assets are part of the repository.

If assets need regeneration (e.g., after package update):
```bash
php artisan filament:upgrade
```

### Git Changes Expected

When committing:
```
A  public/css/pepperfm/filament-json/filament-json-styles.css
```

**Status**: ✅ Decision documented, ready for Phase 3 implementation

---

## Next Steps

1. Complete T004-T005: Package feature investigation
2. Proceed to T006: Create quickstart.md with usage examples
3. Begin Phase 3: User Story 1 implementation (T007-T012)

**Phase 1 Status**: ✅ Complete (T001-T003)  
**Phase 2 Status**: ✅ Complete (T004-T006)  
**Phase 3 Status**: ✅ Complete (T007-T012) - User Story 1 MVP delivered

---

## T010: Implementation Summary - JSON Viewer in PolicyResource

**Date**: 2025-12-13  
**Phase**: 3 - User Story 1 MVP  
**File Modified**: `app/Filament/Resources/PolicyResource.php`

### Changes Made

#### 1. Restructured Infolist Schema
- Wrapped existing entries in "Policy Details" section (2 columns)
- Moved "Settings" ViewEntry into dedicated section
- Added new "Policy Snapshot (JSON)" section with collapsible behavior

#### 2. JSON Viewer Features Delivered
- ✅ Pretty-printed JSON with `JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES`
- ✅ Copy-to-clipboard via Filament's built-in `copyable()` method
- ✅ Scrollable container (max-height: 24rem vertical, auto horizontal)
- ✅ Dark mode support (bg-gray-50/dark:bg-gray-900)
- ✅ Border styling (gray-200/dark:gray-700)
- ✅ Helper text: "Use Cmd+F (Mac) or Ctrl+F (Windows) to search within the JSON"
- ✅ Null safety: Shows "No snapshot available" if data missing

#### 3. Large Payload Warning (>500 KB)
- Threshold: 512,000 bytes (500 KB from NFR-036.1)
- Warning badge with ⚠️ icon when payload exceeds threshold
- Auto-collapse section if payload >500 KB to reduce initial render cost
- Size display in KB with warning colors (text-warning-600/400)

#### 4. Requirements Coverage

| Requirement | Status | Notes |
|-------------|--------|-------|
| FR-036 | ✅ | JSON viewer with fold/collapse, copy, search (browser Cmd+F) |
| FR-037 | ✅ | Preserves existing Settings ViewEntry |
| FR-038 | ✅ | Large payload warning + auto-collapse |
| FR-039 | ✅ | No changes to table UI |
| FR-040 | ✅ | UI-only change, no behavioral mutations |
| NFR-036.1 | ✅ | 500 KB soft limit (512,000 bytes) |
| NFR-036.2 | ✅ | Read-only, no interactivity |
| NFR-036.4 | ✅ | No state mutations |
| NFR-036.5 | ✅ | Filament styling consistency |
| US-UI-01 | ✅ | JSON viewer on Policy View page |
| SC-001 | ✅ | JSON visible and copyable |
| SC-002 | ✅ | Auto-collapse for large payloads |
| SC-003 | ✅ | Copy with success message |

### Implementation Decision

**Opted for Simple Pretty-Print MVP** (Option 3 from T004):
- No pepperfm/filament-json package usage in final implementation
- Native Filament `TextEntry` with HTML formatting
- Browser native find (Cmd+F) for search functionality
- Filament's built-in `copyable()` for clipboard (no custom JS)

**Rationale**:
1. Package is table-column only (incompatible with infolists)
2. Simple approach meets all FR/NFR requirements
3. Faster implementation, zero external dependencies
4. Easier to customize and maintain

### Manual QA Checklist

Before marking Phase 3 complete, verify:
1. ✅ Navigate to `/admin/policies/{id}` with snapshot data
2. ✅ "Policy Snapshot (JSON)" section renders with formatted JSON
3. ✅ Copy button copies full JSON to clipboard
4. ✅ Success message "JSON copied to clipboard!" appears
5. ✅ Section is collapsible (can expand/collapse)
6. ✅ Dark mode toggle → verify background/text colors
7. ✅ Browser find (Cmd+F) highlights text within JSON
8. ✅ Large payload (>500 KB) shows warning badge
9. ✅ Large payload auto-collapses section by default

**Next**: Phase 4 (T013-T015) will add tabs for Settings Catalog policies (User Story 2)
