feat(p9): IiosDlqItem + DlqService (dead-letter + deterministic replay)

Task D.1: mandated dlq_item table (sourceType/sourceId/failureStage/errorCode/
retryCount/payloadRef/consumerName/scopeId/status). DlqService.record (idempotent
per consumer+sourceId, bumps retryCount), onConsumerFailure (quarantine + clear the
IiosProcessedEvent claim so it's replayable — fixes claim-then-fail), registerHandler
+ replay (clears claim, awaits the registered consumer handler → RESOLVED on success,
QUARANTINED+retry on repeat throw; outbox-sourced items reset to PENDING). Wired into
OutboxModule; resetDb truncates it. 3 tests.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-03 01:28:48 +05:30
parent e5d3ce5ecd
commit 208fb0b4f0
6 changed files with 219 additions and 3 deletions
@@ -1,9 +1,10 @@
import { Module } from '@nestjs/common';
import { OutboxBus } from './outbox.bus';
import { OutboxRelay } from './outbox.relay';
import { DlqService } from './dlq.service';
@Module({
providers: [OutboxBus, OutboxRelay],
exports: [OutboxBus, OutboxRelay],
providers: [OutboxBus, OutboxRelay, DlqService],
exports: [OutboxBus, OutboxRelay, DlqService],
})
export class OutboxModule {}