# Notification Audit — Agile Health Alerts

Audit date: 2026-06-05

---

## 1. Project Health At Risk / Critical

| Attribute | Detail |
|-----------|--------|
| **Types** | `project_health_at_risk`, `project_health_critical` |
| **Trigger** | `ProjectHealthUpdated` event OR `AgileNotificationMonitorService::monitorCapacityAndHealth()` |
| **Condition** | `ProjectHealthService::shouldAlert()` → score not null, score < 60, factors non-empty, level ≠ initializing |
| **Does NOT trigger on** | Project create, project update, sprint create, initializing projects |
| **Recipients** | Project owner + members with role `owner` or `manager` |
| **Cooldown** | Daily dedupe: `project_health_alert:{project_id}:{YYYY-MM-DD}`; snapshot service dedupes same level transitions |
| **Data passed** | `project_name`, `project_id`, `health_score`, `health_level`, `contributing_factors` |
| **Example** | Benefits Platform score 39, factors: `critical_risk,blocked_dependency` → `project_health_critical` |

**Listener:** `NotifyOnHealthUpdated::handleProjectHealthUpdated()`

---

## 2. Sprint Health Alert

| Attribute | Detail |
|-----------|--------|
| **Types** | `sprint_health_at_risk`, `sprint_health_critical` |
| **Trigger** | `SprintHealthUpdated` event OR active sprint monitor |
| **Condition** | `SprintHealthEngineService` status `at_risk` or `critical` (score < 60 or < 40) |
| **Recipients** | Sprint project owner + owner/manager members |
| **Cooldown** | `sprint_health_at_risk:{sprint_id}` / `sprint_health_critical:{sprint_id}` via `ProjectDueEvent` |
| **Data passed** | `project_name`, `project_id`, `sprint_name`, `sprint_id`, `health_score` |
| **Example** | Active sprint 35% complete, 3 blocked items → `sprint_health_at_risk` |

**Listener:** `NotifyOnHealthUpdated::handleSprintHealthUpdated()`

---

## 3. Milestone Delay (Overdue / Due Soon)

| Attribute | Detail |
|-----------|--------|
| **Types** | `project_milestone_due`, `project_milestone_overdue` |
| **Trigger** | `AgileNotificationMonitorService::monitorMilestones()` (scheduled) |
| **Due soon condition** | `due_date === tomorrow` |
| **Overdue condition** | `due_date < today` and not completed |
| **Recipients** | Project owner + owner/manager members |
| **Cooldown** | `milestone_due_tomorrow:{id}` / `milestone_overdue:{id}` |
| **Data passed** | `project_name`, `project_id`, `milestone_name`, `milestone_id` |
| **Example** | "Enrollment Go-Live" 5 days past due → `project_milestone_overdue` |

---

## 4. Risk Escalation

| Attribute | Detail |
|-----------|--------|
| **Type** | `project_risk_critical` |
| **Trigger** | Risk creation/update handlers (when risk becomes critical) |
| **Condition** | `probability × impact ≥ 20` and status open |
| **Recipients** | Project managers / risk owner |
| **Cooldown** | Per risk entity event dedupe |
| **Data passed** | `risk_title`, `risk_id`, `project_id` |
| **Gap** | No dedicated "Risk Escalation" type — uses `PROJECT_RISK_CRITICAL` template |

---

## 5. Dependency Blocked

| Attribute | Detail |
|-----------|--------|
| **Dedicated type** | **None** — no `dependency_blocked` notification enum |
| **Indirect exposure** | Project health `blocked_dependency` factor → health alert; executive dashboard blocked work list |
| **Recommendation** | Future: add `DEPENDENCY_BLOCKED` type when dependency created on in-progress target |

---

## 6. Related notifications (capacity / workload)

| Type | Trigger |
|------|---------|
| `sprint_capacity_exceeded` | Active sprint estimates > capacity |
| `workload_overloaded` | Team member overload detected |

---

## Fix summary (this release)

1. `NotifyOnHealthUpdated` — respects `shouldAlert()`, skips `initializing`, passes template variables  
2. `AgileNotificationMonitorService` — fixed sprint types (was wrongly using `PROJECT_HEALTH_CRITICAL`), passes `sprint_name`, `milestone_name`, `project_name`, `health_score`  
3. `NotificationTemplate::render()` — throws on unresolved `{{placeholders}}`, logs error, prevents broken emails

---

## Test coverage

- `tests/Feature/Notifications/NotificationTemplateRenderTest.php` — placeholder validation
