Some checks failed
Main Confidence / confidence (push) Failing after 44s
## Summary - add the new admin findings intake queue at `/admin/findings/intake` with fixed `Unassigned` and `Needs triage` views, tenant-safe filtering, claim flow, and continuity into tenant finding detail and `My Findings` - add Spec 222 artifacts (`spec`, `plan`, `tasks`, `research`, `data model`, `quickstart`, contract, checklist) and register the new admin page - fix follow-up regressions uncovered during full-suite validation around findings action-surface declarations, findings list default columns, provider-blocked run messaging, operation catalog aliases, and workspace overview query volume ## Validation - `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent` - `cd apps/platform && ./vendor/bin/sail artisan test --compact tests/Feature/Findings/FindingsIntakeQueueTest.php tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php tests/Feature/Findings/FindingsClaimHandoffTest.php` - `cd apps/platform && ./vendor/bin/sail artisan test --compact` ## Notes - Filament remains on v5 with Livewire v4-compatible patterns - provider registration remains unchanged in `apps/platform/bootstrap/providers.php` - no new assets or schema changes are introduced Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #260
211 lines
16 KiB
Markdown
211 lines
16 KiB
Markdown
# 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
|
|
|
|
- [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 (Queue Scaffolding)
|
|
|
|
**Purpose**: Prepare the new admin intake files and focused regression suites used across all stories.
|
|
|
|
- [x] T001 [P] Create the new intake page scaffold in `apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php`
|
|
- [x] T002 [P] Create the new intake page view scaffold in `apps/platform/resources/views/filament/pages/findings/findings-intake-queue.blade.php`
|
|
- [x] T003 [P] Create focused Pest scaffolding in `apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php`, `apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php`, and `apps/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.
|
|
|
|
- [x] T004 Register `FindingsIntakeQueue` 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/FindingsIntakeQueue.php`
|
|
- [x] 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`
|
|
- [x] T006 Add foundational page-entry coverage for workspace chooser or resume behavior, non-member `404`, queue-access `403` when no currently viewable findings scope exists, and base queue disclosure boundaries in `apps/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
|
|
|
|
- [x] T007 [P] [US1] Add visible-unassigned queue coverage, active-tenant prefilter behavior, assigned and `acknowledged` exclusion, terminal exclusion, hidden-tenant suppression, and both empty-state branches in `apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php`
|
|
- [x] 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
|
|
|
|
- [x] 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 in `apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php`
|
|
- [x] 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.php` and `apps/platform/resources/views/filament/pages/findings/findings-intake-queue.blade.php`
|
|
- [x] T011 [US1] Implement capability-safe tenant filter options, applied-scope metadata, visible summary counts, and the conditional `Clear tenant filter` header action in `apps/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
|
|
|
|
- [x] T012 [P] [US2] Add fixed `Unassigned` versus `Needs triage` coverage, queue-reason rendering, and view-specific count coverage in `apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php`
|
|
- [x] 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
|
|
|
|
- [x] T014 [US2] Implement fixed `Unassigned` and `Needs triage` queue views plus derived queue-reason labels in `apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php` and `apps/platform/resources/views/filament/pages/findings/findings-intake-queue.blade.php`
|
|
- [x] 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`
|
|
- [x] T016 [US2] Build intake row URLs with `CanonicalNavigationContext` so tenant finding detail preserves `Back to findings intake` continuity from `apps/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
|
|
|
|
- [x] T017 [P] [US3] Add claim preview/confirmation, successful claim, audit side-effect, immediate intake removal, `Open my findings` handoff, and stale-row conflict coverage in `apps/platform/tests/Feature/Findings/FindingsClaimHandoffTest.php`
|
|
- [x] 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
|
|
|
|
- [x] T019 [US3] Implement the `Claim finding` row action with lightweight pre-commit preview and explicit confirmation, visibility rules, and success or error notifications in `apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php`
|
|
- [x] T020 [US3] Add the claim-specific locked-assignee guard while reusing existing assignment audit semantics in `apps/platform/app/Services/Findings/FindingWorkflowService.php`
|
|
- [x] T021 [US3] Align post-confirmation claim queue refresh and the personal-work handoff state in `apps/platform/app/Filament/Pages/Findings/FindingsIntakeQueue.php` and `apps/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.
|
|
|
|
- [x] 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`, and `apps/platform/app/Services/Findings/FindingWorkflowService.php`
|
|
- [x] 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`, and `apps/platform/tests/Feature/Findings/FindingsClaimHandoffTest.php` with `cd apps/platform && ./vendor/bin/sail bin pint --dirty --format agent`
|
|
- [x] T024 Run the focused verification workflow from `specs/222-findings-intake-team-queue/quickstart.md` against `apps/platform/tests/Feature/Findings/FindingsIntakeQueueTest.php`, `apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php`, and `apps/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.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.
|
|
- `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/FindingsIntakeQueueTest.php
|
|
T008 apps/platform/tests/Feature/Authorization/FindingsIntakeAuthorizationTest.php
|
|
```
|
|
|
|
## Parallel Example: User Story 2
|
|
|
|
```bash
|
|
# 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
|
|
|
|
```bash
|
|
# 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)
|
|
|
|
1. Complete Phase 1: Setup.
|
|
2. Complete Phase 2: Foundational.
|
|
3. Complete Phase 3: User Story 1.
|
|
4. Complete Phase 4: User Story 2.
|
|
5. Validate the intake queue against the focused US1 and US2 tests before widening the slice.
|
|
|
|
### Incremental Delivery
|
|
|
|
1. Ship US1 to establish the canonical shared intake queue.
|
|
2. Add US2 to separate triage-first backlog from later shared backlog.
|
|
3. Add US3 to hand eligible rows into `My Findings` safely.
|
|
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 queue visibility and another can harden authorization boundaries.
|
|
3. 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.
|