210 lines
14 KiB
Markdown
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.
|