Phase 2: scope cross-program alerts by household_assignments (full #590 fix)
Context
Follow-up filed alongside the #590 (closed) identity-gate fix. #590 (closed)'s MR closes the worst-of-both-worlds 'decorative worker_id param' state — a caseworker can no longer pass another caseworker's ID and get back the unscoped alert list. That fix is identity-only: it proves the caller is who they say they are, but it does NOT yet filter the result set down to the caseworker's actual assigned cases.
What this issue covers
The audit's preferred resolution (#590 (closed) Option 1) requires:
- Joining
canopy-applications.household_assignmentsagainstprogram_determinationsto filter the returned alert rows to just the caseworker's owned households. - Cross-service call from canopy-eligibility into canopy-applications (or a denormalized read-model of household_assignments) — neither exists today.
Acceptance criteria
- Caseworker tokens calling
GET /v1/eligibility/cross-program-alerts?worker_id=<self>return ONLY alerts for households assigned to that caseworker. - Supervisor / admin tokens continue to receive the unscoped jurisdiction view (this is intentional triage tooling — see #590 (closed) doc).
- Service callers continue to receive the unscoped view.
- Existing #590 (closed) unit + integration tests stay green.
- New integration test: seed one assignment for caseworker A, one for caseworker B, assert each sees only their own.
Out of scope
- The supervisor 'scope down to one worker's view for triage' affordance is already enabled by #590 (closed) (supervisor passes any
worker_idand the identity gate does not fire); narrowing the result set when supervisor passesworker_idbelongs to this issue too. - household_assignments table design + ownership lives with canopy-applications; this issue depends on whatever shape lands there.
Labels
service::eligibility, type::feature, priority::medium, workflow::needs-spec, compliance::pub-1075, program::cross-program