16 KiB
Tasks: Findings Intake & Team Queue V1
Input: Design documents from /specs/222-findings-intake-team-queue/
Prerequisites: plan.md, spec.md, research.md, data-model.md, contracts/findings-intake-team-queue.logical.openapi.yaml, quickstart.md
Tests: Required. This feature changes runtime behavior on a new Filament/Livewire queue surface and a claim mutation path, so Pest coverage must be added in apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php, apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php, and apps/platform/tests/Feature/Findings/FindingsClaimHandoffTest.php.
Operations: No new OperationRun is introduced. The queue remains DB-only and read-first, while Claim finding must reuse the existing finding.assigned audit flow in apps/platform/app/Services/Findings/FindingWorkflowService.php.
RBAC: The intake queue lives on the admin /admin plane and must preserve workspace chooser or resume behavior when workspace context is missing, workspace-membership 404 semantics for out-of-scope users, tenant-safe row and count disclosure inside the queue, and existing 404 and 403 behavior on drilldown to /admin/t/{tenant}/findings/{finding} and claim execution.
UI / Surface Guardrails: Findings intake remains the primary decision surface for pre-assignment routing. /admin/findings/my-work remains the personal execution destination after claim, and the intake queue must not become a second dangerous-action hub.
Filament UI Action Surfaces: FindingsIntakeQueue gets one primary inspect model, one conditional Clear tenant filter header action, one inline safe Claim finding row action with lightweight preview and explicit confirmation, no bulk actions, and one empty-state CTA per branch.
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 shared queue behavior established in US1, US1 plus US2 make up the recommended first releasable intake slice, and US3 depends on the queue truth from US1 but not on every refinement from US2.
Test Governance Checklist
- Lane assignment is named and is the narrowest sufficient proof for the changed behavior.
- New or changed tests stay in the smallest honest family, and any heavy-governance or browser addition is explicit.
- Shared helpers, factories, seeds, fixtures, and context defaults stay cheap by default; any widening is isolated or documented.
- Planned validation commands cover the change without pulling in unrelated lane cost.
- The declared surface test profile or
standard-native-filamentrelief is explicit. - Any material budget, baseline, trend, or escalation note is recorded in the active spec or PR.
Phase 1: Setup (Queue Scaffolding)
Purpose: Prepare the new admin intake files and focused regression suites used across all stories.
- T001 [P] Create the new intake page scaffold in
apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php - T002 [P] Create the new intake page view scaffold in
apps/platform/resources/views/filament/pages/findings/findings-intake-queue.blade.php - T003 [P] Create focused Pest scaffolding in
apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php,apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php, andapps/platform/tests/Feature/Findings/FindingsClaimHandoffTest.php
Checkpoint: The new intake 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 and tenant scoping every story depends on.
⚠️ CRITICAL: No user story work should begin until this phase is complete.
- T004 Register
FindingsIntakeQueueinapps/platform/app/Providers/Filament/AdminPanelProvider.phpand define the page slug and admin-plane access shell inapps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php - T005 Implement workspace-membership gating, visible-tenant resolution, capability-primed tenant disclosure, and active-tenant filter synchronization in
apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php - T006 Add foundational page-entry coverage for workspace chooser or resume behavior, non-member
404, queue-access403when no currently viewable findings scope exists, and base queue disclosure boundaries inapps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php
Checkpoint: The canonical intake route exists, the page is workspace-scoped, and tenant-safe base access rules are covered.
Phase 3: User Story 1 - See Shared Unassigned Backlog In One Queue (Priority: P1)
Goal: Give the current user one trustworthy cross-tenant queue for visible unassigned open findings.
Independent Test: Seed multiple visible and hidden tenants with unassigned, assigned, acknowledged, and terminal findings, then verify /admin/findings/intake shows only visible unassigned rows from Finding::openStatuses().
Tests for User Story 1
- T007 [P] [US1] Add visible-unassigned queue coverage, active-tenant prefilter behavior, assigned and
acknowledgedexclusion, terminal exclusion, hidden-tenant suppression, and both empty-state branches inapps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php - T008 [P] [US1] Add workspace-context recovery, positive tenant-safe queue disclosure for members with viewable findings scope, and protected destination authorization coverage in
apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php
Implementation for User Story 1
- T009 [US1] Implement the base intake query with workspace scope, visible tenant IDs,
assignee_user_id IS NULL,Finding::openStatuses(), and eager-loaded row context inapps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php - T010 [US1] Implement tenant, finding summary, severity, lifecycle, due-state, owner-context, and explicit tenant-prefilter-empty versus backlog-clear empty-state rendering with the correct CTA branch in
apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.phpandapps/platform/resources/views/filament/pages/findings/findings-intake-queue.blade.php - T011 [US1] Implement capability-safe tenant filter options, applied-scope metadata, visible summary counts, and the conditional
Clear tenant filterheader action inapps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php
Checkpoint: User Story 1 is independently functional and the intake page answers “what is still unassigned right now?” without tenant hopping.
Phase 4: User Story 2 - Separate Triage-First Backlog From Later Shared Backlog (Priority: P1)
Goal: Make the queue distinguish Needs triage from the broader unassigned backlog and surface urgent intake in a deterministic order.
Independent Test: Seed unassigned findings in new, reopened, triaged, and in_progress states, then verify the difference between Unassigned and Needs triage, along with overdue and reopened ordering and intake-to-detail continuity.
Tests for User Story 2
- T012 [P] [US2] Add fixed
UnassignedversusNeeds triagecoverage, queue-reason rendering, and view-specific count coverage inapps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php - T013 [US2] Add deterministic urgency ordering and intake-to-detail continuity coverage in
apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php
Implementation for User Story 2
- T014 [US2] Implement fixed
UnassignedandNeeds triagequeue views plus derived queue-reason labels inapps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.phpandapps/platform/resources/views/filament/pages/findings/findings-intake-queue.blade.php - T015 [US2] Implement deterministic overdue, reopened, new, and remaining-backlog ordering plus view-specific summary state in
apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php - T016 [US2] Build intake row URLs with
CanonicalNavigationContextso tenant finding detail preservesBack to findings intakecontinuity fromapps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php
Checkpoint: User Story 2 is independently functional and the queue now highlights what still needs first routing versus what is simply waiting to be claimed.
Phase 5: User Story 3 - Claim A Finding Into Personal Execution (Priority: P2)
Goal: Let an authorized operator claim a visible intake row into /admin/findings/my-work without opening a broader reassignment workflow first.
Independent Test: Claim an eligible intake row, verify assignee becomes the current user, owner and workflow status stay unchanged, the row leaves intake immediately, and a stale or unauthorized claim fails honestly.
Tests for User Story 3
- T017 [P] [US3] Add claim preview/confirmation, successful claim, audit side-effect, immediate intake removal,
Open my findingshandoff, and stale-row conflict coverage inapps/platform/tests/Feature/Findings/FindingsClaimHandoffTest.php - T018 [P] [US3] Add members-without-assign-capability claim rejection and inspect-allowed coverage in
apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php
Implementation for User Story 3
- T019 [US3] Implement the
Claim findingrow action with lightweight pre-commit preview and explicit confirmation, visibility rules, and success or error notifications inapps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php - T020 [US3] Add the claim-specific locked-assignee guard while reusing existing assignment audit semantics in
apps/platform/app/Services/Findings/FindingWorkflowService.php - T021 [US3] Align post-confirmation claim queue refresh and the personal-work handoff state in
apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.phpandapps/platform/resources/views/filament/pages/findings/findings-intake-queue.blade.php
Checkpoint: User Story 3 is independently functional and the shared queue now hands work into personal execution without silent overwrite.
Phase 6: Polish & Cross-Cutting Concerns
Purpose: Finish guardrail alignment, formatting, and focused validation across the full feature.
- T022 Review operator-facing copy, action-surface discipline, and no-bulk-action guardrail alignment in
apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php,apps/platform/resources/views/filament/pages/findings/findings-intake-queue.blade.php,apps/platform/app/Providers/Filament/AdminPanelProvider.php, andapps/platform/app/Services/Findings/FindingWorkflowService.php - T023 Run formatting for
apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php,apps/platform/resources/views/filament/pages/findings/findings-intake-queue.blade.php,apps/platform/app/Providers/Filament/AdminPanelProvider.php,apps/platform/app/Services/Findings/FindingWorkflowService.php,apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php,apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php, andapps/platform/tests/Feature/Findings/FindingsClaimHandoffTest.phpwithcd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent - T024 Run the focused verification workflow from
specs/222-findings-intake-team-queue/quickstart.mdagainstapps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php,apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php, andapps/platform/tests/Feature/Findings/FindingsClaimHandoffTest.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 establishes the base queue behavior required for the first releasable slice.
- User Story 2 (Phase 4): Depends on User Story 1 because it extends the same queue surface with fixed views and ordering behavior and completes the recommended MVP cut.
- User Story 3 (Phase 5): Depends on User Story 1 because claim requires established intake truth, but it does not require User Story 2 to be finished first.
- Polish (Phase 6): Depends on all desired user stories being complete.
User Story Dependencies
- US1: No dependencies beyond Foundational.
- US2: Builds directly on the intake surface introduced in US1.
- US3: Builds on the intake surface and audit-safe assignment semantics from US1, but is independent of the triage-view refinements in 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
FindingsIntakeQueue.phpauthoritative before adjusting Blade copy. - Finish story-level verification before moving to the next priority slice.
Parallel Opportunities
T001,T002, andT003can run in parallel during Setup.T007andT008can run in parallel for User Story 1.T017andT018can run in parallel for User Story 3.
Parallel Example: User Story 1
# User Story 1 tests in parallel
T007 apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php
T008 apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php
Parallel Example: User Story 2
# No recommended parallel split inside US2 after queue-truth coverage was consolidated
T012 apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php
T013 apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php
Parallel Example: User Story 3
# User Story 3 tests in parallel
T017 apps/platform/tests/Feature/Findings/FindingsClaimHandoffTest.php
T018 apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php
Implementation Strategy
MVP First (User Stories 1 And 2)
- Complete Phase 1: Setup.
- Complete Phase 2: Foundational.
- Complete Phase 3: User Story 1.
- Complete Phase 4: User Story 2.
- Validate the intake queue against the focused US1 and US2 tests before widening the slice.
Incremental Delivery
- Ship US1 to establish the canonical shared intake queue.
- Add US2 to separate triage-first backlog from later shared backlog.
- Add US3 to hand eligible rows into
My Findingssafely. - Finish with copy review, formatting, and the focused verification pack.
Parallel Team Strategy
- One contributor can scaffold the page and view while another prepares the focused Pest suites.
- After Foundational work lands, one contributor can drive queue visibility and another can harden authorization boundaries.
- Once US1 is stable, US2 queue-view refinements and US3 claim behavior can proceed in parallel if the shared page seam is coordinated.
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 4.
- All implementation tasks above follow the required checklist format with task ID, optional parallel marker, story label where applicable, and exact file paths.