Repository navigation
Description
Problem context
src/notifications/services/outbox-scheduler.service.ts collects successful job IDs separately, then updates pendingEvents.slice(0, jobIds.length) and assigns jobIds[0] to every selected event. If an earlier enqueue fails, event-to-job mapping can be wrong; all events can also receive the same job ID.
Technical scope
Maintain an explicit eventId-to-jobId result for each successful enqueue and update only the exact matching outbox rows. Preserve at-least-once delivery, idempotent job IDs, retry safety, and correct state transitions when queue insertion or database update partially fails. Reconcile orphaned jobs and pending rows without silently losing an event.
Required tests
- First/middle/last enqueue failure permutations.
- Multiple successful jobs persist distinct IDs on their matching events.
- Crash between enqueue and database update; replay and duplicate prevention.
- Concurrent scheduler runs and partial database update.
- No event is marked dispatched unless its own queue job was confirmed.
Security and architecture constraints
- Contracts and finalized canonical events remain authoritative for protocol state.
- The API remains a projection/read and notification-delivery layer; it must not invent protocol outcomes.
- Fail closed on missing, stale, ambiguous, unauthorized, or incomplete state.
- Do not expose secrets, device tokens, email verification tokens, private evidence, or unnecessary personal data.
- Preserve strict typing, idempotency, privacy, observability redaction, and existing CI/security gates.
Acceptance criteria
- The identified placeholder or unsafe behavior is replaced by a production-quality implementation.
- Provider/recipient/ownership behavior is explicit and documented.
- Every required failure mode is covered by automated tests.
- No synthetic success, cross-user data exposure, or secret leakage remains in the affected path.
- The pull request links exactly this issue and maps evidence to every acceptance criterion.
- Exact-head required CI passes and independent human review is recorded.
Dependencies
- API PREWAVE-BE-019 — Restore the Canonical Notification Outbox Entity Contract #615 — canonical notification outbox entity contract.
- API PREWAVE-BE-018 — Converge Duplicate Notification Module Implementations #613 — canonical notification module wiring.
Non-goals
Replacing BullMQ or redesigning the notification outbox schema.
Complexity and points
- High — 200 points
Candidate only. Activation remains maintainer-controlled; do not apply Stellar Wave as part of implementation.
Activity