# Research: Inventory Coverage Interactive Table ## Decision 1: Use a Filament custom-data table on the existing page - Decision: Implement the page as a Filament `HasTable` / `InteractsWithTable` page backed by custom runtime records rather than a raw Blade ``. - Rationale: Filament v5 explicitly supports custom-data tables with search, sort, filters, and pagination via `records()` and a paginator. That matches the current coverage source, which is derived from arrays and resolvers instead of Eloquent models. - Alternatives considered: - Keep the Blade table and add ad-hoc Alpine or JavaScript interactions: rejected because it would still sit outside the established Filament product surface and duplicate table behavior the framework already provides. - Introduce a database-backed coverage model: rejected because the spec explicitly excludes data-model redesign and the current source of truth is already deterministic. ## Decision 2: Normalize supported policy types and foundations into one runtime dataset - Decision: Build one normalized collection of coverage rows with a `segment` field that distinguishes policy types from foundations. - Rationale: A single table provides one search box, one filter bar, one sorting model, and one empty-state pattern. The extra segment field preserves the existing semantic distinction without forcing duplicate controls across two separate tables. - Alternatives considered: - Keep two separate Filament tables: rejected because it would split search/filter state and make the page feel heavier while still not solving cross-surface discoverability. - Hide foundations in a secondary collapsible section: rejected because it weakens the current coverage storytelling and makes total support harder to scan. ## Decision 3: Derive filter options from the loaded dataset and show restore filtering only when supported - Decision: Build category filter options from distinct category values in the normalized dataset and only register a restore-mode filter when at least one row exposes a restore value. - Rationale: This keeps filters honest to the current data shape, avoids dead controls, and respects the spec requirement to add restore filtering only if that attribute exists. - Alternatives considered: - Always show a restore filter with guessed default values: rejected because it would imply data fidelity that the current source may not provide. - Hardcode category and restore options: rejected because options already live in the metadata catalog and should remain source-driven. ## Decision 4: Preserve badge semantics by reusing existing badge catalogs inside table column rendering - Decision: Keep all type, category, restore, and risk badge rendering delegated to the existing shared badge catalogs and render them from Filament table columns. - Rationale: The constitution requires centralized badge semantics. Reusing the existing catalogs keeps labels, colors, and icons aligned with the rest of the application while allowing the page layout to change. - Alternatives considered: - Rebuild badges inline inside the table columns: rejected because it would duplicate logic and risk semantic drift. - Replace badges with plain text for easier testing: rejected because it would degrade the trust and scanability goals of the feature. ## Decision 5: Test the page as a Livewire table surface and keep manual QA only for visual concerns - Decision: Add a focused Pest feature/component test for the page that uses Filament table helpers to verify page load, search, category filtering, conditional restore filtering, and sorting. Keep dark-mode and badge visual validation as manual QA. - Rationale: Filament v5 documents `searchTable()`, `filterTable()`, and `sortTable()` for table verification, and the repo already uses these patterns in existing Filament tests. That gives fast regression coverage without promoting a purely visual behavior into brittle snapshot tests. - Alternatives considered: - Rely on existing page-load coverage only: rejected because the main risk in this feature is interaction regression, not route availability. - Browser-test the whole surface: rejected for the initial implementation because the feature’s core interactions are already well covered by Filament’s Livewire testing surface.