TenantAtlas/specs/221-findings-operator-inbox/tasks.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

210 lines
14 KiB
Markdown

# Tasks: Findings Operator Inbox V1
**Input**: Design documents from `/specs/221-findings-operator-inbox/`
**Prerequisites**: `plan.md`, `spec.md`, `research.md`, `data-model.md`, `contracts/findings-operator-inbox.logical.openapi.yaml`, `quickstart.md`
**Tests**: Required. This feature changes runtime behavior on new and existing Filament/Livewire surfaces, so Pest coverage must be added in `apps/platform/tests/Feature/Findings/MyWorkInboxTest.php`, `apps/platform/tests/Feature/Authorization/MyWorkInboxAuthorizationTest.php`, and `apps/platform/tests/Feature/Dashboard/MyFindingsSignalTest.php`, with route-alignment coverage extended in `apps/platform/tests/Feature/Filament/WorkspaceOverviewNavigationTest.php`.
**Operations**: No new `OperationRun`, audit flow, or long-running work is introduced. The inbox and overview signal remain DB-only, read-first surfaces.
**RBAC**: The inbox lives on the admin `/admin` plane and must preserve existing chooser or resume behavior when workspace context is missing, workspace-membership `404` semantics for out-of-scope users, capability-filtered tenant-safe row, filter, and count disclosure inside the queue and overview signal, and existing `404`/`403` behavior on drilldown to `/admin/t/{tenant}/findings/{finding}`.
**UI / Surface Guardrails**: `My Findings` remains the primary decision surface. The `/admin` assigned-to-me signal remains secondary and must not become a second queue.
**Filament UI Action Surfaces**: `MyFindingsInbox` gets one primary inspect model, one conditional `Clear tenant filter` header action, no row actions, no bulk actions, and one empty-state CTA. The workspace overview signal exposes only one CTA: `Open my findings`.
**Badges**: Existing finding severity, lifecycle, and due-state semantics remain authoritative. No page-local badge mappings are introduced.
**Organization**: Tasks are grouped by user story so each slice stays independently testable. Recommended delivery order is `US1 -> US2 -> US3`, because US2 extends the same inbox surface and US3 links to the inbox truth.
## Test Governance Checklist
- [x] Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
- [x] New or changed tests stay in the smallest honest family, and any heavy-governance or browser addition is explicit.
- [x] Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default; any widening is isolated or documented.
- [x] Planned validation commands cover the change without pulling in unrelated lane cost.
- [x] The declared surface test profile or `standard-native-filament` relief is explicit.
- [x] Any material budget, baseline, trend, or escalation note is recorded in the active spec or PR.
## Phase 1: Setup (Inbox Scaffolding)
**Purpose**: Prepare the new admin inbox files and focused regression suites used across all stories.
- [x] T001 [P] Create the new inbox page scaffold in `apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php`
- [x] T002 [P] Create the new inbox page view scaffold in `apps/platform/resources/views/filament/pages/findings/my-findings-inbox.blade.php`
- [x] T003 [P] Create focused Pest scaffolding in `apps/platform/tests/Feature/Findings/MyWorkInboxTest.php`, `apps/platform/tests/Feature/Authorization/MyWorkInboxAuthorizationTest.php`, and `apps/platform/tests/Feature/Dashboard/MyFindingsSignalTest.php`
**Checkpoint**: The new surface and focused test files exist and are ready for shared implementation work.
---
## Phase 2: Foundational (Blocking Route And Scope Seams)
**Purpose**: Establish the canonical admin route, page access shell, and base workspace/tenant scoping every story depends on.
**⚠️ CRITICAL**: No user story work should begin until this phase is complete.
- [x] T004 Register `MyFindingsInbox` in `apps/platform/app/Providers/Filament/AdminPanelProvider.php` and define the page slug and admin-plane access shell in `apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php`
- [x] T005 Implement workspace-membership gating, visible-tenant resolution, capability-filtered row and count disclosure, and eager-loaded base queue scoping in `apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php`
- [x] T006 Add foundational admin-plane page-entry coverage for missing workspace chooser or resume behavior and non-member `404` behavior in `apps/platform/tests/Feature/Authorization/MyWorkInboxAuthorizationTest.php`
**Checkpoint**: The canonical inbox route exists, the page is workspace-scoped, and tenant-safe base access rules are covered.
---
## Phase 3: User Story 1 - See My Assigned Findings In One Queue (Priority: P1) 🎯 MVP
**Goal**: Give the current user one trustworthy cross-tenant queue for visible assigned open findings.
**Independent Test**: Seed multiple visible and hidden tenants with assigned, owner-only, unrelated, and terminal findings, then verify `/admin/findings/my-work` shows only open assigned work from entitled tenants.
### Tests for User Story 1
- [x] T007 [P] [US1] Add assigned-versus-owner, owner-context rendering, open-versus-terminal, entitled-versus-capability-eligible queue visibility, full available-filters contract coverage for fixed assignee scope plus tenant, overdue, reopened, and high-severity filters, applied-scope and summary-count truth, and zero-visible-work empty-state coverage in `apps/platform/tests/Feature/Findings/MyWorkInboxTest.php`
- [x] T008 [P] [US1] Add member-without-capability disclosure boundaries, hidden-tenant suppression, and protected-destination coverage in `apps/platform/tests/Feature/Authorization/MyWorkInboxAuthorizationTest.php`
### Implementation for User Story 1
- [x] T009 [US1] Implement the fixed `assignee = current user` and open-status queue query in `apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php`
- [x] T010 [US1] Implement tenant, finding summary, severity, lifecycle status, due-state, reopened cue, owner context, and calm empty-state rendering with branch-specific CTAs that clear the tenant prefilter when it alone excludes rows or otherwise open active-tenant findings or `/admin/choose-tenant` when no tenant context exists in `apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php` and `apps/platform/resources/views/filament/pages/findings/my-findings-inbox.blade.php`
- [x] T011 [US1] Implement the available-filters contract with fixed assignee scope, capability-safe tenant filter options, active-tenant default prefilter sync, applied-scope metadata, inbox summary counts, and the conditional `Clear tenant filter` header action in `apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php`
**Checkpoint**: User Story 1 is independently functional and the inbox answers “what is assigned to me right now?” without tenant hopping.
---
## Phase 4: User Story 2 - Prioritize Urgent Work And Drill Into The Right Finding (Priority: P1)
**Goal**: Make the queue surface urgent work first and preserve a clear return path after opening the tenant finding detail.
**Independent Test**: Seed overdue, reopened, high-severity, and ordinary assigned findings, open the inbox, verify urgency ordering and filters, then open a row and confirm tenant finding detail plus inbox return continuity.
### Tests for User Story 2
- [x] T012 [P] [US2] Add deterministic overdue-then-reopened ordering with due-date and finding-ID tie-break coverage, reopened/high-severity filters, and tenant-prefilter empty-state CTA coverage in `apps/platform/tests/Feature/Findings/MyWorkInboxTest.php`
- [x] T013 [P] [US2] Add queue-to-detail continuity and protected-destination coverage in `apps/platform/tests/Feature/Authorization/MyWorkInboxAuthorizationTest.php`
### Implementation for User Story 2
- [x] T014 [US2] Implement tenant, overdue, reopened, and high-severity filters plus deterministic urgency sorting of overdue first, reopened next, then ordinary findings, with due-date ascending, undated rows last, and finding-ID tie-breaks in `apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php`
- [x] T015 [US2] Implement inbox row drilldown URLs with `CanonicalNavigationContext` in `apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php`
- [x] T016 [US2] Preserve `Back to my findings` continuity on tenant finding detail in `apps/platform/app/Filament/Resources/FindingResource.php`
**Checkpoint**: User Story 2 is independently functional and the queue now highlights urgent work and lands on the correct finding detail with continuity preserved.
---
## Phase 5: User Story 3 - Discover My Assigned Work From The Workspace Overview (Priority: P2)
**Goal**: Make `/admin` show whether visible assigned findings work exists and link into the canonical inbox in one click.
**Independent Test**: Seed assigned and unassigned work across visible and hidden tenants, open `/admin`, and verify the assigned-to-me signal matches inbox truth, stays calm when appropriate, and drills into `/admin/findings/my-work`.
### Tests for User Story 3
- [x] T017 [P] [US3] Add open-count, overdue-count, calm-state, hidden-tenant suppression, and capability-safe count suppression coverage in `apps/platform/tests/Feature/Dashboard/MyFindingsSignalTest.php`
- [x] T018 [P] [US3] Extend inbox CTA and route-alignment coverage in `apps/platform/tests/Feature/Filament/WorkspaceOverviewNavigationTest.php`
### Implementation for User Story 3
- [x] T019 [US3] Add the `my_findings_signal` payload with visible capability-safe open and overdue counts to `apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php`
- [x] T020 [US3] Render the `Assigned to me` summary block and `Open my findings` CTA in `apps/platform/resources/views/filament/pages/workspace-overview.blade.php`
**Checkpoint**: User Story 3 is independently functional and the workspace overview exposes the same personal-work truth as the inbox.
---
## Phase 6: Polish & Cross-Cutting Concerns
**Purpose**: Finish guardrail alignment, formatting, and focused validation across the full feature.
- [x] T021 Review operator-facing copy, action-surface discipline, and “signal not second queue” guardrails in `apps/platform/app/Filament/Pages/Findings/MyFindingsInbox.php`, `apps/platform/resources/views/filament/pages/findings/my-findings-inbox.blade.php`, `apps/platform/app/Support/Workspaces/WorkspaceOverviewBuilder.php`, and `apps/platform/resources/views/filament/pages/workspace-overview.blade.php`
- [x] T022 Run formatting with `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
- [x] T023 Run the focused verification workflow from `specs/221-findings-operator-inbox/quickstart.md` against `apps/platform/tests/Feature/Findings/MyWorkInboxTest.php`, `apps/platform/tests/Feature/Authorization/MyWorkInboxAuthorizationTest.php`, `apps/platform/tests/Feature/Dashboard/MyFindingsSignalTest.php`, and `apps/platform/tests/Feature/Filament/WorkspaceOverviewNavigationTest.php`
---
## Dependencies & Execution Order
### Phase Dependencies
- **Setup (Phase 1)**: Starts immediately and prepares the new page, view, and focused Pest files.
- **Foundational (Phase 2)**: Depends on Setup and blocks all user stories until the canonical route and base access shell exist.
- **User Story 1 (Phase 3)**: Depends on Foundational completion and is the recommended MVP cut.
- **User Story 2 (Phase 4)**: Depends on User Story 1 because it extends the same inbox query, filter, and drilldown surface.
- **User Story 3 (Phase 5)**: Depends on User Story 1 because the workspace overview signal must link to established inbox truth.
- **Polish (Phase 6)**: Depends on all desired user stories being complete.
### User Story Dependencies
- **US1**: No dependencies beyond Foundational.
- **US2**: Builds directly on the inbox surface introduced in US1.
- **US3**: Depends on the canonical inbox route and queue truth from US1, but not on the urgency and detail work from US2.
### Within Each User Story
- Write the story tests first and confirm they fail before implementation is considered complete.
- Keep page-query and authorization behavior in `MyFindingsInbox.php` authoritative before adjusting Blade copy.
- Finish story-level verification before moving to the next priority slice.
### Parallel Opportunities
- `T001`, `T002`, and `T003` can run in parallel during Setup.
- `T007` and `T008` can run in parallel for User Story 1.
- `T012` and `T013` can run in parallel for User Story 2.
- `T017` and `T018` can run in parallel for User Story 3.
---
## Parallel Example: User Story 1
```bash
# User Story 1 tests in parallel
T007 apps/platform/tests/Feature/Findings/MyWorkInboxTest.php
T008 apps/platform/tests/Feature/Authorization/MyWorkInboxAuthorizationTest.php
```
## Parallel Example: User Story 2
```bash
# User Story 2 tests in parallel
T012 apps/platform/tests/Feature/Findings/MyWorkInboxTest.php
T013 apps/platform/tests/Feature/Authorization/MyWorkInboxAuthorizationTest.php
```
## Parallel Example: User Story 3
```bash
# User Story 3 tests in parallel
T017 apps/platform/tests/Feature/Dashboard/MyFindingsSignalTest.php
T018 apps/platform/tests/Feature/Filament/WorkspaceOverviewNavigationTest.php
```
---
## Implementation Strategy
### MVP First (User Story 1 Only)
1. Complete Phase 1: Setup.
2. Complete Phase 2: Foundational.
3. Complete Phase 3: User Story 1.
4. Validate the inbox against the focused US1 tests before widening the slice.
### Incremental Delivery
1. Ship US1 to establish the canonical personal queue.
2. Add US2 to prioritize work and preserve detail continuity.
3. Add US3 to make the queue discoverable from `/admin`.
4. Finish with copy review, formatting, and the focused verification pack.
### Parallel Team Strategy
1. One contributor can scaffold the page and view while another prepares the focused Pest suites.
2. After Foundational work lands, one contributor can drive inbox visibility and another can harden authorization boundaries.
3. Once US1 is stable, overview signal work can proceed separately from urgency-ordering refinements if needed.
---
## Notes
- `[P]` tasks target different files and can be worked independently once upstream blockers are cleared.
- `[US1]`, `[US2]`, and `[US3]` map directly to the feature specification user stories.
- The suggested MVP scope is Phase 1 through Phase 3 only.
- All implementation tasks above follow the required checklist format with task ID, optional parallel marker, story label where applicable, and exact file paths.