fix: enforce application limits and signature format
This commit is contained in:
+75
@@ -0,0 +1,75 @@
|
||||
-- Enforce a real per-application daily send quota and make 100,000 the platform default.
|
||||
UPDATE "SmsApplication"
|
||||
SET "dailyLimit" = 100000
|
||||
WHERE "dailyLimit" IS NULL;
|
||||
|
||||
ALTER TABLE "SmsApplication"
|
||||
ALTER COLUMN "dailyLimit" SET DEFAULT 100000,
|
||||
ALTER COLUMN "dailyLimit" SET NOT NULL;
|
||||
|
||||
CREATE TABLE "SmsApplicationDailyUsage" (
|
||||
"id" TEXT NOT NULL,
|
||||
"applicationId" TEXT NOT NULL,
|
||||
"usageDate" DATE NOT NULL,
|
||||
"usedCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "SmsApplicationDailyUsage_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "SmsApplicationDailyUsage_applicationId_usageDate_key"
|
||||
ON "SmsApplicationDailyUsage"("applicationId", "usageDate");
|
||||
CREATE INDEX "SmsApplicationDailyUsage_usageDate_idx"
|
||||
ON "SmsApplicationDailyUsage"("usageDate");
|
||||
ALTER TABLE "SmsApplicationDailyUsage"
|
||||
ADD CONSTRAINT "SmsApplicationDailyUsage_applicationId_fkey"
|
||||
FOREIGN KEY ("applicationId") REFERENCES "SmsApplication"("id")
|
||||
ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- Preserve sends already accepted earlier on the deployment day, so deploying at
|
||||
-- midday cannot grant an extra full quota. The business day is Asia/Shanghai.
|
||||
INSERT INTO "SmsApplicationDailyUsage" (
|
||||
"id", "applicationId", "usageDate", "usedCount", "createdAt", "updatedAt"
|
||||
)
|
||||
SELECT
|
||||
md5(message."applicationId" || ':' || ((CURRENT_TIMESTAMP AT TIME ZONE 'Asia/Shanghai')::date)::text),
|
||||
message."applicationId",
|
||||
(CURRENT_TIMESTAMP AT TIME ZONE 'Asia/Shanghai')::date,
|
||||
COUNT(*)::integer,
|
||||
CURRENT_TIMESTAMP,
|
||||
CURRENT_TIMESTAMP
|
||||
FROM "SmsMessageRecord" message
|
||||
WHERE message."applicationId" IS NOT NULL
|
||||
AND message."queuedAt" >= ((CURRENT_TIMESTAMP AT TIME ZONE 'Asia/Shanghai')::date::timestamp AT TIME ZONE 'Asia/Shanghai')
|
||||
AND message."queuedAt" < (((CURRENT_TIMESTAMP AT TIME ZONE 'Asia/Shanghai')::date + 1)::timestamp AT TIME ZONE 'Asia/Shanghai')
|
||||
GROUP BY message."applicationId";
|
||||
|
||||
-- HTTP applications created before the UI default fix retained CMPP delivery modes.
|
||||
-- Existing enabled webhook capabilities are migrated to the HTTP transport they expose.
|
||||
UPDATE "SmsApplicationHttpConfig"
|
||||
SET "receiptDeliveryMode" = 'http'
|
||||
WHERE "enabled" = TRUE
|
||||
AND "receiptWebhookEnabled" = TRUE
|
||||
AND "receiptDeliveryMode" = 'cmpp';
|
||||
|
||||
UPDATE "SmsApplicationHttpConfig"
|
||||
SET "uplinkDeliveryMode" = 'http'
|
||||
WHERE "enabled" = TRUE
|
||||
AND "uplinkWebhookEnabled" = TRUE
|
||||
AND "uplinkDeliveryMode" = 'cmpp';
|
||||
|
||||
ALTER TABLE "SmsApplicationHttpConfig"
|
||||
ALTER COLUMN "sendEnabled" SET DEFAULT TRUE,
|
||||
ALTER COLUMN "messageQueryEnabled" SET DEFAULT TRUE,
|
||||
ALTER COLUMN "receiptWebhookEnabled" SET DEFAULT TRUE,
|
||||
ALTER COLUMN "uplinkWebhookEnabled" SET DEFAULT TRUE,
|
||||
ALTER COLUMN "uplinkQueryEnabled" SET DEFAULT TRUE,
|
||||
ALTER COLUMN "credentialSelfServiceEnabled" SET DEFAULT TRUE,
|
||||
ALTER COLUMN "receiptDeliveryMode" SET DEFAULT 'http',
|
||||
ALTER COLUMN "uplinkDeliveryMode" SET DEFAULT 'http';
|
||||
|
||||
-- Rollback guidance:
|
||||
-- Drop SmsApplicationDailyUsage and its FK/indexes, restore SmsApplication.dailyLimit
|
||||
-- to nullable/no-default, and restore HTTP column defaults to FALSE/'cmpp'. Data migrated
|
||||
-- from cmpp to http is intentionally not auto-reversed because explicit edits after upgrade
|
||||
-- cannot be distinguished safely.
|
||||
@@ -0,0 +1,20 @@
|
||||
-- SMS signature names are canonical business identifiers and must contain
|
||||
-- exactly one complete pair of Chinese black brackets: 【signature】.
|
||||
WITH normalized AS (
|
||||
SELECT
|
||||
id,
|
||||
btrim(
|
||||
regexp_replace(
|
||||
regexp_replace(btrim(name), '^[【\[]+', ''),
|
||||
'[】\]]+$',
|
||||
''
|
||||
)
|
||||
) AS inner_name
|
||||
FROM "SmsSignature"
|
||||
)
|
||||
UPDATE "SmsSignature" AS signature
|
||||
SET name = '【' || normalized.inner_name || '】'
|
||||
FROM normalized
|
||||
WHERE signature.id = normalized.id
|
||||
AND normalized.inner_name <> ''
|
||||
AND signature.name IS DISTINCT FROM '【' || normalized.inner_name || '】';
|
||||
@@ -366,7 +366,7 @@ model SmsApplication {
|
||||
interfaceType String @default("cmpp20")
|
||||
cmppMaxConnections Int @default(1)
|
||||
cmppWindowSize Int @default(16)
|
||||
dailyLimit Int?
|
||||
dailyLimit Int @default(100000)
|
||||
customerUnitPrice BigInt @default(0)
|
||||
queuePriority String @default("normal")
|
||||
maxPhonesPerTask Int @default(1000000)
|
||||
@@ -399,6 +399,7 @@ model SmsApplication {
|
||||
openApiRequests OpenApiRequest[]
|
||||
httpWebhookEndpoints HttpWebhookEndpoint[]
|
||||
httpWebhookEvents HttpWebhookEvent[]
|
||||
dailyUsages SmsApplicationDailyUsage[]
|
||||
|
||||
@@index([tenantId, status])
|
||||
}
|
||||
@@ -419,20 +420,20 @@ model SmsApplicationHttpConfig {
|
||||
id String @id @default(cuid())
|
||||
applicationId String @unique
|
||||
enabled Boolean @default(false)
|
||||
sendEnabled Boolean @default(false)
|
||||
messageQueryEnabled Boolean @default(false)
|
||||
receiptWebhookEnabled Boolean @default(false)
|
||||
uplinkWebhookEnabled Boolean @default(false)
|
||||
uplinkQueryEnabled Boolean @default(false)
|
||||
credentialSelfServiceEnabled Boolean @default(false)
|
||||
sendEnabled Boolean @default(true)
|
||||
messageQueryEnabled Boolean @default(true)
|
||||
receiptWebhookEnabled Boolean @default(true)
|
||||
uplinkWebhookEnabled Boolean @default(true)
|
||||
uplinkQueryEnabled Boolean @default(true)
|
||||
credentialSelfServiceEnabled Boolean @default(true)
|
||||
qpsLimit Int @default(10)
|
||||
timestampToleranceSeconds Int @default(300)
|
||||
maxCredentialCount Int @default(2)
|
||||
uplinkRetentionDays Int @default(90)
|
||||
maxQueryRangeDays Int @default(31)
|
||||
maxPageSize Int @default(100)
|
||||
receiptDeliveryMode String @default("cmpp")
|
||||
uplinkDeliveryMode String @default("cmpp")
|
||||
receiptDeliveryMode String @default("http")
|
||||
uplinkDeliveryMode String @default("http")
|
||||
webhookRetryEnabled Boolean @default(true)
|
||||
webhookMaxAttempts Int @default(7)
|
||||
webhookTimeoutSeconds Int @default(10)
|
||||
@@ -445,6 +446,20 @@ model SmsApplicationHttpConfig {
|
||||
application SmsApplication @relation(fields: [applicationId], references: [id], onDelete: Cascade)
|
||||
}
|
||||
|
||||
model SmsApplicationDailyUsage {
|
||||
id String @id @default(cuid())
|
||||
applicationId String
|
||||
usageDate DateTime @db.Date
|
||||
usedCount Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
application SmsApplication @relation(fields: [applicationId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([applicationId, usageDate])
|
||||
@@index([usageDate])
|
||||
}
|
||||
|
||||
model SmsApplicationHttpIpAllowlist {
|
||||
id String @id @default(cuid())
|
||||
applicationId String
|
||||
|
||||
Reference in New Issue
Block a user