TenantAtlas/specs/221-findings-operator-inbox/research.md
ahmido 81bb5f42c7
Some checks failed
Main Confidence / confidence (push) Failing after 55s
feat: add findings operator inbox (#258)
## Summary
- add the canonical admin-plane `My Findings` inbox at `/admin/findings/my-work`
- add the workspace overview `Assigned to me` signal and inbox-to-detail continuity
- add focused Pest coverage plus the full Spec 221 artifact bundle

## Validation
- `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Findings/MyWorkInboxTest.php tests/Feature/Authorization/MyWorkInboxAuthorizationTest.php tests/Feature/Dashboard/MyFindingsSignalTest.php`
- `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Filament/WorkspaceOverviewNavigationTest.php`
- integrated-browser smoke completed against the browser-facing `tenantatlas` runtime, including seeded positive-path and negative-path checks plus fixture cleanup

## Filament v5 Guardrails
- Livewire v4.0+ compliant
- panel provider registration remains in `apps/platform/bootstrap/providers.php`
- global search behavior is unchanged; `FindingResource` already has a View page and the new inbox is a custom page, not a searchable resource
- no destructive actions were introduced on the inbox or overview signal
- no new assets were added; the existing deploy step for `cd apps/platform && php artisan filament:assets` remains unchanged
- coverage includes the new inbox page, authorization boundaries, the workspace overview signal, and the overview CTA regression

Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de>
Reviewed-on: #258
2026-04-21 09:19:54 +00:00

49 lines
5.5 KiB
Markdown

# Research: Findings Operator Inbox V1
## Decision 1: Implement the inbox as an admin panel page with slug `findings/my-work`
- **Decision**: Add a new Filament admin page under the existing `AdminPanelProvider` for the canonical inbox route `/admin/findings/my-work`.
- **Rationale**: The feature is explicitly an admin-plane, workspace-scoped surface. The admin panel already owns comparable custom pages such as `FindingExceptionsQueue`, and page registration gives the correct Filament middleware, route shape, and Livewire page lifecycle without creating a second routing model.
- **Alternatives considered**:
- Reuse the tenant-local `FindingResource` list as the canonical inbox. Rejected because it keeps the operator trapped in tenant-first navigation and does not answer the cross-tenant personal-work question.
- Add a standalone controller route in `routes/web.php`. Rejected because this is a normal admin panel surface, not a one-off shell route like `/admin` home.
## Decision 2: Keep queue truth as a direct `Finding` query, not a new shared query subsystem
- **Decision**: Build the inbox from `Finding` records scoped by current workspace, visible capability-eligible tenant IDs, `assignee_user_id = current user`, and `Finding::openStatusesForQuery()`, with eager-loaded `tenant`, `ownerUser`, and `assigneeUser` relationships.
- **Rationale**: The feature has two concrete consumers, but both are narrow and local: one queue page and one workspace signal. A direct query keeps the logic readable, honors Spec 111 and Spec 219 as-is, and avoids importing a new reusable abstraction before it is clearly needed.
- **Alternatives considered**:
- Introduce a new shared findings-query service immediately. Rejected because the scope is still small and the repo guidance prefers direct implementation until a second real abstraction pressure appears.
- Mix owner and assignee semantics into one queue query. Rejected because Spec 219 explicitly separates assignee work from owner accountability.
## Decision 3: Reuse `CanonicalAdminTenantFilterState` for the default active-tenant prefilter
- **Decision**: Let the inbox synchronize its tenant filter through `CanonicalAdminTenantFilterState`, so the active tenant becomes the default prefilter and can be cleared without removing personal assignment scope.
- **Rationale**: The repo already uses this helper on admin-panel lists and monitoring pages to keep active tenant context honest and clearable. Reusing it keeps the inbox aligned with existing admin context behavior and avoids inventing a page-specific prefilter mechanism.
- **Alternatives considered**:
- Drive tenant prefiltering only through explicit query parameters. Rejected because the feature requirement is about active tenant context, not just shareable URLs.
- Hard-lock the queue to the active tenant whenever tenant context exists. Rejected because the spec requires a clear path back to all visible tenants.
## Decision 4: Add the workspace signal as a dedicated overview payload and Blade block
- **Decision**: Extend `WorkspaceOverviewBuilder` with a compact `my_findings_signal` payload and render it directly in the existing workspace overview Blade view with one explicit CTA.
- **Rationale**: The signal must show open count, overdue count, calm state, and one named CTA. The existing generic `summary_metrics` lane is optimized for one metric value plus description and does not cleanly express the contract without distorting the overview metric family.
- **Alternatives considered**:
- Encode the signal as another generic summary metric. Rejected because the metric card does not naturally expose both counts and an explicit `Open my findings` CTA.
- Add a second standalone dashboard or queue widget. Rejected because the overview only needs a small drill-in signal, not another work surface.
## Decision 5: Preserve queue-to-detail continuity through `CanonicalNavigationContext`
- **Decision**: Append a `CanonicalNavigationContext` payload when an inbox row opens `/admin/t/{tenant}/findings/{finding}` so the detail page can render `Back to my findings`.
- **Rationale**: The repo already uses `CanonicalNavigationContext` for cross-surface return links on admin and tenant detail pages. Reusing it preserves a single continuity model and keeps the return path explicit instead of relying on fragile browser history.
- **Alternatives considered**:
- Depend on the browser referer only. Rejected because it is brittle across reloads, tabs, and copied links.
- Add a new inbox-specific controller just to set session return state. Rejected because the existing navigation context already solves this problem cleanly.
## Decision 6: Prove the feature with three focused feature suites plus one route-alignment extension
- **Decision**: Add `MyWorkInboxTest`, `MyWorkInboxAuthorizationTest`, and `MyFindingsSignalTest` as the three new focused suites, and extend `WorkspaceOverviewNavigationTest` for route-alignment proof.
- **Rationale**: The user-visible risk is visibility, prioritization, tenant safety, and overview-to-inbox truth alignment. Those are best proven through focused feature coverage using the existing workspace and tenant helpers, while the inbox CTA alignment belongs in the existing route-alignment regression instead of a fourth new suite.
- **Alternatives considered**:
- Add browser coverage. Rejected because the surface is simple and already well represented by Filament/Livewire feature assertions.
- Add a unit-only seam around queue counting. Rejected because the important risk is integrated scope behavior, not isolated arithmetic.