TenantAtlas/specs/124-inventory-coverage-table/research.md
ahmido 3971c315d8 feat: add inventory coverage interactive table (#151)
## Summary
- replace the static Inventory Coverage HTML tables with a Filament native searchable, sortable, filterable table on the existing tenant page
- normalize supported policy types and foundations into one runtime dataset while preserving centralized badge semantics and the documented read-only action-surface exemption
- add the full spec kit artifact set for feature 124 and focused Pest coverage for rendering, search, sort, filters, empty state, and regression-sensitive page copy

## Testing
- `vendor/bin/sail bin pint --dirty --format agent`
- `vendor/bin/sail artisan test --compact tests/Feature/Filament/InventoryCoverageTableTest.php tests/Feature/Filament/InventoryPagesTest.php tests/Feature/Filament/InventoryHubDbOnlyTest.php`

## Filament Notes
- Livewire v4.0+ compliance: yes, this uses Filament v5 table APIs on the existing page and does not introduce any Livewire v3 patterns
- Provider registration: unchanged; Laravel 11+ provider registration remains in `bootstrap/providers.php`
- Globally searchable resources: none changed in this feature; no Resource global-search behavior was added or modified
- Destructive actions: none; the page remains read-only and only exposes a non-destructive clear-filters empty-state action
- Asset strategy: no new panel or shared assets were added, so no `filament:assets` deployment change is required for this feature
- Testing plan delivered: focused Filament/Pest coverage for the page table surface plus existing page-load regressions

## Follow-up
- Manual dark-mode and badge-regression QA from task `T018` is still pending and should be completed before merge if that check remains mandatory in your review flow.

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #151
2026-03-08 18:33:00 +00:00

41 lines
4.2 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.

# 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 `<table>`.
- 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 features core interactions are already well covered by Filaments Livewire testing surface.