feat(service): P5.2 adapter tables (raw_event, outbound_command, delivery_attempt, rate_limit_bucket) + resetDb
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,72 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE "IiosInboundRawEvent" (
|
||||
"id" TEXT NOT NULL,
|
||||
"channelType" TEXT NOT NULL,
|
||||
"externalEventId" TEXT,
|
||||
"signatureStatus" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'RECEIVED',
|
||||
"headers" JSONB,
|
||||
"payload" JSONB NOT NULL,
|
||||
"traceId" TEXT,
|
||||
"interactionId" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "IiosInboundRawEvent_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "IiosOutboundCommand" (
|
||||
"id" TEXT NOT NULL,
|
||||
"channelType" TEXT NOT NULL,
|
||||
"target" TEXT NOT NULL,
|
||||
"payload" JSONB NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'PENDING',
|
||||
"idempotencyKey" TEXT NOT NULL,
|
||||
"providerRef" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "IiosOutboundCommand_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "IiosDeliveryAttempt" (
|
||||
"id" TEXT NOT NULL,
|
||||
"commandId" TEXT NOT NULL,
|
||||
"attemptNo" INTEGER NOT NULL,
|
||||
"status" TEXT NOT NULL,
|
||||
"providerRef" TEXT,
|
||||
"latencyMs" INTEGER,
|
||||
"errorCode" TEXT,
|
||||
"at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "IiosDeliveryAttempt_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "IiosRateLimitBucket" (
|
||||
"channelType" TEXT NOT NULL,
|
||||
"bucketKey" TEXT NOT NULL,
|
||||
"windowStart" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"count" INTEGER NOT NULL DEFAULT 0,
|
||||
"resetAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "IiosRateLimitBucket_pkey" PRIMARY KEY ("channelType","bucketKey")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "IiosInboundRawEvent_status_idx" ON "IiosInboundRawEvent"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "IiosInboundRawEvent_channelType_externalEventId_key" ON "IiosInboundRawEvent"("channelType", "externalEventId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "IiosOutboundCommand_idempotencyKey_key" ON "IiosOutboundCommand"("idempotencyKey");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "IiosOutboundCommand_channelType_status_idx" ON "IiosOutboundCommand"("channelType", "status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "IiosDeliveryAttempt_commandId_idx" ON "IiosDeliveryAttempt"("commandId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "IiosDeliveryAttempt" ADD CONSTRAINT "IiosDeliveryAttempt_commandId_fkey" FOREIGN KEY ("commandId") REFERENCES "IiosOutboundCommand"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
@@ -517,3 +517,63 @@ model IiosCallbackRequest {
|
||||
|
||||
@@index([scopeId, status])
|
||||
}
|
||||
|
||||
// ─── P5: Adapters (anti-corruption layer, simulation mode) ────────
|
||||
|
||||
/// Raw inbound provider payload (claim-check / replay). Verified before storing.
|
||||
model IiosInboundRawEvent {
|
||||
id String @id @default(cuid())
|
||||
channelType String
|
||||
externalEventId String?
|
||||
signatureStatus String // VERIFIED | INVALID | UNSIGNED
|
||||
status String @default("RECEIVED") // RECEIVED | NORMALIZED | REJECTED | FAILED
|
||||
headers Json?
|
||||
payload Json
|
||||
traceId String?
|
||||
interactionId String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@unique([channelType, externalEventId])
|
||||
@@index([status])
|
||||
}
|
||||
|
||||
/// A signed command to send on an external channel — executed by the sandbox sink.
|
||||
model IiosOutboundCommand {
|
||||
id String @id @default(cuid())
|
||||
channelType String
|
||||
target String
|
||||
payload Json
|
||||
status String @default("PENDING") // PENDING | SENT | FAILED | RATE_LIMITED
|
||||
idempotencyKey String @unique
|
||||
providerRef String?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
attempts IiosDeliveryAttempt[]
|
||||
|
||||
@@index([channelType, status])
|
||||
}
|
||||
|
||||
model IiosDeliveryAttempt {
|
||||
id String @id @default(cuid())
|
||||
commandId String
|
||||
command IiosOutboundCommand @relation(fields: [commandId], references: [id], onDelete: Cascade)
|
||||
attemptNo Int
|
||||
status String
|
||||
providerRef String?
|
||||
latencyMs Int?
|
||||
errorCode String?
|
||||
at DateTime @default(now())
|
||||
|
||||
@@index([commandId])
|
||||
}
|
||||
|
||||
/// Per-(channelType, key) token/window bucket for outbound throttling.
|
||||
model IiosRateLimitBucket {
|
||||
channelType String
|
||||
bucketKey String
|
||||
windowStart DateTime @default(now())
|
||||
count Int @default(0)
|
||||
resetAt DateTime
|
||||
|
||||
@@id([channelType, bucketKey])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user