-- RFC-004 Phase 0 (GOO-172): transactional outbox for async messaging backbone. -- Producers insert into event_outbox in the same tx as the domain change. -- A single relay process (Postgres advisory-lock leader) tails pending rows -- and publishes them to Redis Streams, then flips published_at. CREATE TABLE "event_outbox" ( "id" TEXT NOT NULL, "eventId" TEXT NOT NULL, "eventType" TEXT NOT NULL, "aggregateId" TEXT, "envelope" JSONB NOT NULL, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, "publishedAt" TIMESTAMP(3), "attempts" INTEGER NOT NULL DEFAULT 0, "lastError" TEXT, CONSTRAINT "event_outbox_pkey" PRIMARY KEY ("id") ); CREATE UNIQUE INDEX "event_outbox_eventId_key" ON "event_outbox"("eventId"); -- Hot path: relay scans `WHERE publishedAt IS NULL ORDER BY createdAt`. CREATE INDEX "event_outbox_publishedAt_createdAt_idx" ON "event_outbox"("publishedAt", "createdAt"); -- Diagnostics: per-type backlog inspection. CREATE INDEX "event_outbox_eventType_createdAt_idx" ON "event_outbox"("eventType", "createdAt");