feat(iios): wire projectors + relay into DLQ (P9 chaos-safe)

Projectors register a replay handler and route bus errors to
dlq.onConsumerFailure (dead-letter + clear the claim-then-fail claim)
instead of swallowing them. Relay dead-letters an outbox event after
IIOS_OUTBOX_MAX_ATTEMPTS instead of retrying forever. Chaos test proves
poison → DLQ → replay resolves while sibling events keep flowing (KG-13/KG-06).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-03 01:43:57 +05:30
parent 208fb0b4f0
commit d3d557766e
14 changed files with 128 additions and 18 deletions
@@ -1,5 +1,6 @@
import { describe, it, expect, beforeAll, afterAll, beforeEach } from 'vitest';
import { PrismaClient } from '@prisma/client';
import { DlqService } from '../outbox/dlq.service';
import { resetDb } from '../test-utils/reset-db';
import { makeFakePorts, portalMessageBasic, replayTwice, isIdempotent } from '@insignia/iios-testkit';
import { IngestService } from '../interactions/ingest.service';
@@ -36,7 +37,7 @@ describe('outbox relay + replay', () => {
const bus = new OutboxBus();
const received: string[] = [];
bus.onAny((eventType) => received.push(eventType));
const relay = new OutboxRelay(asService, bus);
const relay = new OutboxRelay(asService, bus, new DlqService(asService));
await ingest.ingest(portalMessageBasic, portalMessageBasic.providerEventId!);