TenantAtlas/specs/111-findings-workflow-sla/quickstart.md
ahmido 7ac53f4cc4 feat(111): findings workflow + SLA settings (#135)
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
2026-02-25 01:48:01 +00:00

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.