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
57 lines
7.0 KiB
Markdown
57 lines
7.0 KiB
Markdown
# Research: Findings Intake & Team Queue V1
|
|
|
|
## Decision 1: Implement the intake queue as an admin panel page with slug `findings/intake`
|
|
|
|
- **Decision**: Add a new Filament admin page under the existing `AdminPanelProvider` for the canonical route `/admin/findings/intake`.
|
|
- **Rationale**: The feature is an admin-plane, workspace-scoped decision surface, not a tenant-local variant of the existing findings resource. A page registration keeps the same Filament middleware, route shape, session handling, and Livewire page lifecycle already used by `MyFindingsInbox`.
|
|
- **Alternatives considered**:
|
|
- Reuse the tenant-local `FindingResource` list with a preset filter. Rejected because it still forces tenant-first navigation and does not answer the cross-tenant intake question.
|
|
- Add a standalone controller route in `routes/web.php`. Rejected because this is a normal admin panel surface and should stay inside Filament routing and guardrails.
|
|
|
|
## Decision 2: Keep intake truth as a direct `Finding` query, but use `Finding::openStatuses()` instead of `openStatusesForQuery()`
|
|
|
|
- **Decision**: Build the intake queue from `Finding` records scoped by current workspace, visible tenant IDs, `assignee_user_id IS NULL`, and `Finding::openStatuses()`.
|
|
- **Rationale**: Spec 222 explicitly reuses Spec 111 open statuses for intake: `new`, `triaged`, `in_progress`, and `reopened`. The broader `openStatusesForQuery()` helper includes `acknowledged`, which belongs in existing tenant-local workflows but not in this shared intake queue.
|
|
- **Alternatives considered**:
|
|
- Reuse `Finding::openStatusesForQuery()` exactly as `MyFindingsInbox` does. Rejected because it would leak `acknowledged` rows into intake and violate FR-003.
|
|
- Introduce a new shared intake-query service immediately. Rejected because there is still only one concrete intake consumer and the repo guidance prefers direct implementation until reuse pressure is real.
|
|
|
|
## Decision 3: Model `Unassigned` and `Needs triage` as fixed page-level views, not a new taxonomy or generic filter framework
|
|
|
|
- **Decision**: Represent `Unassigned` and `Needs triage` as fixed queue-view controls in the page shell, with `Needs triage` implemented as the strict subset of intake rows in `new` or `reopened` status.
|
|
- **Rationale**: The two views are product vocabulary, not a reusable classification framework. Page-local view state keeps the implementation explicit, honors the spec's fixed queue contract, and avoids adding new persisted preferences or a generic queue-view registry.
|
|
- **Alternatives considered**:
|
|
- Add a reusable taxonomy or enum for queue view types. Rejected because two concrete values do not justify new semantic machinery.
|
|
- Model the views as ordinary optional filters only. Rejected because the spec treats them as fixed queue modes, not ad hoc filter combinations.
|
|
|
|
## Decision 4: Reuse canonical admin tenant filter and navigation context helpers
|
|
|
|
- **Decision**: Use `CanonicalAdminTenantFilterState` to apply the active tenant as the default prefilter and `CanonicalNavigationContext` to carry `Back to findings intake` continuity into tenant finding detail.
|
|
- **Rationale**: The repo already uses these helpers for canonical admin-plane filters and cross-surface back links. Reusing them keeps intake aligned with the existing admin shell, keeps row and count disclosure tenant-safe, and avoids adding another page-specific context mechanism. If a workspace member has no currently viewable findings scope anywhere, the queue should fail with `403` instead of pretending the backlog is simply empty.
|
|
- **Alternatives considered**:
|
|
- Store active tenant and return-path state in a queue-local session structure. Rejected because the existing helpers already solve both problems and another state path would add drift.
|
|
- Depend on browser history for return links. Rejected because it is brittle across reloads, tabs, and copied URLs.
|
|
|
|
## Decision 5: Add `Claim finding` as a narrow row action that reuses assignment semantics, adds a lightweight preview/confirmation step, and adds a stale-row conflict guard
|
|
|
|
- **Decision**: Implement `Claim finding` as the single inline safe shortcut on the intake row, gated by `Capabilities::TENANT_FINDINGS_ASSIGN`, surfaced through a lightweight preview/confirmation modal, and routed through `FindingWorkflowService` plus the existing `finding.assigned` audit action while adding a claim-specific re-check that refuses rows whose assignee is no longer null under lock.
|
|
- **Rationale**: The current assignment service already owns audit logging, tenant ownership checks, and capability enforcement, but plain assign semantics would allow a stale queue click to overwrite a newer assignee and would not satisfy the repository write-flow governance. A lightweight preview/confirmation step plus a narrow guard inside the existing service seam solves both needs without inventing a second assignment system.
|
|
- **Alternatives considered**:
|
|
- Reuse the existing `Assign` form unchanged. Rejected because the intake surface needs a lighter self-claim preview/confirmation flow, not a broader owner/assignee form.
|
|
- Reuse `assign()` without an extra guard. Rejected because it could silently overwrite another operator's successful claim, violating FR-014.
|
|
|
|
## Decision 6: Keep post-claim continuity explicit through `My Findings` rather than auto-redirecting away from intake
|
|
|
|
- **Decision**: Refresh the queue after a successful claim so the row disappears immediately, then provide a clear next step into `/admin/findings/my-work` while leaving row-open detail continuity available when the operator needs deeper context first.
|
|
- **Rationale**: The queue is still the canonical shared backlog surface. Auto-redirecting every successful claim would interrupt batch intake review, while a clear `Open my findings` next step satisfies the spec without hiding the updated queue truth.
|
|
- **Alternatives considered**:
|
|
- Redirect to `My Findings` after every claim. Rejected because it would add navigation churn when multiple intake items are reviewed in sequence.
|
|
- Keep success feedback to a generic toast only. Rejected because the spec requires a clear next step into the existing personal execution destination.
|
|
|
|
## Decision 7: Prove the feature with three focused feature suites and rely on existing UI guard tests as ambient protection
|
|
|
|
- **Decision**: Add `FindingsIntakeQueueTest`, `FindingsIntakeAuthorizationTest`, and `FindingsClaimHandoffTest` as the focused proving suites while allowing existing action-surface and Filament-table guards to stay in their normal CI role.
|
|
- **Rationale**: The user-visible risk is queue truth, hidden-tenant isolation, claim authorization, stale-row conflict handling, and handoff continuity. Those are best proven with focused feature tests that exercise the real Livewire and Filament seams.
|
|
- **Alternatives considered**:
|
|
- Add browser coverage. Rejected because the surface is straightforward and already well served by existing feature-test patterns.
|
|
- Add a new heavy-governance suite for this page. Rejected because the change is still one bounded feature surface, not a new cross-cutting UI family. |