feat: add report material workflows and gateway safeguards
This commit is contained in:
+134
@@ -0,0 +1,134 @@
|
||||
ALTER TABLE "SmsSignature"
|
||||
ADD COLUMN "materialVersion" INTEGER NOT NULL DEFAULT 1,
|
||||
ADD COLUMN "pendingReport" BOOLEAN NOT NULL DEFAULT true,
|
||||
ADD COLUMN "reportChangedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE "SmsDrainageInfo"
|
||||
ADD COLUMN "materialVersion" INTEGER NOT NULL DEFAULT 1,
|
||||
ADD COLUMN "pendingReport" BOOLEAN NOT NULL DEFAULT true,
|
||||
ADD COLUMN "reportChangedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
|
||||
|
||||
ALTER TABLE "ChannelReportField"
|
||||
ADD COLUMN "exportName" TEXT,
|
||||
ADD COLUMN "columnWidth" INTEGER NOT NULL DEFAULT 18,
|
||||
ADD COLUMN "imageWidth" INTEGER NOT NULL DEFAULT 120,
|
||||
ADD COLUMN "imageHeight" INTEGER NOT NULL DEFAULT 80,
|
||||
ADD COLUMN "defaultValue" TEXT,
|
||||
ADD COLUMN "transform" TEXT;
|
||||
|
||||
ALTER TABLE "ReportExportFile"
|
||||
ALTER COLUMN "taskId" DROP NOT NULL,
|
||||
ADD COLUMN "batchId" TEXT,
|
||||
ADD COLUMN "channelId" TEXT;
|
||||
|
||||
CREATE TABLE "ReportMaterialBatch" (
|
||||
"id" TEXT NOT NULL,
|
||||
"batchNo" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'generating',
|
||||
"createdById" TEXT,
|
||||
"selectedCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"channelCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"fileCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"errorMessage" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"completedAt" TIMESTAMP(3),
|
||||
CONSTRAINT "ReportMaterialBatch_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "ReportMaterialBatchItem" (
|
||||
"id" TEXT NOT NULL,
|
||||
"batchId" TEXT NOT NULL,
|
||||
"signatureId" TEXT NOT NULL,
|
||||
"drainageItemId" TEXT,
|
||||
"reportType" TEXT NOT NULL,
|
||||
"materialVersion" INTEGER NOT NULL,
|
||||
"snapshot" JSONB NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "ReportMaterialBatchItem_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "ReportExportFileItem" (
|
||||
"id" TEXT NOT NULL,
|
||||
"exportFileId" TEXT NOT NULL,
|
||||
"batchItemId" TEXT NOT NULL,
|
||||
"taskId" TEXT NOT NULL,
|
||||
"rowNumber" INTEGER NOT NULL,
|
||||
CONSTRAINT "ReportExportFileItem_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "ReportMaterialImportProfile" (
|
||||
"id" TEXT NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"reportType" TEXT NOT NULL,
|
||||
"tenantId" TEXT,
|
||||
"applicationId" TEXT,
|
||||
"sheetName" TEXT,
|
||||
"headerRowCount" INTEGER NOT NULL DEFAULT 1,
|
||||
"dataStartRow" INTEGER NOT NULL DEFAULT 2,
|
||||
"status" TEXT NOT NULL DEFAULT 'active',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
CONSTRAINT "ReportMaterialImportProfile_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "ReportMaterialImportProfileColumn" (
|
||||
"id" TEXT NOT NULL,
|
||||
"profileId" TEXT NOT NULL,
|
||||
"sourceHeader" TEXT NOT NULL,
|
||||
"sourceHeaderPath" TEXT,
|
||||
"sourceColumnIndex" INTEGER NOT NULL,
|
||||
"targetFieldCode" TEXT NOT NULL,
|
||||
"targetKind" TEXT NOT NULL DEFAULT 'dynamic',
|
||||
"fieldType" TEXT NOT NULL DEFAULT 'string',
|
||||
"required" BOOLEAN NOT NULL DEFAULT false,
|
||||
"transform" TEXT,
|
||||
"sortOrder" INTEGER NOT NULL DEFAULT 100,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
CONSTRAINT "ReportMaterialImportProfileColumn_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE TABLE "ReportMaterialImportBatch" (
|
||||
"id" TEXT NOT NULL,
|
||||
"tenantId" TEXT NOT NULL,
|
||||
"applicationId" TEXT,
|
||||
"profileId" TEXT,
|
||||
"fileObjectId" TEXT NOT NULL,
|
||||
"fileName" TEXT NOT NULL,
|
||||
"reportType" TEXT NOT NULL,
|
||||
"status" TEXT NOT NULL DEFAULT 'analyzed',
|
||||
"sheetName" TEXT NOT NULL,
|
||||
"headerRowCount" INTEGER NOT NULL DEFAULT 1,
|
||||
"dataStartRow" INTEGER NOT NULL DEFAULT 2,
|
||||
"mapping" JSONB NOT NULL,
|
||||
"preview" JSONB,
|
||||
"result" JSONB,
|
||||
"rowCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"successCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"failedCount" INTEGER NOT NULL DEFAULT 0,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"completedAt" TIMESTAMP(3),
|
||||
CONSTRAINT "ReportMaterialImportBatch_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX "ReportMaterialBatch_batchNo_key" ON "ReportMaterialBatch"("batchNo");
|
||||
CREATE INDEX "ReportMaterialBatch_status_createdAt_idx" ON "ReportMaterialBatch"("status", "createdAt");
|
||||
CREATE INDEX "ReportMaterialBatchItem_batchId_reportType_idx" ON "ReportMaterialBatchItem"("batchId", "reportType");
|
||||
CREATE INDEX "ReportMaterialBatchItem_signatureId_drainageItemId_idx" ON "ReportMaterialBatchItem"("signatureId", "drainageItemId");
|
||||
CREATE UNIQUE INDEX "ReportExportFileItem_exportFileId_batchItemId_key" ON "ReportExportFileItem"("exportFileId", "batchItemId");
|
||||
CREATE INDEX "ReportExportFileItem_taskId_idx" ON "ReportExportFileItem"("taskId");
|
||||
CREATE INDEX "ReportExportFile_batchId_channelId_idx" ON "ReportExportFile"("batchId", "channelId");
|
||||
CREATE INDEX "ReportMaterialImportProfile_reportType_status_idx" ON "ReportMaterialImportProfile"("reportType", "status");
|
||||
CREATE INDEX "ReportMaterialImportProfile_tenantId_applicationId_idx" ON "ReportMaterialImportProfile"("tenantId", "applicationId");
|
||||
CREATE UNIQUE INDEX "ReportMaterialImportProfileColumn_profileId_sourceColumnIndex_key" ON "ReportMaterialImportProfileColumn"("profileId", "sourceColumnIndex");
|
||||
CREATE INDEX "ReportMaterialImportProfileColumn_profileId_sortOrder_idx" ON "ReportMaterialImportProfileColumn"("profileId", "sortOrder");
|
||||
CREATE INDEX "ReportMaterialImportBatch_tenantId_createdAt_idx" ON "ReportMaterialImportBatch"("tenantId", "createdAt");
|
||||
CREATE INDEX "ReportMaterialImportBatch_status_createdAt_idx" ON "ReportMaterialImportBatch"("status", "createdAt");
|
||||
|
||||
ALTER TABLE "ReportExportFile" ADD CONSTRAINT "ReportExportFile_batchId_fkey" FOREIGN KEY ("batchId") REFERENCES "ReportMaterialBatch"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "ReportMaterialBatchItem" ADD CONSTRAINT "ReportMaterialBatchItem_batchId_fkey" FOREIGN KEY ("batchId") REFERENCES "ReportMaterialBatch"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "ReportMaterialBatchItem" ADD CONSTRAINT "ReportMaterialBatchItem_signatureId_fkey" FOREIGN KEY ("signatureId") REFERENCES "SmsSignature"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
ALTER TABLE "ReportMaterialBatchItem" ADD CONSTRAINT "ReportMaterialBatchItem_drainageItemId_fkey" FOREIGN KEY ("drainageItemId") REFERENCES "SmsDrainageInfo"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
ALTER TABLE "ReportExportFileItem" ADD CONSTRAINT "ReportExportFileItem_exportFileId_fkey" FOREIGN KEY ("exportFileId") REFERENCES "ReportExportFile"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "ReportExportFileItem" ADD CONSTRAINT "ReportExportFileItem_batchItemId_fkey" FOREIGN KEY ("batchItemId") REFERENCES "ReportMaterialBatchItem"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "ReportExportFileItem" ADD CONSTRAINT "ReportExportFileItem_taskId_fkey" FOREIGN KEY ("taskId") REFERENCES "ChannelSignatureReportTask"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
ALTER TABLE "ReportMaterialImportProfileColumn" ADD CONSTRAINT "ReportMaterialImportProfileColumn_profileId_fkey" FOREIGN KEY ("profileId") REFERENCES "ReportMaterialImportProfile"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
DROP INDEX IF EXISTS "ChannelReportField_channelId_code_key";
|
||||
|
||||
INSERT INTO "ChannelReportField" (
|
||||
"id", "channelId", "drainageFieldId", "reportType", "code", "name", "exportName", "fieldType",
|
||||
"required", "description", "sortOrder", "columnWidth", "imageWidth", "imageHeight", "defaultValue",
|
||||
"transform", "status", "createdAt", "updatedAt"
|
||||
)
|
||||
SELECT
|
||||
"id" || '_drainage', "channelId", "drainageFieldId", 'drainage', "code", "name", "exportName", "fieldType",
|
||||
"required", "description", "sortOrder", "columnWidth", "imageWidth", "imageHeight", "defaultValue",
|
||||
"transform", "status", "createdAt", "updatedAt"
|
||||
FROM "ChannelReportField"
|
||||
WHERE "reportType" = 'both';
|
||||
|
||||
UPDATE "ChannelReportField" SET "reportType" = 'signature' WHERE "reportType" = 'both';
|
||||
|
||||
CREATE UNIQUE INDEX "ChannelReportField_channelId_code_reportType_key"
|
||||
ON "ChannelReportField"("channelId", "code", "reportType");
|
||||
+4
@@ -0,0 +1,4 @@
|
||||
-- Existing rows predate the pending-material workflow and must not be treated as newly changed.
|
||||
-- New rows continue to use the schema default (true), while later edits explicitly set true.
|
||||
UPDATE "SmsSignature" SET "pendingReport" = false;
|
||||
UPDATE "SmsDrainageInfo" SET "pendingReport" = false;
|
||||
@@ -0,0 +1 @@
|
||||
ALTER TABLE "SmsChannelGroupItem" DROP COLUMN "rateLimitPerSecond";
|
||||
+140
-4
@@ -417,6 +417,9 @@ model SmsSignature {
|
||||
auditStatus String @default("draft")
|
||||
reportStatus String @default("waiting_material")
|
||||
rejectReason String?
|
||||
materialVersion Int @default(1)
|
||||
pendingReport Boolean @default(true)
|
||||
reportChangedAt DateTime @default(now())
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@ -429,6 +432,7 @@ model SmsSignature {
|
||||
drainageItems SmsDrainageInfo[]
|
||||
reportTasks ChannelSignatureReportTask[]
|
||||
messageRecords SmsMessageRecord[]
|
||||
reportBatchItems ReportMaterialBatchItem[]
|
||||
|
||||
@@index([tenantId, auditStatus])
|
||||
@@index([tenantId, reportStatus])
|
||||
@@ -445,6 +449,9 @@ model SmsDrainageInfo {
|
||||
reportValues Json?
|
||||
auditStatus String @default("pending")
|
||||
rejectReason String?
|
||||
materialVersion Int @default(1)
|
||||
pendingReport Boolean @default(true)
|
||||
reportChangedAt DateTime @default(now())
|
||||
submittedAt DateTime @default(now())
|
||||
reviewedAt DateTime?
|
||||
createdAt DateTime @default(now())
|
||||
@@ -455,6 +462,7 @@ model SmsDrainageInfo {
|
||||
application SmsApplication? @relation(fields: [applicationId], references: [id])
|
||||
reportTasks ChannelSignatureReportTask[]
|
||||
messageRecords SmsMessageRecord[]
|
||||
reportBatchItems ReportMaterialBatchItem[]
|
||||
|
||||
@@index([tenantId, auditStatus, updatedAt])
|
||||
@@index([signatureId, auditStatus])
|
||||
@@ -651,7 +659,6 @@ model SmsChannelGroupItem {
|
||||
priority Int @default(100)
|
||||
weight Int @default(1)
|
||||
isBackup Boolean @default(false)
|
||||
rateLimitPerSecond Int?
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
group SmsChannelGroup @relation(fields: [groupId], references: [id], onDelete: Cascade)
|
||||
@@ -707,10 +714,16 @@ model ChannelReportField {
|
||||
reportType String @default("both")
|
||||
code String
|
||||
name String
|
||||
exportName String?
|
||||
fieldType String
|
||||
required Boolean @default(false)
|
||||
description String?
|
||||
sortOrder Int @default(100)
|
||||
columnWidth Int @default(18)
|
||||
imageWidth Int @default(120)
|
||||
imageHeight Int @default(80)
|
||||
defaultValue String?
|
||||
transform String?
|
||||
status String @default("active")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
@@ -718,7 +731,7 @@ model ChannelReportField {
|
||||
channel SmsChannel @relation(fields: [channelId], references: [id], onDelete: Cascade)
|
||||
drainageField DrainageField? @relation(fields: [drainageFieldId], references: [id])
|
||||
|
||||
@@unique([channelId, code])
|
||||
@@unique([channelId, code, reportType])
|
||||
@@index([drainageFieldId, reportType])
|
||||
}
|
||||
|
||||
@@ -791,6 +804,7 @@ model ChannelSignatureReportTask {
|
||||
records ChannelSignatureReportRecord[]
|
||||
exportFiles ReportExportFile[]
|
||||
receiptImports ReportReceiptImport[]
|
||||
exportItems ReportExportFileItem[]
|
||||
|
||||
@@index([tenantId, status])
|
||||
@@index([signatureId, channelId])
|
||||
@@ -819,14 +833,136 @@ model ChannelSignatureReportRecord {
|
||||
|
||||
model ReportExportFile {
|
||||
id String @id @default(cuid())
|
||||
taskId String
|
||||
taskId String?
|
||||
batchId String?
|
||||
channelId String?
|
||||
fileObjectId String?
|
||||
fileName String
|
||||
rowCount Int @default(0)
|
||||
status String @default("generated")
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
task ChannelSignatureReportTask @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
||||
task ChannelSignatureReportTask? @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
||||
batch ReportMaterialBatch? @relation(fields: [batchId], references: [id], onDelete: Cascade)
|
||||
items ReportExportFileItem[]
|
||||
|
||||
@@index([batchId, channelId])
|
||||
}
|
||||
|
||||
model ReportMaterialBatch {
|
||||
id String @id @default(cuid())
|
||||
batchNo String @unique
|
||||
status String @default("generating")
|
||||
createdById String?
|
||||
selectedCount Int @default(0)
|
||||
channelCount Int @default(0)
|
||||
fileCount Int @default(0)
|
||||
errorMessage String?
|
||||
createdAt DateTime @default(now())
|
||||
completedAt DateTime?
|
||||
|
||||
items ReportMaterialBatchItem[]
|
||||
exportFiles ReportExportFile[]
|
||||
|
||||
@@index([status, createdAt])
|
||||
}
|
||||
|
||||
model ReportMaterialBatchItem {
|
||||
id String @id @default(cuid())
|
||||
batchId String
|
||||
signatureId String
|
||||
drainageItemId String?
|
||||
reportType String
|
||||
materialVersion Int
|
||||
snapshot Json
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
batch ReportMaterialBatch @relation(fields: [batchId], references: [id], onDelete: Cascade)
|
||||
signature SmsSignature @relation(fields: [signatureId], references: [id])
|
||||
drainageInfo SmsDrainageInfo? @relation(fields: [drainageItemId], references: [id])
|
||||
exportItems ReportExportFileItem[]
|
||||
|
||||
@@index([batchId, reportType])
|
||||
@@index([signatureId, drainageItemId])
|
||||
}
|
||||
|
||||
model ReportExportFileItem {
|
||||
id String @id @default(cuid())
|
||||
exportFileId String
|
||||
batchItemId String
|
||||
taskId String
|
||||
rowNumber Int
|
||||
|
||||
exportFile ReportExportFile @relation(fields: [exportFileId], references: [id], onDelete: Cascade)
|
||||
batchItem ReportMaterialBatchItem @relation(fields: [batchItemId], references: [id], onDelete: Cascade)
|
||||
task ChannelSignatureReportTask @relation(fields: [taskId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([exportFileId, batchItemId])
|
||||
@@index([taskId])
|
||||
}
|
||||
|
||||
model ReportMaterialImportProfile {
|
||||
id String @id @default(cuid())
|
||||
name String
|
||||
reportType String
|
||||
tenantId String?
|
||||
applicationId String?
|
||||
sheetName String?
|
||||
headerRowCount Int @default(1)
|
||||
dataStartRow Int @default(2)
|
||||
status String @default("active")
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
columns ReportMaterialImportProfileColumn[]
|
||||
|
||||
@@index([reportType, status])
|
||||
@@index([tenantId, applicationId])
|
||||
}
|
||||
|
||||
model ReportMaterialImportProfileColumn {
|
||||
id String @id @default(cuid())
|
||||
profileId String
|
||||
sourceHeader String
|
||||
sourceHeaderPath String?
|
||||
sourceColumnIndex Int
|
||||
targetFieldCode String
|
||||
targetKind String @default("dynamic")
|
||||
fieldType String @default("string")
|
||||
required Boolean @default(false)
|
||||
transform String?
|
||||
sortOrder Int @default(100)
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
profile ReportMaterialImportProfile @relation(fields: [profileId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([profileId, sourceColumnIndex])
|
||||
@@index([profileId, sortOrder])
|
||||
}
|
||||
|
||||
model ReportMaterialImportBatch {
|
||||
id String @id @default(cuid())
|
||||
tenantId String
|
||||
applicationId String?
|
||||
profileId String?
|
||||
fileObjectId String
|
||||
fileName String
|
||||
reportType String
|
||||
status String @default("analyzed")
|
||||
sheetName String
|
||||
headerRowCount Int @default(1)
|
||||
dataStartRow Int @default(2)
|
||||
mapping Json
|
||||
preview Json?
|
||||
result Json?
|
||||
rowCount Int @default(0)
|
||||
successCount Int @default(0)
|
||||
failedCount Int @default(0)
|
||||
createdAt DateTime @default(now())
|
||||
completedAt DateTime?
|
||||
|
||||
@@index([tenantId, createdAt])
|
||||
@@index([status, createdAt])
|
||||
}
|
||||
|
||||
model ReportReceiptImport {
|
||||
|
||||
Reference in New Issue
Block a user