Implements spec 111 (Findings workflow + SLA) and fixes Workspace findings SLA settings UX/validation. Key changes: - Findings workflow service + SLA policy and alerting. - Workspace settings: allow partial SLA overrides without auto-filling unset severities in the UI; effective values still resolve via defaults. - New migrations, jobs, command, UI/resource updates, and comprehensive test coverage. Tests: - `vendor/bin/sail artisan test --compact` (1779 passed, 8 skipped). Co-authored-by: Ahmed Darrazi <ahmed.darrazi@live.de> Reviewed-on: #135
111 lines
3.9 KiB
Markdown
111 lines
3.9 KiB
Markdown
# Quickstart: 111 — Findings Workflow V2 + SLA
|
|
|
|
**Date**: 2026-02-24
|
|
**Branch**: `111-findings-workflow-sla`
|
|
|
|
---
|
|
|
|
## Prerequisites
|
|
|
|
- Sail services running (`vendor/bin/sail up -d`)
|
|
- Database migrated to latest
|
|
- At least one workspace with at least one tenant
|
|
- Queue worker running for queued jobs (e.g., `vendor/bin/sail artisan queue:work`)
|
|
|
|
---
|
|
|
|
## Implementation Phases
|
|
|
|
### Phase 1: Data Layer (Findings v2 Columns + Badges + Settings)
|
|
|
|
**Goal:** Extend `findings` to v2 lifecycle fields and add SLA policy setting.
|
|
|
|
1. Migrations (add v2 columns + indexes; two-phase if enforcing NOT NULL after backfill)
|
|
2. Update `App\Models\Finding` constants for v2 statuses and severities
|
|
3. BADGE-001: extend Finding status badge mapping to include v2 statuses (and legacy `acknowledged` mapping)
|
|
4. Settings:
|
|
- Add `findings.sla_days` to `SettingsRegistry`
|
|
- Expose in Workspace Settings UI (JSON textarea), validate via registry rules
|
|
|
|
**Run:** `vendor/bin/sail artisan migrate && vendor/bin/sail artisan test --compact --filter=SettingsRegistry`
|
|
|
|
---
|
|
|
|
### Phase 2: Workflow + RBAC (Server-Side Enforcement + Filament Actions)
|
|
|
|
**Goal:** Enforce transition rules, write timestamps, and provide safe UI actions.
|
|
|
|
1. Capabilities:
|
|
- Add new `TENANT_FINDINGS_*` constants
|
|
- Keep `TENANT_FINDINGS_ACKNOWLEDGE` as triage alias (migration window)
|
|
- Update `RoleCapabilityMap`
|
|
2. Policy/service layer:
|
|
- Enforce allowed transitions server-side
|
|
- Require reasons for resolve/close/risk accept
|
|
- Audit log every mutation (before/after + reason fields)
|
|
3. Filament `FindingResource`:
|
|
- Remove drift-only default filters
|
|
- Default to Open statuses across all finding types
|
|
- Add quick filters (Open/Overdue/High severity/My assigned)
|
|
- Add row actions + bulk actions per spec (grouped under “More”)
|
|
|
|
**Run:** `vendor/bin/sail artisan test --compact --filter=FindingWorkflow`
|
|
|
|
---
|
|
|
|
### Phase 3: Generators (Lifecycle Fields + Drift Recurrence + Stale Resolve)
|
|
|
|
**Goal:** Ensure findings lifecycle fields and recurrence behavior are maintained automatically.
|
|
|
|
1. Drift:
|
|
- Compute `recurrence_key` and upsert by it
|
|
- Auto-reopen only from `resolved` into `reopened`
|
|
- Auto-resolve stale drift for a scope when no longer detected (`resolved_reason=no_longer_detected`)
|
|
2. Permission posture + Entra roles:
|
|
- Preserve existing reopen/auto-resolve behavior
|
|
- Add lifecycle fields: first/last seen, times_seen, due_at/sla_days
|
|
|
|
**Run:** `vendor/bin/sail artisan test --compact --filter=FindingRecurrence`
|
|
|
|
---
|
|
|
|
### Phase 4: Alerts (SLA Due Producer + UI Re-Enable)
|
|
|
|
**Goal:** Make `sla_due` alert rules functional.
|
|
|
|
1. Add SLA due producer to `EvaluateAlertsJob` that emits one tenant-level event summarizing overdue counts.
|
|
2. Re-enable `sla_due` in AlertRuleResource event type options (only after producer exists).
|
|
|
|
**Manual verification:**
|
|
1. Create (or backfill) a finding with `due_at` in the past and open status.
|
|
2. Run `vendor/bin/sail artisan tenantpilot:alerts:dispatch --workspace={id}`
|
|
3. Confirm an `alert_deliveries` row is created for matching enabled rules.
|
|
|
|
**Run:** `vendor/bin/sail artisan test --compact --filter=FindingSlaDue`
|
|
|
|
---
|
|
|
|
### Phase 5: Backfill/Consolidation (OperationRun-Backed)
|
|
|
|
**Goal:** Upgrade legacy findings and consolidate drift duplicates.
|
|
|
|
1. Trigger backfill from tenant context (Filament action and/or an artisan command entrypoint).
|
|
2. Verify OPS-UX:
|
|
- queued toast intent-only
|
|
- progress visible in active ops widget + OperationRun detail
|
|
- exactly one terminal completion notification (initiator-only)
|
|
3. Verify data outcomes:
|
|
- `acknowledged → triaged`
|
|
- lifecycle fields populated
|
|
- due dates set from backfill time + SLA days for legacy open findings
|
|
- drift duplicates consolidated (one canonical open row per recurrence identity)
|
|
|
|
**Run:** `vendor/bin/sail artisan test --compact --filter=FindingBackfill`
|
|
|
|
---
|
|
|
|
## Formatting / Hygiene
|
|
|
|
- Run `vendor/bin/sail bin pint --dirty` before finalizing.
|
|
|