67 lines
3.3 KiB
Markdown
67 lines
3.3 KiB
Markdown
# Research — Tenant UI Polish (Dashboard + Inventory Hub + Operations)
|
|
|
|
## Goal
|
|
Deliver a drift-first, tenant-scoped UI polish pass that is:
|
|
- DB-only on render and on any auto-refresh.
|
|
- Calm (polling only when needed; no modal churn).
|
|
- Consistent IA (Inventory hub sub-navigation; canonical Operations).
|
|
|
|
## Existing Code & Patterns (to reuse)
|
|
|
|
### Operations
|
|
- Canonical list/detail already exist via `OperationRunResource` (`/operations`).
|
|
- Tenant scoping already enforced in `OperationRunResource::getEloquentQuery()`.
|
|
- Detail view already uses conditional polling with safeguards (tab hidden / modal open) via `RunDetailPolling`.
|
|
|
|
### Inventory
|
|
- Inventory entry page exists as `InventoryLanding`.
|
|
- Inventory “Items” and “Sync Runs” are currently resources (`InventoryItemResource`, `InventorySyncRunResource`).
|
|
- Inventory sync “start surface” already follows constitution rules: authorize → create/reuse `OperationRun` → enqueue job → “View run”.
|
|
|
|
### Monitoring DB-only + Tenant isolation tests
|
|
- Monitoring/Operations has DB-only tests and tenant scope tests.
|
|
- Inventory landing + coverage have basic smoke tests.
|
|
|
|
## Key Decisions
|
|
|
|
### Decision: Use Filament clusters to implement the Inventory “hub” navigation
|
|
- **Decision**: Create an Inventory cluster and attach:
|
|
- `InventoryLanding` (page)
|
|
- Inventory items resource
|
|
- Inventory sync runs resource
|
|
- `InventoryCoverage` (page)
|
|
- **Rationale**: Filament clusters are designed for “common sub-navigation between pages”, including mixing pages and resources.
|
|
- **Notes**:
|
|
- Requires enabling cluster discovery in the panel provider.
|
|
- Sub-navigation position will be set to `Start` to achieve left-side navigation.
|
|
|
|
### Decision: Implement KPI headers as widgets (StatsOverviewWidget / TableWidget)
|
|
- **Decision**: Use Filament widgets for KPI headers on:
|
|
- Tenant dashboard (drift + ops)
|
|
- Inventory hub (inventory KPIs)
|
|
- Operations index (ops KPIs)
|
|
- **Rationale**: Widgets are first-class, composable, and can optionally poll (with `$pollingInterval`) while remaining DB-only.
|
|
|
|
### Decision: “Calm UI” auto-refresh strategy
|
|
- **Decision**:
|
|
- Dashboard + Operations index: enable polling only while active runs exist.
|
|
- Widgets/tables: polling is disabled when no active runs exist.
|
|
- No polling inside modals.
|
|
- **Rationale**: Matches FR-012 and avoids background churn.
|
|
- **Implementation approach**:
|
|
- Use Filament polling mechanisms:
|
|
- Widgets: `$pollingInterval = null | '10s'` depending on “active runs exist”.
|
|
- Tables: enable `$table->poll('10s')` only when “active runs exist”.
|
|
|
|
### Decision: No Graph / remote dependencies
|
|
- **Decision**: All queries for this feature are Eloquent/PostgreSQL queries.
|
|
- **Rationale**: Matches constitution and SC-005.
|
|
|
|
## Alternatives Considered
|
|
- **Custom Blade layouts for hub navigation**: Rejected because clusters provide consistent sub-nav across resources/pages without fragile view overrides.
|
|
- **Always-on polling**: Rejected to comply with calm UI rules and avoid waste.
|
|
- **Keep `Monitoring/Operations` as canonical**: Rejected because `OperationRunResource` is already the canonical Operations surface with correct routing and detail pages.
|
|
|
|
## Open Questions
|
|
None — all “NEEDS CLARIFICATION” items are resolved for planning.
|