This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
CREATE TABLE "ReportReadinessState" (
|
||||
"objectKey" TEXT PRIMARY KEY, "mask" INTEGER NOT NULL, "armed" BOOLEAN NOT NULL,
|
||||
"cycle" INTEGER NOT NULL DEFAULT 0, "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC')
|
||||
);
|
||||
CREATE TABLE "ReportNotificationHour" (
|
||||
"id" TEXT PRIMARY KEY, "tenantId" TEXT NOT NULL, "tenantName" TEXT NOT NULL,
|
||||
"hour" TIMESTAMP(3) NOT NULL, "revision" INTEGER NOT NULL DEFAULT 1,
|
||||
"signatureCount" INTEGER NOT NULL DEFAULT 0, "drainageCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC'),
|
||||
UNIQUE ("tenantId", "hour")
|
||||
);
|
||||
CREATE INDEX "ReportNotificationHour_hour_idx" ON "ReportNotificationHour" ("hour" DESC);
|
||||
CREATE TABLE "ReportReadinessEvent" (
|
||||
"id" TEXT PRIMARY KEY, "hourId" TEXT NOT NULL REFERENCES "ReportNotificationHour"("id"),
|
||||
"objectKey" TEXT NOT NULL, "cycle" INTEGER NOT NULL, "tenantId" TEXT NOT NULL,
|
||||
"reportType" TEXT NOT NULL, "signatureId" TEXT NOT NULL, "drainageItemId" TEXT,
|
||||
"applicationId" TEXT, "applicationName" TEXT, "signatureName" TEXT NOT NULL,
|
||||
"targetName" TEXT NOT NULL, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC'),
|
||||
UNIQUE ("objectKey", "cycle")
|
||||
);
|
||||
CREATE INDEX "ReportReadinessEvent_hour_idx" ON "ReportReadinessEvent" ("hourId", "createdAt", "id");
|
||||
CREATE TABLE "ReportNotificationRead" (
|
||||
"userId" TEXT NOT NULL, "hourId" TEXT NOT NULL REFERENCES "ReportNotificationHour"("id"),
|
||||
"revision" INTEGER NOT NULL, PRIMARY KEY ("userId", "hourId")
|
||||
);
|
||||
|
||||
CREATE FUNCTION cmpp_report_ready_mask(kind TEXT, signature_id TEXT, drainage_id TEXT) RETURNS INTEGER
|
||||
LANGUAGE sql STABLE AS $$
|
||||
SELECT COALESCE(sum(bit),0)::integer FROM (VALUES ('mobile',1),('unicom',2),('telecom',4)) AS carriers(name,bit)
|
||||
WHERE EXISTS (
|
||||
SELECT 1 FROM "SmsChannel" c
|
||||
WHERE c.status='active' AND c."sendRegion"='全国'
|
||||
AND (CASE WHEN cardinality(c.carriers)>0 THEN carriers.name=ANY(c.carriers)
|
||||
ELSE c.carrier IN (carriers.name,'all') END)
|
||||
AND (SELECT t.status FROM "ChannelSignatureReportTask" t
|
||||
WHERE t."channelId"=c.id AND t."signatureId"=signature_id AND t."reportType"=kind
|
||||
AND (kind='signature' OR t."drainageItemId"=drainage_id)
|
||||
AND (t.carrier=carriers.name OR (t.carrier IS NULL AND t."approvalScope"='legacy_channel'))
|
||||
ORDER BY (t.carrier=carriers.name) DESC NULLS LAST, t."updatedAt" DESC, t.id DESC LIMIT 1)='approved'
|
||||
);
|
||||
$$;
|
||||
|
||||
-- Seed only state. Existing successes must never become historical unread notices.
|
||||
INSERT INTO "ReportReadinessState" ("objectKey",mask,armed)
|
||||
SELECT 'signature:'||id, mask, mask=0 FROM "SmsSignature" s
|
||||
CROSS JOIN LATERAL (SELECT cmpp_report_ready_mask('signature',s.id,NULL) AS mask) m;
|
||||
INSERT INTO "ReportReadinessState" ("objectKey",mask,armed)
|
||||
SELECT 'drainage:'||id, mask, mask=0 FROM "SmsDrainageInfo" d
|
||||
CROSS JOIN LATERAL (SELECT cmpp_report_ready_mask('drainage',d."signatureId",d.id) AS mask) m;
|
||||
|
||||
CREATE FUNCTION cmpp_report_readiness_before() RETURNS trigger LANGUAGE plpgsql AS $$
|
||||
DECLARE r "ChannelSignatureReportTask"; k TEXT; m INTEGER;
|
||||
BEGIN
|
||||
r := CASE WHEN TG_OP='DELETE' THEN OLD ELSE NEW END;
|
||||
IF TG_OP='UPDATE' AND (OLD."signatureId",OLD."drainageItemId",OLD."reportType") IS DISTINCT FROM
|
||||
(NEW."signatureId",NEW."drainageItemId",NEW."reportType") THEN
|
||||
RAISE EXCEPTION 'Reporting task identity is immutable';
|
||||
END IF;
|
||||
k := r."reportType"||':'||CASE WHEN r."reportType"='drainage' THEN r."drainageItemId" ELSE r."signatureId" END;
|
||||
IF k IS NULL THEN RETURN r; END IF;
|
||||
PERFORM pg_advisory_xact_lock(hashtextextended(k, 20260906));
|
||||
m := cmpp_report_ready_mask(r."reportType",r."signatureId",r."drainageItemId");
|
||||
INSERT INTO "ReportReadinessState" ("objectKey",mask,armed) VALUES(k,m,m=0) ON CONFLICT DO NOTHING;
|
||||
-- A configuration change can remove eligibility without changing a reporting task.
|
||||
UPDATE "ReportReadinessState" SET mask=m, armed=armed OR m=0 WHERE "objectKey"=k;
|
||||
RETURN r;
|
||||
END;
|
||||
$$;
|
||||
CREATE FUNCTION cmpp_report_readiness_after() RETURNS trigger LANGUAGE plpgsql AS $$
|
||||
DECLARE r "ChannelSignatureReportTask"; k TEXT; m INTEGER; st "ReportReadinessState";
|
||||
sig "SmsSignature"; tenant_name TEXT; app_name TEXT; target_name TEXT;
|
||||
app_id TEXT; hour_value TIMESTAMP(3); hour_id TEXT; next_cycle INTEGER;
|
||||
BEGIN
|
||||
r := CASE WHEN TG_OP='DELETE' THEN OLD ELSE NEW END;
|
||||
k := r."reportType"||':'||CASE WHEN r."reportType"='drainage' THEN r."drainageItemId" ELSE r."signatureId" END;
|
||||
IF k IS NULL THEN RETURN r; END IF;
|
||||
SELECT * INTO st FROM "ReportReadinessState" WHERE "objectKey"=k FOR UPDATE;
|
||||
m := cmpp_report_ready_mask(r."reportType",r."signatureId",r."drainageItemId");
|
||||
IF m=7 AND st.armed THEN
|
||||
SELECT * INTO sig FROM "SmsSignature" WHERE id=r."signatureId";
|
||||
IF sig.id IS NOT NULL THEN
|
||||
SELECT name INTO tenant_name FROM "Tenant" WHERE id=sig."tenantId";
|
||||
app_id:=sig."applicationId"; target_name:=sig.name;
|
||||
IF r."reportType"='drainage' THEN
|
||||
SELECT COALESCE(d."applicationId",sig."applicationId"), d.url INTO app_id,target_name
|
||||
FROM "SmsDrainageInfo" d WHERE id=r."drainageItemId";
|
||||
END IF;
|
||||
SELECT name INTO app_name FROM "SmsApplication" WHERE id=app_id;
|
||||
hour_value:=date_trunc('hour',timezone('UTC',statement_timestamp()));
|
||||
hour_id:=md5(sig."tenantId"||':'||hour_value::text);
|
||||
next_cycle:=st.cycle+1;
|
||||
INSERT INTO "ReportNotificationHour" (id,"tenantId","tenantName",hour,"signatureCount","drainageCount")
|
||||
VALUES(hour_id,sig."tenantId",tenant_name,hour_value,(r."reportType"='signature')::integer,(r."reportType"='drainage')::integer)
|
||||
ON CONFLICT ("tenantId",hour) DO UPDATE SET revision="ReportNotificationHour".revision+1,
|
||||
"signatureCount"="ReportNotificationHour"."signatureCount"+EXCLUDED."signatureCount",
|
||||
"drainageCount"="ReportNotificationHour"."drainageCount"+EXCLUDED."drainageCount",
|
||||
"updatedAt"=timezone('UTC',statement_timestamp()) RETURNING id INTO hour_id;
|
||||
INSERT INTO "ReportReadinessEvent" (id,"hourId","objectKey",cycle,"tenantId","reportType","signatureId","drainageItemId","applicationId","applicationName","signatureName","targetName")
|
||||
VALUES(md5(k||':'||next_cycle),hour_id,k,next_cycle,sig."tenantId",r."reportType",sig.id,r."drainageItemId",app_id,app_name,sig.name,target_name);
|
||||
UPDATE "ReportReadinessState" SET cycle=next_cycle,armed=false WHERE "objectKey"=k;
|
||||
END IF;
|
||||
END IF;
|
||||
UPDATE "ReportReadinessState" SET mask=m,armed=armed OR m=0,"updatedAt"=timezone('UTC',statement_timestamp()) WHERE "objectKey"=k;
|
||||
RETURN r;
|
||||
END;
|
||||
$$;
|
||||
CREATE TRIGGER report_readiness_before BEFORE INSERT OR UPDATE OR DELETE ON "ChannelSignatureReportTask"
|
||||
FOR EACH ROW EXECUTE FUNCTION cmpp_report_readiness_before();
|
||||
CREATE TRIGGER report_readiness_after AFTER INSERT OR UPDATE OR DELETE ON "ChannelSignatureReportTask"
|
||||
FOR EACH ROW EXECUTE FUNCTION cmpp_report_readiness_after();
|
||||
@@ -0,0 +1,73 @@
|
||||
ALTER TABLE "SmsSubmitRecord" ADD COLUMN "firstWireSubmitAt" TIMESTAMP(3), ADD COLUMN "wireTimeSource" TEXT;
|
||||
ALTER TABLE "SmsMessageSegmentAudit" ADD COLUMN "firstWireSubmitAt" TIMESTAMP(3), ADD COLUMN "wireTimeSource" TEXT;
|
||||
ALTER TABLE "UpstreamReceiptInbox" ADD COLUMN "gatewayReceivedAt" TIMESTAMP(3);
|
||||
ALTER TABLE "SmsSubmitRecord" ADD COLUMN "receiptRequested" BOOLEAN;
|
||||
ALTER TABLE "SmsMessageSegmentAudit" ADD COLUMN "receiptRequested" BOOLEAN;
|
||||
CREATE INDEX "SmsSubmitRecord_monitor_updated_idx" ON "SmsSubmitRecord" ("updatedAt",id);
|
||||
CREATE INDEX "SmsSubmitRecord_monitor_created_idx" ON "SmsSubmitRecord" ("createdAt",id);
|
||||
CREATE INDEX "UpstreamReceiptInbox_monitor_updated_idx" ON "UpstreamReceiptInbox" ("updatedAt",id);
|
||||
CREATE INDEX "UpstreamReceiptInbox_monitor_message_idx" ON "UpstreamReceiptInbox" ("matchedMessageRecordId","gatewayMessageId");
|
||||
|
||||
CREATE TABLE "SendingMonitorTarget" (
|
||||
"channelId" TEXT PRIMARY KEY, enabled BOOLEAN NOT NULL, version INTEGER NOT NULL,
|
||||
"effectiveFrom" TIMESTAMP(3) NOT NULL, "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC'),
|
||||
"updatedBy" TEXT NOT NULL
|
||||
);
|
||||
CREATE TABLE "SendingMonitorTargetVersion" (
|
||||
"channelId" TEXT NOT NULL, version INTEGER NOT NULL, enabled BOOLEAN NOT NULL,
|
||||
"effectiveFrom" TIMESTAMP(3) NOT NULL, "updatedBy" TEXT NOT NULL,
|
||||
PRIMARY KEY("channelId",version)
|
||||
);
|
||||
CREATE TABLE "SendingMonitorRule" (
|
||||
id TEXT PRIMARY KEY, type TEXT NOT NULL, "scopeKey" TEXT NOT NULL, scope JSONB NOT NULL,
|
||||
config JSONB NOT NULL, version INTEGER NOT NULL, "effectiveAt" TIMESTAMP(3) NOT NULL,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC'), "updatedBy" TEXT NOT NULL,
|
||||
UNIQUE(type,"scopeKey")
|
||||
);
|
||||
CREATE TABLE "SendingMonitorRuleVersion" (
|
||||
"ruleId" TEXT NOT NULL, version INTEGER NOT NULL, type TEXT NOT NULL, scope JSONB NOT NULL,
|
||||
config JSONB NOT NULL, "effectiveAt" TIMESTAMP(3) NOT NULL, "createdAt" TIMESTAMP(3) NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC'),
|
||||
"createdBy" TEXT NOT NULL, PRIMARY KEY("ruleId",version)
|
||||
);
|
||||
CREATE INDEX "SendingMonitorRuleVersion_effective_idx" ON "SendingMonitorRuleVersion" (type,"effectiveAt");
|
||||
CREATE TABLE "SendingMonitorFact" (
|
||||
id TEXT PRIMARY KEY, kind TEXT NOT NULL, "sourceId" TEXT NOT NULL, "dimensionKey" TEXT NOT NULL,
|
||||
"messageRecordId" TEXT REFERENCES "SmsMessageRecord"(id) ON DELETE SET NULL ON UPDATE CASCADE,
|
||||
dimensions JSONB NOT NULL, "submittedAt" TIMESTAMP(3) NOT NULL, "successAt" TIMESTAMP(3),
|
||||
verification BOOLEAN NOT NULL, reason TEXT, "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC'),
|
||||
UNIQUE(kind,"sourceId")
|
||||
);
|
||||
CREATE INDEX "SendingMonitorFact_window_idx" ON "SendingMonitorFact" (kind,"submittedAt","dimensionKey");
|
||||
CREATE INDEX "SendingMonitorFact_message_idx" ON "SendingMonitorFact" ("messageRecordId");
|
||||
CREATE TABLE "SendingMonitorMinute" (
|
||||
kind TEXT NOT NULL, "dimensionKey" TEXT NOT NULL, minute TIMESTAMP(3) NOT NULL,
|
||||
verification BOOLEAN NOT NULL, dimensions JSONB NOT NULL, metrics JSONB NOT NULL,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC'),
|
||||
PRIMARY KEY(kind,"dimensionKey",minute,verification)
|
||||
);
|
||||
CREATE INDEX "SendingMonitorMinute_window_idx" ON "SendingMonitorMinute" (kind,minute);
|
||||
CREATE TABLE "SendingMonitorSnapshot" (
|
||||
id TEXT PRIMARY KEY, type TEXT NOT NULL, "dimensionKey" TEXT NOT NULL, dimensions JSONB NOT NULL,
|
||||
"evaluationAt" TIMESTAMP(3) NOT NULL, "windowFrom" TIMESTAMP(3) NOT NULL,
|
||||
"observedUntil" TIMESTAMP(3) NOT NULL, stage TEXT NOT NULL, revision INTEGER NOT NULL DEFAULT 1,
|
||||
metrics JSONB NOT NULL, rule JSONB, status TEXT NOT NULL, completeness JSONB NOT NULL,
|
||||
"computedAt" TIMESTAMP(3) NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC'),
|
||||
UNIQUE(type,"dimensionKey","evaluationAt")
|
||||
);
|
||||
CREATE INDEX "SendingMonitorSnapshot_latest_idx" ON "SendingMonitorSnapshot" (type,"evaluationAt" DESC,status);
|
||||
CREATE INDEX "SendingMonitorSnapshot_history_idx" ON "SendingMonitorSnapshot" (type,"dimensionKey","evaluationAt");
|
||||
CREATE TABLE "SendingMonitorAlert" (
|
||||
id TEXT PRIMARY KEY, type TEXT NOT NULL, "dimensionKey" TEXT NOT NULL, dimensions JSONB NOT NULL,
|
||||
state TEXT NOT NULL, "openedAt" TIMESTAMP(3) NOT NULL, "lastEvaluatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"closedAt" TIMESTAMP(3), "closeReason" TEXT, "ruleKey" TEXT NOT NULL,
|
||||
latest JSONB NOT NULL, worst JSONB NOT NULL, "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC')
|
||||
);
|
||||
CREATE UNIQUE INDEX "SendingMonitorAlert_one_active_idx" ON "SendingMonitorAlert" (type,"dimensionKey") WHERE state='active';
|
||||
CREATE INDEX "SendingMonitorAlert_state_idx" ON "SendingMonitorAlert" (state,"openedAt" DESC);
|
||||
CREATE TABLE "SendingMonitorAlertRead" (
|
||||
"alertId" TEXT NOT NULL, "userId" TEXT NOT NULL, "readAt" TIMESTAMP(3) NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC'),
|
||||
PRIMARY KEY("alertId","userId")
|
||||
);
|
||||
CREATE TABLE "SendingMonitorCheckpoint" (
|
||||
id TEXT PRIMARY KEY, data JSONB NOT NULL, "updatedAt" TIMESTAMP(3) NOT NULL DEFAULT (CURRENT_TIMESTAMP AT TIME ZONE 'UTC')
|
||||
);
|
||||
@@ -696,6 +696,56 @@ model HttpWebhookAttempt {
|
||||
@@unique([deliveryId, attemptNo])
|
||||
}
|
||||
|
||||
model ReportReadinessState {
|
||||
objectKey String @id
|
||||
mask Int
|
||||
armed Boolean
|
||||
cycle Int @default(0)
|
||||
updatedAt DateTime @default(dbgenerated("(CURRENT_TIMESTAMP AT TIME ZONE 'UTC')"))
|
||||
}
|
||||
|
||||
model ReportNotificationHour {
|
||||
id String @id
|
||||
tenantId String
|
||||
tenantName String
|
||||
hour DateTime
|
||||
revision Int @default(1)
|
||||
signatureCount Int @default(0)
|
||||
drainageCount Int @default(0)
|
||||
updatedAt DateTime @default(dbgenerated("(CURRENT_TIMESTAMP AT TIME ZONE 'UTC')"))
|
||||
events ReportReadinessEvent[]
|
||||
reads ReportNotificationRead[]
|
||||
@@unique([tenantId, hour])
|
||||
@@index([hour(sort: Desc)], map: "ReportNotificationHour_hour_idx")
|
||||
}
|
||||
|
||||
model ReportReadinessEvent {
|
||||
id String @id
|
||||
hourId String
|
||||
objectKey String
|
||||
cycle Int
|
||||
tenantId String
|
||||
reportType String
|
||||
signatureId String
|
||||
drainageItemId String?
|
||||
applicationId String?
|
||||
applicationName String?
|
||||
signatureName String
|
||||
targetName String
|
||||
createdAt DateTime @default(dbgenerated("(CURRENT_TIMESTAMP AT TIME ZONE 'UTC')"))
|
||||
hour ReportNotificationHour @relation(fields: [hourId], references: [id], onDelete: NoAction, onUpdate: NoAction)
|
||||
@@unique([objectKey, cycle])
|
||||
@@index([hourId, createdAt, id], map: "ReportReadinessEvent_hour_idx")
|
||||
}
|
||||
|
||||
model ReportNotificationRead {
|
||||
userId String
|
||||
hourId String
|
||||
revision Int
|
||||
hour ReportNotificationHour @relation(fields: [hourId], references: [id], onDelete: NoAction, onUpdate: NoAction)
|
||||
@@id([userId, hourId])
|
||||
}
|
||||
|
||||
model SmsSignature {
|
||||
id String @id @default(cuid())
|
||||
tenantId String
|
||||
@@ -1705,6 +1755,7 @@ model SmsApiRequest {
|
||||
}
|
||||
|
||||
model SmsMessageRecord {
|
||||
monitorFacts SendingMonitorFact[]
|
||||
id String @id @default(cuid())
|
||||
tenantId String?
|
||||
batchTaskId String?
|
||||
@@ -1813,6 +1864,9 @@ model SmsSubmitRecord {
|
||||
errorCode String?
|
||||
errorMessage String?
|
||||
submittedAt DateTime?
|
||||
firstWireSubmitAt DateTime?
|
||||
wireTimeSource String?
|
||||
receiptRequested Boolean?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@ -1832,6 +1886,8 @@ model SmsSubmitRecord {
|
||||
@@index([gatewayMessageId])
|
||||
@@index([channelId, gatewayMessageId])
|
||||
@@index([channelGroupId])
|
||||
@@index([updatedAt,id], map: "SmsSubmitRecord_monitor_updated_idx")
|
||||
@@index([createdAt,id], map: "SmsSubmitRecord_monitor_created_idx")
|
||||
}
|
||||
|
||||
model GatewaySubmitOutbox {
|
||||
@@ -1958,6 +2014,9 @@ model SmsMessageSegmentAudit {
|
||||
errorCode String?
|
||||
errorMessage String?
|
||||
submittedAt DateTime?
|
||||
firstWireSubmitAt DateTime?
|
||||
wireTimeSource String?
|
||||
receiptRequested Boolean?
|
||||
deliveredAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
@@ -2339,6 +2398,7 @@ model UpstreamReceiptInbox {
|
||||
errorCode String?
|
||||
errorMessage String?
|
||||
deliveredAt DateTime
|
||||
gatewayReceivedAt DateTime?
|
||||
receivedAt DateTime @default(now())
|
||||
status String @default("pending")
|
||||
matchedMessageRecordId String?
|
||||
@@ -2355,6 +2415,8 @@ model UpstreamReceiptInbox {
|
||||
@@index([gatewayMessageId, phoneNumber])
|
||||
@@index([incomingChannelId, receivedAt])
|
||||
@@index([matchedMessageRecordId])
|
||||
@@index([updatedAt,id], map: "UpstreamReceiptInbox_monitor_updated_idx")
|
||||
@@index([matchedMessageRecordId,gatewayMessageId], map: "UpstreamReceiptInbox_monitor_message_idx")
|
||||
}
|
||||
|
||||
model GatewaySubmitDeadLetter {
|
||||
@@ -2563,3 +2625,127 @@ model InfrastructureAlertRead {
|
||||
@@unique([fingerprint, userId])
|
||||
@@index([userId, readAt])
|
||||
}
|
||||
|
||||
model SendingMonitorTarget {
|
||||
channelId String @id
|
||||
enabled Boolean
|
||||
version Int
|
||||
effectiveFrom DateTime
|
||||
updatedAt DateTime @default(dbgenerated("(CURRENT_TIMESTAMP AT TIME ZONE 'UTC')"))
|
||||
updatedBy String
|
||||
}
|
||||
|
||||
model SendingMonitorRule {
|
||||
id String @id
|
||||
type String
|
||||
scopeKey String
|
||||
scope Json
|
||||
config Json
|
||||
version Int
|
||||
effectiveAt DateTime
|
||||
updatedAt DateTime @default(dbgenerated("(CURRENT_TIMESTAMP AT TIME ZONE 'UTC')"))
|
||||
updatedBy String
|
||||
@@unique([type,scopeKey])
|
||||
}
|
||||
|
||||
model SendingMonitorRuleVersion {
|
||||
ruleId String
|
||||
version Int
|
||||
type String
|
||||
scope Json
|
||||
config Json
|
||||
effectiveAt DateTime
|
||||
createdAt DateTime @default(dbgenerated("(CURRENT_TIMESTAMP AT TIME ZONE 'UTC')"))
|
||||
createdBy String
|
||||
@@id([ruleId,version])
|
||||
@@index([type,effectiveAt], map: "SendingMonitorRuleVersion_effective_idx")
|
||||
}
|
||||
|
||||
model SendingMonitorFact {
|
||||
id String @id
|
||||
kind String
|
||||
sourceId String
|
||||
messageRecordId String?
|
||||
messageRecord SmsMessageRecord? @relation(fields: [messageRecordId], references: [id], onDelete: SetNull)
|
||||
dimensionKey String
|
||||
dimensions Json
|
||||
submittedAt DateTime
|
||||
successAt DateTime?
|
||||
verification Boolean
|
||||
reason String?
|
||||
updatedAt DateTime @default(dbgenerated("(CURRENT_TIMESTAMP AT TIME ZONE 'UTC')"))
|
||||
@@unique([kind,sourceId])
|
||||
@@index([messageRecordId], map: "SendingMonitorFact_message_idx")
|
||||
@@index([kind,submittedAt,dimensionKey], map: "SendingMonitorFact_window_idx")
|
||||
}
|
||||
|
||||
model SendingMonitorMinute {
|
||||
kind String
|
||||
dimensionKey String
|
||||
minute DateTime
|
||||
verification Boolean
|
||||
dimensions Json
|
||||
metrics Json
|
||||
updatedAt DateTime @default(dbgenerated("(CURRENT_TIMESTAMP AT TIME ZONE 'UTC')"))
|
||||
@@id([kind,dimensionKey,minute,verification])
|
||||
@@index([kind,minute], map: "SendingMonitorMinute_window_idx")
|
||||
}
|
||||
|
||||
model SendingMonitorSnapshot {
|
||||
id String @id
|
||||
type String
|
||||
dimensionKey String
|
||||
dimensions Json
|
||||
evaluationAt DateTime
|
||||
windowFrom DateTime
|
||||
observedUntil DateTime
|
||||
stage String
|
||||
revision Int @default(1)
|
||||
metrics Json
|
||||
rule Json?
|
||||
status String
|
||||
completeness Json
|
||||
computedAt DateTime @default(dbgenerated("(CURRENT_TIMESTAMP AT TIME ZONE 'UTC')"))
|
||||
@@unique([type,dimensionKey,evaluationAt])
|
||||
@@index([type,evaluationAt(sort: Desc),status], map: "SendingMonitorSnapshot_latest_idx")
|
||||
@@index([type,dimensionKey,evaluationAt], map: "SendingMonitorSnapshot_history_idx")
|
||||
}
|
||||
|
||||
model SendingMonitorAlert {
|
||||
id String @id
|
||||
type String
|
||||
dimensionKey String
|
||||
dimensions Json
|
||||
state String
|
||||
openedAt DateTime
|
||||
lastEvaluatedAt DateTime
|
||||
closedAt DateTime?
|
||||
closeReason String?
|
||||
ruleKey String
|
||||
latest Json
|
||||
worst Json
|
||||
updatedAt DateTime @default(dbgenerated("(CURRENT_TIMESTAMP AT TIME ZONE 'UTC')"))
|
||||
@@index([state,openedAt(sort: Desc)], map: "SendingMonitorAlert_state_idx")
|
||||
}
|
||||
|
||||
model SendingMonitorAlertRead {
|
||||
alertId String
|
||||
userId String
|
||||
readAt DateTime @default(dbgenerated("(CURRENT_TIMESTAMP AT TIME ZONE 'UTC')"))
|
||||
@@id([alertId,userId])
|
||||
}
|
||||
|
||||
model SendingMonitorCheckpoint {
|
||||
id String @id
|
||||
data Json
|
||||
updatedAt DateTime @default(dbgenerated("(CURRENT_TIMESTAMP AT TIME ZONE 'UTC')"))
|
||||
}
|
||||
|
||||
model SendingMonitorTargetVersion {
|
||||
channelId String
|
||||
version Int
|
||||
enabled Boolean
|
||||
effectiveFrom DateTime @db.Timestamp(3)
|
||||
updatedBy String
|
||||
@@id([channelId,version])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user