Initial commit: 风影 OA 全栈源码(API/Web/Flutter/IM)

含 Phase 1.1 IM seq 排序、断线重连、多端已读同步与微信式语音转文字 UI。
排除 node_modules、构建产物、安装包与 .env 密钥。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-09-02 10:04:03 +00:00
commit 76f266645d
507 changed files with 99891 additions and 0 deletions
@@ -0,0 +1,567 @@
-- CreateTable
CREATE TABLE "User" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"username" TEXT NOT NULL,
"passwordHash" TEXT NOT NULL,
"displayName" TEXT NOT NULL,
"status" TEXT NOT NULL DEFAULT 'ACTIVE',
"employeeId" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "RefreshToken" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"tokenHash" TEXT NOT NULL,
"expiresAt" TIMESTAMP(3) NOT NULL,
"revokedAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "RefreshToken_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Department" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"parentId" TEXT,
"name" TEXT NOT NULL,
"code" TEXT NOT NULL,
"deptType" TEXT NOT NULL,
"categoryCode" TEXT,
"sortNo" INTEGER NOT NULL DEFAULT 0,
CONSTRAINT "Department_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Employee" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"name" TEXT NOT NULL,
"employeeNo" TEXT NOT NULL,
"departmentId" TEXT NOT NULL,
"title" TEXT,
"restSchedule" TEXT NOT NULL DEFAULT 'SINGLE',
"employmentStatus" TEXT NOT NULL DEFAULT 'REGULAR',
"hiredAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Employee_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Role" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"name" TEXT NOT NULL,
"code" TEXT NOT NULL,
"description" TEXT NOT NULL DEFAULT '',
CONSTRAINT "Role_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Permission" (
"id" TEXT NOT NULL,
"parentId" TEXT,
"name" TEXT NOT NULL,
"code" TEXT NOT NULL,
"permType" TEXT NOT NULL,
"path" TEXT,
"icon" TEXT,
"sortNo" INTEGER NOT NULL DEFAULT 0,
"visible" BOOLEAN NOT NULL DEFAULT true,
CONSTRAINT "Permission_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "RolePermission" (
"roleId" TEXT NOT NULL,
"permissionId" TEXT NOT NULL,
CONSTRAINT "RolePermission_pkey" PRIMARY KEY ("roleId","permissionId")
);
-- CreateTable
CREATE TABLE "UserRole" (
"userId" TEXT NOT NULL,
"roleId" TEXT NOT NULL,
CONSTRAINT "UserRole_pkey" PRIMARY KEY ("userId","roleId")
);
-- CreateTable
CREATE TABLE "DictItem" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"dictType" TEXT NOT NULL,
"label" TEXT NOT NULL,
"value" TEXT NOT NULL,
"sortNo" INTEGER NOT NULL DEFAULT 0,
CONSTRAINT "DictItem_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "LegalEntity" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"name" TEXT NOT NULL,
"shortName" TEXT NOT NULL,
"creditNo" TEXT,
"isDefault" BOOLEAN NOT NULL DEFAULT false,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "LegalEntity_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "BusinessParty" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"name" TEXT NOT NULL,
"creditNo" TEXT,
"level" TEXT NOT NULL DEFAULT 'B',
"riskFlag" BOOLEAN NOT NULL DEFAULT false,
"remark" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "BusinessParty_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PartyContact" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"partyId" TEXT NOT NULL,
"name" TEXT NOT NULL,
"phone" TEXT,
"title" TEXT,
CONSTRAINT "PartyContact_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Qualification" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"name" TEXT NOT NULL,
"code" TEXT NOT NULL,
"expiresAt" TIMESTAMP(3),
"keeper" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "Qualification_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "SealRequest" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"sealType" TEXT NOT NULL,
"reason" TEXT NOT NULL,
"bidCaseId" TEXT,
"takeOut" BOOLEAN NOT NULL DEFAULT false,
"returnAt" TIMESTAMP(3),
"status" TEXT NOT NULL DEFAULT 'PENDING',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "SealRequest_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "CredentialBorrow" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"itemName" TEXT NOT NULL,
"borrower" TEXT NOT NULL,
"dueAt" TIMESTAMP(3),
"returnedAt" TIMESTAMP(3),
"status" TEXT NOT NULL DEFAULT 'BORROWED',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "CredentialBorrow_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "BidCase" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"bidNo" TEXT NOT NULL,
"name" TEXT NOT NULL,
"externalNo" TEXT,
"projectType" TEXT NOT NULL,
"sourceType" TEXT NOT NULL DEFAULT 'FLOW',
"source" TEXT,
"qualificationNeed" TEXT,
"legalEntityId" TEXT,
"tenderMethod" TEXT,
"applyStartAt" TIMESTAMP(3),
"applyEndAt" TIMESTAMP(3),
"applyMethod" TEXT,
"openAt" TIMESTAMP(3),
"openMethod" TEXT,
"openPlace" TEXT,
"securityLevel" TEXT NOT NULL DEFAULT 'INTERNAL',
"projectNature" TEXT,
"partyId" TEXT,
"contactName" TEXT,
"contactPhone" TEXT,
"bondMethod" TEXT,
"bondStatus" TEXT,
"bondPaidAt" TIMESTAMP(3),
"delivererName" TEXT,
"priceCap" TEXT,
"quoteAmount" TEXT,
"summary" TEXT,
"remark" TEXT,
"status" TEXT NOT NULL DEFAULT 'TECH_INITIAL',
"nasPath" TEXT,
"createdById" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "BidCase_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "BidReviewer" (
"id" TEXT NOT NULL,
"bidCaseId" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"stage" TEXT NOT NULL,
"result" TEXT NOT NULL DEFAULT 'PENDING',
"comment" TEXT,
CONSTRAINT "BidReviewer_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "TodoTask" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"title" TEXT NOT NULL,
"bizType" TEXT NOT NULL,
"bizId" TEXT,
"assigneeId" TEXT NOT NULL,
"dueAt" TIMESTAMP(3),
"status" TEXT NOT NULL DEFAULT 'OPEN',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "TodoTask_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "ApprovalTask" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"title" TEXT NOT NULL,
"bizType" TEXT NOT NULL,
"bizId" TEXT,
"assigneeId" TEXT NOT NULL,
"status" TEXT NOT NULL DEFAULT 'PENDING',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "ApprovalTask_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "WorkReport" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"authorId" TEXT NOT NULL,
"period" TEXT NOT NULL,
"content" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "WorkReport_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Contract" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"contractNo" TEXT NOT NULL,
"name" TEXT NOT NULL,
"bidCaseId" TEXT,
"amount" DECIMAL(18,2) NOT NULL DEFAULT 0,
"status" TEXT NOT NULL DEFAULT 'DRAFT',
"signedAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Contract_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PaymentMilestone" (
"id" TEXT NOT NULL,
"contractId" TEXT NOT NULL,
"name" TEXT NOT NULL,
"ratio" DECIMAL(5,2) NOT NULL,
"dueAt" TIMESTAMP(3),
"trigger" TEXT,
CONSTRAINT "PaymentMilestone_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Project" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"projectNo" TEXT NOT NULL,
"name" TEXT NOT NULL,
"contractId" TEXT,
"status" TEXT NOT NULL DEFAULT 'ACTIVE',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Project_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "ProjectTask" (
"id" TEXT NOT NULL,
"projectId" TEXT NOT NULL,
"name" TEXT NOT NULL,
"department" TEXT,
"dueAt" TIMESTAMP(3),
"status" TEXT NOT NULL DEFAULT 'OPEN',
CONSTRAINT "ProjectTask_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "Timesheet" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"projectId" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"workDate" TIMESTAMP(3) NOT NULL,
"hours" DECIMAL(6,2) NOT NULL,
"note" TEXT,
CONSTRAINT "Timesheet_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "ExpenseClaim" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"claimNo" TEXT NOT NULL,
"applicantId" TEXT NOT NULL,
"costType" TEXT NOT NULL,
"bidCaseId" TEXT,
"projectId" TEXT,
"amount" DECIMAL(18,2) NOT NULL DEFAULT 0,
"status" TEXT NOT NULL DEFAULT 'DRAFT',
"remark" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "ExpenseClaim_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "LoanRecord" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"applicantId" TEXT NOT NULL,
"amount" DECIMAL(18,2) NOT NULL,
"purpose" TEXT NOT NULL,
"status" TEXT NOT NULL DEFAULT 'OPEN',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "LoanRecord_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "BondRecord" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"bidCaseId" TEXT NOT NULL,
"bondType" TEXT NOT NULL,
"amount" DECIMAL(18,2) NOT NULL,
"paidAt" TIMESTAMP(3),
"dueBackAt" TIMESTAMP(3),
"returnedAt" TIMESTAMP(3),
"status" TEXT NOT NULL DEFAULT 'UNPAID',
CONSTRAINT "BondRecord_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "InvoiceRecord" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"invoiceNo" TEXT,
"amount" DECIMAL(18,2) NOT NULL,
"status" TEXT NOT NULL DEFAULT 'TO_ISSUE',
"issuedAt" TIMESTAMP(3),
"receivedAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "InvoiceRecord_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "PurchaseRequest" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"title" TEXT NOT NULL,
"projectId" TEXT,
"amount" DECIMAL(18,2) NOT NULL DEFAULT 0,
"status" TEXT NOT NULL DEFAULT 'DRAFT',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "PurchaseRequest_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "AssetOccupancy" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"assetName" TEXT NOT NULL,
"holder" TEXT NOT NULL,
"status" TEXT NOT NULL DEFAULT 'IN_USE',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "AssetOccupancy_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "OperationLog" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"userId" TEXT,
"action" TEXT NOT NULL,
"path" TEXT NOT NULL,
"requestId" TEXT,
"ip" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "OperationLog_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "User_tenantId_username_key" ON "User"("tenantId", "username");
-- CreateIndex
CREATE INDEX "RefreshToken_userId_idx" ON "RefreshToken"("userId");
-- CreateIndex
CREATE UNIQUE INDEX "Department_tenantId_code_key" ON "Department"("tenantId", "code");
-- CreateIndex
CREATE UNIQUE INDEX "Employee_tenantId_employeeNo_key" ON "Employee"("tenantId", "employeeNo");
-- CreateIndex
CREATE UNIQUE INDEX "Role_tenantId_code_key" ON "Role"("tenantId", "code");
-- CreateIndex
CREATE UNIQUE INDEX "Permission_code_key" ON "Permission"("code");
-- CreateIndex
CREATE UNIQUE INDEX "DictItem_tenantId_dictType_value_key" ON "DictItem"("tenantId", "dictType", "value");
-- CreateIndex
CREATE UNIQUE INDEX "LegalEntity_tenantId_name_key" ON "LegalEntity"("tenantId", "name");
-- CreateIndex
CREATE UNIQUE INDEX "BusinessParty_tenantId_name_key" ON "BusinessParty"("tenantId", "name");
-- CreateIndex
CREATE UNIQUE INDEX "BidCase_tenantId_bidNo_key" ON "BidCase"("tenantId", "bidNo");
-- CreateIndex
CREATE INDEX "BidReviewer_bidCaseId_idx" ON "BidReviewer"("bidCaseId");
-- CreateIndex
CREATE UNIQUE INDEX "Contract_tenantId_contractNo_key" ON "Contract"("tenantId", "contractNo");
-- CreateIndex
CREATE UNIQUE INDEX "Project_tenantId_projectNo_key" ON "Project"("tenantId", "projectNo");
-- CreateIndex
CREATE UNIQUE INDEX "ExpenseClaim_tenantId_claimNo_key" ON "ExpenseClaim"("tenantId", "claimNo");
-- AddForeignKey
ALTER TABLE "User" ADD CONSTRAINT "User_employeeId_fkey" FOREIGN KEY ("employeeId") REFERENCES "Employee"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "RefreshToken" ADD CONSTRAINT "RefreshToken_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Department" ADD CONSTRAINT "Department_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "Department"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Employee" ADD CONSTRAINT "Employee_departmentId_fkey" FOREIGN KEY ("departmentId") REFERENCES "Department"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Permission" ADD CONSTRAINT "Permission_parentId_fkey" FOREIGN KEY ("parentId") REFERENCES "Permission"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "RolePermission" ADD CONSTRAINT "RolePermission_roleId_fkey" FOREIGN KEY ("roleId") REFERENCES "Role"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "RolePermission" ADD CONSTRAINT "RolePermission_permissionId_fkey" FOREIGN KEY ("permissionId") REFERENCES "Permission"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "UserRole" ADD CONSTRAINT "UserRole_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "UserRole" ADD CONSTRAINT "UserRole_roleId_fkey" FOREIGN KEY ("roleId") REFERENCES "Role"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PartyContact" ADD CONSTRAINT "PartyContact_partyId_fkey" FOREIGN KEY ("partyId") REFERENCES "BusinessParty"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BidCase" ADD CONSTRAINT "BidCase_legalEntityId_fkey" FOREIGN KEY ("legalEntityId") REFERENCES "LegalEntity"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BidCase" ADD CONSTRAINT "BidCase_partyId_fkey" FOREIGN KEY ("partyId") REFERENCES "BusinessParty"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BidCase" ADD CONSTRAINT "BidCase_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BidReviewer" ADD CONSTRAINT "BidReviewer_bidCaseId_fkey" FOREIGN KEY ("bidCaseId") REFERENCES "BidCase"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "TodoTask" ADD CONSTRAINT "TodoTask_assigneeId_fkey" FOREIGN KEY ("assigneeId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ApprovalTask" ADD CONSTRAINT "ApprovalTask_assigneeId_fkey" FOREIGN KEY ("assigneeId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Contract" ADD CONSTRAINT "Contract_bidCaseId_fkey" FOREIGN KEY ("bidCaseId") REFERENCES "BidCase"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "PaymentMilestone" ADD CONSTRAINT "PaymentMilestone_contractId_fkey" FOREIGN KEY ("contractId") REFERENCES "Contract"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Project" ADD CONSTRAINT "Project_contractId_fkey" FOREIGN KEY ("contractId") REFERENCES "Contract"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ProjectTask" ADD CONSTRAINT "ProjectTask_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "Timesheet" ADD CONSTRAINT "Timesheet_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ExpenseClaim" ADD CONSTRAINT "ExpenseClaim_bidCaseId_fkey" FOREIGN KEY ("bidCaseId") REFERENCES "BidCase"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "ExpenseClaim" ADD CONSTRAINT "ExpenseClaim_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BondRecord" ADD CONSTRAINT "BondRecord_bidCaseId_fkey" FOREIGN KEY ("bidCaseId") REFERENCES "BidCase"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,34 @@
-- AlterTable
ALTER TABLE "BidCase" ADD COLUMN "fetchedAt" TIMESTAMP(3);
-- AlterTable
ALTER TABLE "BidReviewer" ADD COLUMN "decidedAt" TIMESTAMP(3);
-- CreateTable
CREATE TABLE "BidActionLog" (
"id" TEXT NOT NULL,
"bidCaseId" TEXT NOT NULL,
"actorId" TEXT NOT NULL,
"action" TEXT NOT NULL,
"fromStatus" TEXT,
"toStatus" TEXT,
"comment" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "BidActionLog_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE UNIQUE INDEX "BidReviewer_bidCaseId_userId_stage_key" ON "BidReviewer"("bidCaseId", "userId", "stage");
-- CreateIndex
CREATE INDEX "BidActionLog_bidCaseId_idx" ON "BidActionLog"("bidCaseId");
-- AddForeignKey
ALTER TABLE "BidReviewer" ADD CONSTRAINT "BidReviewer_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BidActionLog" ADD CONSTRAINT "BidActionLog_bidCaseId_fkey" FOREIGN KEY ("bidCaseId") REFERENCES "BidCase"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "BidActionLog" ADD CONSTRAINT "BidActionLog_actorId_fkey" FOREIGN KEY ("actorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
@@ -0,0 +1,50 @@
-- AlterTable
ALTER TABLE "BidCase" ADD COLUMN "reviewCycle" INTEGER NOT NULL DEFAULT 1;
ALTER TABLE "BidCase" ADD COLUMN "printCost" DECIMAL(18,2);
ALTER TABLE "BidCase" ADD COLUMN "printNote" TEXT;
ALTER TABLE "BidCase" ADD COLUMN "printedAt" TIMESTAMP(3);
ALTER TABLE "BidCase" ADD COLUMN "costDisposition" TEXT;
ALTER TABLE "BidCase" ADD COLUMN "resultNote" TEXT;
ALTER TABLE "BidCase" ADD COLUMN "openedResultAt" TIMESTAMP(3);
-- AlterTable
ALTER TABLE "BidReviewer" ADD COLUMN "cycle" INTEGER NOT NULL DEFAULT 1;
DROP INDEX IF EXISTS "BidReviewer_bidCaseId_userId_stage_key";
CREATE UNIQUE INDEX "BidReviewer_bidCaseId_userId_stage_cycle_key" ON "BidReviewer"("bidCaseId", "userId", "stage", "cycle");
-- CreateTable
CREATE TABLE "BidAssignee" (
"id" TEXT NOT NULL,
"bidCaseId" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"role" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "BidAssignee_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "BidAssignee_bidCaseId_userId_role_key" ON "BidAssignee"("bidCaseId", "userId", "role");
CREATE INDEX "BidAssignee_bidCaseId_idx" ON "BidAssignee"("bidCaseId");
ALTER TABLE "BidAssignee" ADD CONSTRAINT "BidAssignee_bidCaseId_fkey" FOREIGN KEY ("bidCaseId") REFERENCES "BidCase"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "BidAssignee" ADD CONSTRAINT "BidAssignee_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- CreateTable
CREATE TABLE "BidDocVersion" (
"id" TEXT NOT NULL,
"bidCaseId" TEXT NOT NULL,
"versionNo" INTEGER NOT NULL,
"nasPath" TEXT NOT NULL,
"note" TEXT,
"submittedById" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "BidDocVersion_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "BidDocVersion_bidCaseId_versionNo_key" ON "BidDocVersion"("bidCaseId", "versionNo");
CREATE INDEX "BidDocVersion_bidCaseId_idx" ON "BidDocVersion"("bidCaseId");
ALTER TABLE "BidDocVersion" ADD CONSTRAINT "BidDocVersion_bidCaseId_fkey" FOREIGN KEY ("bidCaseId") REFERENCES "BidCase"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "BidDocVersion" ADD CONSTRAINT "BidDocVersion_submittedById_fkey" FOREIGN KEY ("submittedById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
@@ -0,0 +1,56 @@
-- AlterTable
ALTER TABLE "Contract" ADD COLUMN "legalEntityId" TEXT;
ALTER TABLE "Contract" ADD COLUMN "nasPath" TEXT;
ALTER TABLE "Contract" ADD COLUMN "remark" TEXT;
ALTER TABLE "Contract" ADD COLUMN "submittedAt" TIMESTAMP(3);
ALTER TABLE "Contract" ADD COLUMN "approvedAt" TIMESTAMP(3);
ALTER TABLE "Contract" ADD COLUMN "createdById" TEXT;
ALTER TABLE "Contract" ADD CONSTRAINT "Contract_legalEntityId_fkey" FOREIGN KEY ("legalEntityId") REFERENCES "LegalEntity"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "Contract" ADD CONSTRAINT "Contract_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AlterTable
ALTER TABLE "SealRequest" ADD COLUMN "contractId" TEXT;
ALTER TABLE "SealRequest" ADD COLUMN "applicantId" TEXT;
ALTER TABLE "SealRequest" ADD CONSTRAINT "SealRequest_contractId_fkey" FOREIGN KEY ("contractId") REFERENCES "Contract"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- AlterTable
ALTER TABLE "Project" ADD COLUMN "presalesCost" DECIMAL(18,2) NOT NULL DEFAULT 0;
-- CreateTable
CREATE TABLE "ContractReviewer" (
"id" TEXT NOT NULL,
"contractId" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"result" TEXT NOT NULL DEFAULT 'PENDING',
"comment" TEXT,
"decidedAt" TIMESTAMP(3),
CONSTRAINT "ContractReviewer_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "ContractReviewer_contractId_userId_key" ON "ContractReviewer"("contractId", "userId");
CREATE INDEX "ContractReviewer_contractId_idx" ON "ContractReviewer"("contractId");
ALTER TABLE "ContractReviewer" ADD CONSTRAINT "ContractReviewer_contractId_fkey" FOREIGN KEY ("contractId") REFERENCES "Contract"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "ContractReviewer" ADD CONSTRAINT "ContractReviewer_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- CreateTable
CREATE TABLE "ContractActionLog" (
"id" TEXT NOT NULL,
"contractId" TEXT NOT NULL,
"actorId" TEXT NOT NULL,
"action" TEXT NOT NULL,
"fromStatus" TEXT,
"toStatus" TEXT,
"comment" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "ContractActionLog_pkey" PRIMARY KEY ("id")
);
CREATE INDEX "ContractActionLog_contractId_idx" ON "ContractActionLog"("contractId");
ALTER TABLE "ContractActionLog" ADD CONSTRAINT "ContractActionLog_contractId_fkey" FOREIGN KEY ("contractId") REFERENCES "Contract"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "ContractActionLog" ADD CONSTRAINT "ContractActionLog_actorId_fkey" FOREIGN KEY ("actorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
@@ -0,0 +1,67 @@
-- ExpenseClaim
ALTER TABLE "ExpenseClaim" ADD COLUMN "loanId" TEXT;
ALTER TABLE "ExpenseClaim" ADD COLUMN "submittedAt" TIMESTAMP(3);
ALTER TABLE "ExpenseClaim" ADD COLUMN "decidedAt" TIMESTAMP(3);
ALTER TABLE "ExpenseClaim" ADD COLUMN "decidedById" TEXT;
ALTER TABLE "ExpenseClaim" ADD COLUMN "rejectComment" TEXT;
ALTER TABLE "ExpenseClaim" ADD CONSTRAINT "ExpenseClaim_applicantId_fkey" FOREIGN KEY ("applicantId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE "ExpenseClaim" ADD CONSTRAINT "ExpenseClaim_decidedById_fkey" FOREIGN KEY ("decidedById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "ExpenseClaim" ADD CONSTRAINT "ExpenseClaim_loanId_fkey" FOREIGN KEY ("loanId") REFERENCES "LoanRecord"("id") ON DELETE SET NULL ON UPDATE CASCADE;
CREATE INDEX "ExpenseClaim_applicantId_idx" ON "ExpenseClaim"("applicantId");
CREATE INDEX "ExpenseClaim_loanId_idx" ON "ExpenseClaim"("loanId");
-- LoanRecord
ALTER TABLE "LoanRecord" ADD COLUMN "loanNo" TEXT;
ALTER TABLE "LoanRecord" ADD COLUMN "costType" TEXT;
ALTER TABLE "LoanRecord" ADD COLUMN "bidCaseId" TEXT;
ALTER TABLE "LoanRecord" ADD COLUMN "projectId" TEXT;
ALTER TABLE "LoanRecord" ADD COLUMN "offsetAmount" DECIMAL(18,2) NOT NULL DEFAULT 0;
ALTER TABLE "LoanRecord" ADD COLUMN "remark" TEXT;
ALTER TABLE "LoanRecord" ADD COLUMN "submittedAt" TIMESTAMP(3);
ALTER TABLE "LoanRecord" ADD COLUMN "decidedAt" TIMESTAMP(3);
ALTER TABLE "LoanRecord" ADD COLUMN "decidedById" TEXT;
UPDATE "LoanRecord" SET "loanNo" = 'JK-LEGACY-' || substr("id", 1, 8) WHERE "loanNo" IS NULL;
UPDATE "LoanRecord" SET "costType" = 'ADMIN' WHERE "costType" IS NULL;
ALTER TABLE "LoanRecord" ALTER COLUMN "loanNo" SET NOT NULL;
ALTER TABLE "LoanRecord" ALTER COLUMN "costType" SET NOT NULL;
ALTER TABLE "LoanRecord" ALTER COLUMN "status" SET DEFAULT 'DRAFT';
CREATE UNIQUE INDEX "LoanRecord_tenantId_loanNo_key" ON "LoanRecord"("tenantId", "loanNo");
CREATE INDEX "LoanRecord_applicantId_idx" ON "LoanRecord"("applicantId");
ALTER TABLE "LoanRecord" ADD CONSTRAINT "LoanRecord_bidCaseId_fkey" FOREIGN KEY ("bidCaseId") REFERENCES "BidCase"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "LoanRecord" ADD CONSTRAINT "LoanRecord_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "LoanRecord" ADD CONSTRAINT "LoanRecord_applicantId_fkey" FOREIGN KEY ("applicantId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE "LoanRecord" ADD CONSTRAINT "LoanRecord_decidedById_fkey" FOREIGN KEY ("decidedById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- BondRecord
ALTER TABLE "BondRecord" ADD COLUMN "bondNo" TEXT;
ALTER TABLE "BondRecord" ADD COLUMN "projectId" TEXT;
ALTER TABLE "BondRecord" ADD COLUMN "contractId" TEXT;
ALTER TABLE "BondRecord" ADD COLUMN "remark" TEXT;
ALTER TABLE "BondRecord" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
UPDATE "BondRecord" SET "bondNo" = 'BZ-LEGACY-' || substr("id", 1, 8) WHERE "bondNo" IS NULL;
ALTER TABLE "BondRecord" ALTER COLUMN "bondNo" SET NOT NULL;
ALTER TABLE "BondRecord" ALTER COLUMN "bidCaseId" DROP NOT NULL;
ALTER TABLE "BondRecord" DROP CONSTRAINT "BondRecord_bidCaseId_fkey";
ALTER TABLE "BondRecord" ADD CONSTRAINT "BondRecord_bidCaseId_fkey" FOREIGN KEY ("bidCaseId") REFERENCES "BidCase"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "BondRecord" ADD CONSTRAINT "BondRecord_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "BondRecord" ADD CONSTRAINT "BondRecord_contractId_fkey" FOREIGN KEY ("contractId") REFERENCES "Contract"("id") ON DELETE SET NULL ON UPDATE CASCADE;
CREATE UNIQUE INDEX "BondRecord_tenantId_bondNo_key" ON "BondRecord"("tenantId", "bondNo");
-- InvoiceRecord
DELETE FROM "InvoiceRecord";
ALTER TABLE "InvoiceRecord" ADD COLUMN "contractId" TEXT NOT NULL;
ALTER TABLE "InvoiceRecord" ADD COLUMN "milestoneId" TEXT NOT NULL;
ALTER TABLE "InvoiceRecord" ADD COLUMN "dueAt" TIMESTAMP(3);
ALTER TABLE "InvoiceRecord" ADD COLUMN "remark" TEXT;
ALTER TABLE "InvoiceRecord" ADD COLUMN "createdById" TEXT;
CREATE UNIQUE INDEX "InvoiceRecord_milestoneId_key" ON "InvoiceRecord"("milestoneId");
ALTER TABLE "InvoiceRecord" ADD CONSTRAINT "InvoiceRecord_contractId_fkey" FOREIGN KEY ("contractId") REFERENCES "Contract"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE "InvoiceRecord" ADD CONSTRAINT "InvoiceRecord_milestoneId_fkey" FOREIGN KEY ("milestoneId") REFERENCES "PaymentMilestone"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE "InvoiceRecord" ADD CONSTRAINT "InvoiceRecord_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
@@ -0,0 +1,57 @@
-- Project hour rate and acceptance timestamps
ALTER TABLE "Project" ADD COLUMN "hourRate" DECIMAL(18,2) NOT NULL DEFAULT 200;
ALTER TABLE "Project" ADD COLUMN "internalAcceptedAt" TIMESTAMP(3);
ALTER TABLE "Project" ADD COLUMN "customerAcceptedAt" TIMESTAMP(3);
-- ProjectTask WBS
ALTER TABLE "ProjectTask" ADD COLUMN "departmentId" TEXT;
ALTER TABLE "ProjectTask" ADD COLUMN "assigneeId" TEXT;
ALTER TABLE "ProjectTask" ADD COLUMN "sortNo" INTEGER NOT NULL DEFAULT 0;
ALTER TABLE "ProjectTask" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
CREATE INDEX "ProjectTask_projectId_idx" ON "ProjectTask"("projectId");
ALTER TABLE "ProjectTask" ADD CONSTRAINT "ProjectTask_departmentId_fkey" FOREIGN KEY ("departmentId") REFERENCES "Department"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "ProjectTask" ADD CONSTRAINT "ProjectTask_assigneeId_fkey" FOREIGN KEY ("assigneeId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- Timesheet
ALTER TABLE "Timesheet" ADD COLUMN "taskId" TEXT;
ALTER TABLE "Timesheet" ADD COLUMN "costAmount" DECIMAL(18,2) NOT NULL DEFAULT 0;
ALTER TABLE "Timesheet" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP;
CREATE INDEX "Timesheet_projectId_idx" ON "Timesheet"("projectId");
CREATE INDEX "Timesheet_userId_idx" ON "Timesheet"("userId");
ALTER TABLE "Timesheet" ADD CONSTRAINT "Timesheet_taskId_fkey" FOREIGN KEY ("taskId") REFERENCES "ProjectTask"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "Timesheet" ADD CONSTRAINT "Timesheet_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- Expense budget category (travel / purchase)
ALTER TABLE "ExpenseClaim" ADD COLUMN "budgetCategory" TEXT;
-- ProjectBudget
CREATE TABLE "ProjectBudget" (
"id" TEXT NOT NULL,
"projectId" TEXT NOT NULL,
"category" TEXT NOT NULL,
"amount" DECIMAL(18,2) NOT NULL,
CONSTRAINT "ProjectBudget_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "ProjectBudget_projectId_category_key" ON "ProjectBudget"("projectId", "category");
ALTER TABLE "ProjectBudget" ADD CONSTRAINT "ProjectBudget_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- ProjectAcceptance
CREATE TABLE "ProjectAcceptance" (
"id" TEXT NOT NULL,
"projectId" TEXT NOT NULL,
"kind" TEXT NOT NULL,
"result" TEXT NOT NULL,
"comment" TEXT,
"actorId" TEXT NOT NULL,
"decidedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "ProjectAcceptance_pkey" PRIMARY KEY ("id")
);
CREATE INDEX "ProjectAcceptance_projectId_idx" ON "ProjectAcceptance"("projectId");
ALTER TABLE "ProjectAcceptance" ADD CONSTRAINT "ProjectAcceptance_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "ProjectAcceptance" ADD CONSTRAINT "ProjectAcceptance_actorId_fkey" FOREIGN KEY ("actorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
@@ -0,0 +1,19 @@
-- SealRequest: actual return and decision
ALTER TABLE "SealRequest" ADD COLUMN "returnedAt" TIMESTAMP(3);
ALTER TABLE "SealRequest" ADD COLUMN "decidedAt" TIMESTAMP(3);
ALTER TABLE "SealRequest" ADD COLUMN "decidedById" TEXT;
ALTER TABLE "SealRequest" ADD COLUMN "rejectComment" TEXT;
ALTER TABLE "SealRequest" ADD CONSTRAINT "SealRequest_bidCaseId_fkey" FOREIGN KEY ("bidCaseId") REFERENCES "BidCase"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "SealRequest" ADD CONSTRAINT "SealRequest_applicantId_fkey" FOREIGN KEY ("applicantId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "SealRequest" ADD CONSTRAINT "SealRequest_decidedById_fkey" FOREIGN KEY ("decidedById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- CredentialBorrow: link to person, qualification, bid
ALTER TABLE "CredentialBorrow" ADD COLUMN "borrowerId" TEXT;
ALTER TABLE "CredentialBorrow" ADD COLUMN "qualificationId" TEXT;
ALTER TABLE "CredentialBorrow" ADD COLUMN "bidCaseId" TEXT;
ALTER TABLE "CredentialBorrow" ADD COLUMN "remark" TEXT;
ALTER TABLE "CredentialBorrow" ADD CONSTRAINT "CredentialBorrow_borrowerId_fkey" FOREIGN KEY ("borrowerId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "CredentialBorrow" ADD CONSTRAINT "CredentialBorrow_qualificationId_fkey" FOREIGN KEY ("qualificationId") REFERENCES "Qualification"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "CredentialBorrow" ADD CONSTRAINT "CredentialBorrow_bidCaseId_fkey" FOREIGN KEY ("bidCaseId") REFERENCES "BidCase"("id") ON DELETE SET NULL ON UPDATE CASCADE;
@@ -0,0 +1,134 @@
-- Employee: salary, reporting line, lifecycle dates, compensatory leave
ALTER TABLE "Employee" ADD COLUMN "internStartAt" TIMESTAMP(3);
ALTER TABLE "Employee" ADD COLUMN "probationEndAt" TIMESTAMP(3);
ALTER TABLE "Employee" ADD COLUMN "leftAt" TIMESTAMP(3);
ALTER TABLE "Employee" ADD COLUMN "managerId" TEXT;
ALTER TABLE "Employee" ADD COLUMN "baseSalary" DECIMAL(18,2) NOT NULL DEFAULT 0;
ALTER TABLE "Employee" ADD COLUMN "perfBase" DECIMAL(18,2) NOT NULL DEFAULT 0;
ALTER TABLE "Employee" ADD COLUMN "socialBase" DECIMAL(18,2) NOT NULL DEFAULT 0;
ALTER TABLE "Employee" ADD COLUMN "compLeaveHours" DECIMAL(10,2) NOT NULL DEFAULT 0;
CREATE INDEX "Employee_departmentId_idx" ON "Employee"("departmentId");
CREATE INDEX "Employee_managerId_idx" ON "Employee"("managerId");
ALTER TABLE "Employee" ADD CONSTRAINT "Employee_managerId_fkey" FOREIGN KEY ("managerId") REFERENCES "Employee"("id") ON DELETE SET NULL ON UPDATE CASCADE;
UPDATE "Employee" SET "baseSalary" = 8000, "perfBase" = 0, "socialBase" = 8000 WHERE "employeeNo" = 'E000';
UPDATE "Employee" SET "baseSalary" = 25000, "perfBase" = 10000, "socialBase" = 20000 WHERE "employeeNo" = 'E001';
UPDATE "Employee" SET "baseSalary" = 18000, "perfBase" = 8000, "socialBase" = 18000 WHERE "employeeNo" = 'E010';
UPDATE "Employee" SET "baseSalary" = 9000, "perfBase" = 2500, "socialBase" = 9000 WHERE "employeeNo" = 'E011';
UPDATE "Employee" SET "baseSalary" = 15000, "perfBase" = 5000, "socialBase" = 15000 WHERE "employeeNo" IN ('E020','E021','E022','E023');
UPDATE "Employee" SET "baseSalary" = 10000, "perfBase" = 2000, "socialBase" = 10000 WHERE "employeeNo" = 'E030';
UPDATE "Employee" SET "baseSalary" = 9000, "perfBase" = 2000, "socialBase" = 9000 WHERE "employeeNo" = 'E040';
UPDATE "Employee" SET "baseSalary" = 10000, "perfBase" = 3000, "socialBase" = 10000 WHERE "employeeNo" = 'E100';
UPDATE "Employee" AS e
SET "managerId" = d.id
FROM "Employee" AS d
WHERE e."employeeNo" = 'E100' AND d."employeeNo" = 'E023';
-- CreateTable
CREATE TABLE "EmploymentEvent" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"employeeId" TEXT NOT NULL,
"kind" TEXT NOT NULL,
"fromStatus" TEXT,
"toStatus" TEXT,
"fromDeptId" TEXT,
"toDeptId" TEXT,
"effectiveAt" TIMESTAMP(3) NOT NULL,
"comment" TEXT,
"actorId" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "EmploymentEvent_pkey" PRIMARY KEY ("id")
);
CREATE INDEX "EmploymentEvent_employeeId_idx" ON "EmploymentEvent"("employeeId");
CREATE INDEX "EmploymentEvent_effectiveAt_idx" ON "EmploymentEvent"("effectiveAt");
ALTER TABLE "EmploymentEvent" ADD CONSTRAINT "EmploymentEvent_employeeId_fkey" FOREIGN KEY ("employeeId") REFERENCES "Employee"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE "EmploymentEvent" ADD CONSTRAINT "EmploymentEvent_fromDeptId_fkey" FOREIGN KEY ("fromDeptId") REFERENCES "Department"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "EmploymentEvent" ADD CONSTRAINT "EmploymentEvent_toDeptId_fkey" FOREIGN KEY ("toDeptId") REFERENCES "Department"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "EmploymentEvent" ADD CONSTRAINT "EmploymentEvent_actorId_fkey" FOREIGN KEY ("actorId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- CreateTable
CREATE TABLE "AttendanceMonth" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"employeeId" TEXT NOT NULL,
"yearMonth" TEXT NOT NULL,
"workDays" DECIMAL(6,2) NOT NULL DEFAULT 0,
"leaveDays" DECIMAL(6,2) NOT NULL DEFAULT 0,
"sickDays" DECIMAL(6,2) NOT NULL DEFAULT 0,
"overtimeHours" DECIMAL(6,2) NOT NULL DEFAULT 0,
"compLeaveDays" DECIMAL(6,2) NOT NULL DEFAULT 0,
"remark" TEXT,
"importedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"importedById" TEXT,
CONSTRAINT "AttendanceMonth_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "AttendanceMonth_employeeId_yearMonth_key" ON "AttendanceMonth"("employeeId", "yearMonth");
CREATE INDEX "AttendanceMonth_yearMonth_idx" ON "AttendanceMonth"("yearMonth");
ALTER TABLE "AttendanceMonth" ADD CONSTRAINT "AttendanceMonth_employeeId_fkey" FOREIGN KEY ("employeeId") REFERENCES "Employee"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE "AttendanceMonth" ADD CONSTRAINT "AttendanceMonth_importedById_fkey" FOREIGN KEY ("importedById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- CreateTable
CREATE TABLE "PayrollRun" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"yearMonth" TEXT NOT NULL,
"status" TEXT NOT NULL DEFAULT 'DRAFT',
"createdById" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"confirmedAt" TIMESTAMP(3),
CONSTRAINT "PayrollRun_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "PayrollRun_tenantId_yearMonth_key" ON "PayrollRun"("tenantId", "yearMonth");
ALTER TABLE "PayrollRun" ADD CONSTRAINT "PayrollRun_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- CreateTable
CREATE TABLE "PayrollItem" (
"id" TEXT NOT NULL,
"runId" TEXT NOT NULL,
"employeeId" TEXT NOT NULL,
"prorationFactor" DECIMAL(8,6) NOT NULL DEFAULT 1,
"scheduledDays" DECIMAL(6,2) NOT NULL DEFAULT 0,
"dailyRate" DECIMAL(18,2) NOT NULL DEFAULT 0,
"basePay" DECIMAL(18,2) NOT NULL DEFAULT 0,
"performancePay" DECIMAL(18,2) NOT NULL DEFAULT 0,
"performanceRatio" DECIMAL(5,2) NOT NULL DEFAULT 100,
"leaveDeduct" DECIMAL(18,2) NOT NULL DEFAULT 0,
"sickDeduct" DECIMAL(18,2) NOT NULL DEFAULT 0,
"socialPersonal" DECIMAL(18,2) NOT NULL DEFAULT 0,
"housingFund" DECIMAL(18,2) NOT NULL DEFAULT 0,
"tax" DECIMAL(18,2) NOT NULL DEFAULT 0,
"grossPay" DECIMAL(18,2) NOT NULL DEFAULT 0,
"netPay" DECIMAL(18,2) NOT NULL DEFAULT 0,
"overtimeHours" DECIMAL(6,2) NOT NULL DEFAULT 0,
"compLeaveUsedDays" DECIMAL(6,2) NOT NULL DEFAULT 0,
"compLeaveHours" DECIMAL(10,2) NOT NULL DEFAULT 0,
CONSTRAINT "PayrollItem_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "PayrollItem_runId_employeeId_key" ON "PayrollItem"("runId", "employeeId");
ALTER TABLE "PayrollItem" ADD CONSTRAINT "PayrollItem_runId_fkey" FOREIGN KEY ("runId") REFERENCES "PayrollRun"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "PayrollItem" ADD CONSTRAINT "PayrollItem_employeeId_fkey" FOREIGN KEY ("employeeId") REFERENCES "Employee"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
-- Directors only see 绩效发放 under 组织人事, not the full HR module
INSERT INTO "RolePermission" ("roleId", "permissionId")
SELECT r.id, p.id
FROM "Role" r
CROSS JOIN "Permission" p
WHERE r.code IN ('tech_director', 'biz_director')
AND p.code = 'hr:performance'
ON CONFLICT DO NOTHING;
@@ -0,0 +1,98 @@
ALTER TABLE "Role" ADD COLUMN "dataScope" TEXT NOT NULL DEFAULT 'ALL';
ALTER TABLE "WorkReport" ADD COLUMN "periodType" TEXT NOT NULL DEFAULT 'DAY';
ALTER TABLE "WorkReport" ADD COLUMN "periodStart" TIMESTAMP(3);
ALTER TABLE "WorkReport" ADD COLUMN "hours" DECIMAL(8,2) NOT NULL DEFAULT 0;
DELETE FROM "WorkReport" WHERE "authorId" IS NOT NULL AND "authorId" NOT IN (SELECT "id" FROM "User");
ALTER TABLE "WorkReport" ADD CONSTRAINT "WorkReport_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
CREATE INDEX "WorkReport_authorId_idx" ON "WorkReport"("authorId");
ALTER TABLE "PurchaseRequest" ADD COLUMN "remark" TEXT;
ALTER TABLE "PurchaseRequest" ADD COLUMN "applicantId" TEXT;
ALTER TABLE "PurchaseRequest" ADD COLUMN "decidedById" TEXT;
ALTER TABLE "PurchaseRequest" ADD COLUMN "decidedAt" TIMESTAMP(3);
UPDATE "PurchaseRequest" SET "projectId" = NULL WHERE "projectId" IS NOT NULL AND "projectId" NOT IN (SELECT "id" FROM "Project");
ALTER TABLE "PurchaseRequest" ADD CONSTRAINT "PurchaseRequest_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "PurchaseRequest" ADD CONSTRAINT "PurchaseRequest_applicantId_fkey" FOREIGN KEY ("applicantId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "PurchaseRequest" ADD CONSTRAINT "PurchaseRequest_decidedById_fkey" FOREIGN KEY ("decidedById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "AssetOccupancy" ADD COLUMN "holderId" TEXT;
ALTER TABLE "AssetOccupancy" ADD COLUMN "projectId" TEXT;
ALTER TABLE "AssetOccupancy" ADD COLUMN "dueAt" TIMESTAMP(3);
ALTER TABLE "AssetOccupancy" ADD COLUMN "returnedAt" TIMESTAMP(3);
UPDATE "AssetOccupancy" SET "projectId" = NULL WHERE "projectId" IS NOT NULL AND "projectId" NOT IN (SELECT "id" FROM "Project");
ALTER TABLE "AssetOccupancy" ADD CONSTRAINT "AssetOccupancy_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "AssetOccupancy" ADD CONSTRAINT "AssetOccupancy_holderId_fkey" FOREIGN KEY ("holderId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "OperationLog" ADD COLUMN "username" TEXT;
ALTER TABLE "OperationLog" ADD COLUMN "detail" TEXT;
ALTER TABLE "OperationLog" ADD COLUMN "success" BOOLEAN NOT NULL DEFAULT true;
UPDATE "OperationLog" SET "userId" = NULL WHERE "userId" IS NOT NULL AND "userId" NOT IN (SELECT "id" FROM "User");
ALTER TABLE "OperationLog" ADD CONSTRAINT "OperationLog_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
CREATE INDEX "OperationLog_createdAt_idx" ON "OperationLog"("createdAt");
CREATE INDEX "OperationLog_action_idx" ON "OperationLog"("action");
CREATE TABLE "NumberRule" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"code" TEXT NOT NULL,
"name" TEXT NOT NULL,
"prefix" TEXT NOT NULL,
"padLength" INTEGER NOT NULL DEFAULT 5,
CONSTRAINT "NumberRule_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "NumberRule_tenantId_code_key" ON "NumberRule"("tenantId", "code");
INSERT INTO "NumberRule" ("id", "code", "name", "prefix", "padLength") VALUES
('nr-bid', 'BID', '投标编号', 'BID', 5),
('nr-ht', 'HT', '合同编号', 'HT', 5),
('nr-prj', 'PRJ', '项目编号', 'PRJ', 5);
CREATE TABLE "SealItem" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"name" TEXT NOT NULL,
"keeper" TEXT NOT NULL DEFAULT '行政',
"status" TEXT NOT NULL DEFAULT 'IN_STOCK',
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "SealItem_pkey" PRIMARY KEY ("id")
);
INSERT INTO "SealItem" ("id", "name", "keeper", "status") VALUES
('seal-official', '公章', '行政', 'IN_STOCK'),
('seal-legal', '法人章', '行政', 'IN_STOCK');
CREATE TABLE "ProjectChange" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"projectId" TEXT NOT NULL,
"summary" TEXT NOT NULL,
"amountDelta" DECIMAL(18,2) NOT NULL DEFAULT 0,
"status" TEXT NOT NULL DEFAULT 'PENDING',
"comment" TEXT,
"actorId" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"decidedAt" TIMESTAMP(3),
CONSTRAINT "ProjectChange_pkey" PRIMARY KEY ("id")
);
CREATE INDEX "ProjectChange_projectId_idx" ON "ProjectChange"("projectId");
ALTER TABLE "ProjectChange" ADD CONSTRAINT "ProjectChange_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
ALTER TABLE "ProjectChange" ADD CONSTRAINT "ProjectChange_actorId_fkey" FOREIGN KEY ("actorId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
CREATE TABLE "PaymentRecord" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"payNo" TEXT NOT NULL,
"kind" TEXT NOT NULL,
"refId" TEXT,
"amount" DECIMAL(18,2) NOT NULL,
"status" TEXT NOT NULL DEFAULT 'TODO',
"remark" TEXT,
"paidAt" TIMESTAMP(3),
"createdById" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "PaymentRecord_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "PaymentRecord_tenantId_payNo_key" ON "PaymentRecord"("tenantId", "payNo");
ALTER TABLE "PaymentRecord" ADD CONSTRAINT "PaymentRecord_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
@@ -0,0 +1,13 @@
ALTER TABLE "WorkReport" ADD COLUMN "toUserId" TEXT;
ALTER TABLE "WorkReport" ADD COLUMN "ccUserId" TEXT;
ALTER TABLE "WorkReport" ADD COLUMN "status" TEXT NOT NULL DEFAULT 'DRAFT';
ALTER TABLE "WorkReport" ADD COLUMN "submittedAt" TIMESTAMP(3);
ALTER TABLE "WorkReport" ALTER COLUMN "content" SET DEFAULT '';
UPDATE "WorkReport" SET "toUserId" = NULL WHERE "toUserId" IS NOT NULL AND "toUserId" NOT IN (SELECT "id" FROM "User");
UPDATE "WorkReport" SET "ccUserId" = NULL WHERE "ccUserId" IS NOT NULL AND "ccUserId" NOT IN (SELECT "id" FROM "User");
ALTER TABLE "WorkReport" ADD CONSTRAINT "WorkReport_toUserId_fkey" FOREIGN KEY ("toUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "WorkReport" ADD CONSTRAINT "WorkReport_ccUserId_fkey" FOREIGN KEY ("ccUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
CREATE INDEX "WorkReport_toUserId_idx" ON "WorkReport"("toUserId");
CREATE INDEX "WorkReport_ccUserId_idx" ON "WorkReport"("ccUserId");
@@ -0,0 +1,29 @@
ALTER TABLE "ExpenseClaim" ADD COLUMN IF NOT EXISTS "expenseCategory" TEXT;
CREATE TABLE IF NOT EXISTS "FileAsset" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"bizType" TEXT NOT NULL,
"bizId" TEXT NOT NULL,
"fileName" TEXT NOT NULL,
"mimeType" TEXT NOT NULL,
"size" INTEGER NOT NULL,
"storageKey" TEXT NOT NULL,
"uploadedById" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "FileAsset_pkey" PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "FileAsset_bizType_bizId_idx" ON "FileAsset"("bizType", "bizId");
CREATE INDEX IF NOT EXISTS "FileAsset_uploadedById_idx" ON "FileAsset"("uploadedById");
INSERT INTO "DictItem" ("id", "tenantId", "dictType", "label", "value", "sortNo")
VALUES
('e1c10000-0000-4000-8000-000000000001', '1', 'expenseCategory', '交通', '交通', 1),
('e1c10000-0000-4000-8000-000000000002', '1', 'expenseCategory', '餐饮', '餐饮', 2),
('e1c10000-0000-4000-8000-000000000003', '1', 'expenseCategory', '住宿', '住宿', 3),
('e1c10000-0000-4000-8000-000000000004', '1', 'expenseCategory', '办公', '办公', 4),
('e1c10000-0000-4000-8000-000000000005', '1', 'expenseCategory', '招待', '招待', 5),
('e1c10000-0000-4000-8000-000000000006', '1', 'expenseCategory', '其他', '其他', 6)
ON CONFLICT ("tenantId", "dictType", "value") DO NOTHING;
@@ -0,0 +1,19 @@
-- CreateTable
CREATE TABLE "SmsSendLog" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"phones" TEXT NOT NULL,
"signName" TEXT NOT NULL,
"templateCode" TEXT NOT NULL,
"templateParam" TEXT,
"bizId" TEXT,
"code" TEXT NOT NULL,
"message" TEXT,
"createdById" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "SmsSendLog_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "SmsSendLog_createdAt_idx" ON "SmsSendLog"("createdAt");
@@ -0,0 +1,67 @@
-- Employee archive fields aligned with personnel files
ALTER TABLE "Employee" ADD COLUMN "gender" TEXT;
ALTER TABLE "Employee" ADD COLUMN "email" TEXT;
ALTER TABLE "Employee" ADD COLUMN "mobile" TEXT;
ALTER TABLE "Employee" ADD COLUMN "idNo" TEXT;
ALTER TABLE "Employee" ADD COLUMN "education" TEXT;
ALTER TABLE "Employee" ADD COLUMN "bankName" TEXT;
ALTER TABLE "Employee" ADD COLUMN "bankAccount" TEXT;
ALTER TABLE "Employee" ADD COLUMN "remark" TEXT;
CREATE TABLE "HrSetting" (
"id" TEXT NOT NULL DEFAULT 'default',
"tenantId" TEXT NOT NULL DEFAULT '1',
"idMask" BOOLEAN NOT NULL DEFAULT true,
"autoAccount" BOOLEAN NOT NULL DEFAULT false,
"probationMonths" INTEGER NOT NULL DEFAULT 3,
"defaultRest" TEXT NOT NULL DEFAULT 'SINGLE',
"workStart" TEXT NOT NULL DEFAULT '09:00',
"workEnd" TEXT NOT NULL DEFAULT '18:00',
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "HrSetting_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "HrSetting_tenantId_key" ON "HrSetting"("tenantId");
INSERT INTO "HrSetting" ("id", "tenantId", "idMask", "autoAccount", "probationMonths", "defaultRest", "workStart", "workEnd", "updatedAt")
VALUES ('default', '1', true, false, 3, 'SINGLE', '09:00', '18:00', CURRENT_TIMESTAMP);
CREATE TABLE "AttendanceRule" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"name" TEXT NOT NULL,
"restSchedule" TEXT NOT NULL,
"workStart" TEXT NOT NULL,
"workEnd" TEXT NOT NULL,
"lateGraceMinutes" INTEGER NOT NULL DEFAULT 0,
"enabled" BOOLEAN NOT NULL DEFAULT true,
"sortNo" INTEGER NOT NULL DEFAULT 0,
"remark" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "AttendanceRule_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX "AttendanceRule_tenantId_name_key" ON "AttendanceRule"("tenantId", "name");
INSERT INTO "AttendanceRule" ("id", "tenantId", "name", "restSchedule", "workStart", "workEnd", "lateGraceMinutes", "enabled", "sortNo", "remark", "createdAt", "updatedAt")
VALUES
('att-rule-single-000000000001', '1', '单休班次', 'SINGLE', '09:00', '18:00', 0, true, 1, '每周休一天,薪酬按 26.09 天核算', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP),
('att-rule-double-000000000001', '1', '双休班次', 'DOUBLE', '09:00', '18:00', 0, true, 2, '每周休两天,薪酬按 21.75 天核算', CURRENT_TIMESTAMP, CURRENT_TIMESTAMP);
INSERT INTO "DictItem" ("id", "tenantId", "dictType", "label", "value", "sortNo")
SELECT d."id", '1', d."dictType", d."label", d."value", d."sortNo"
FROM (VALUES
('dict-gender-male-00000000001', 'gender', '男', 'MALE', 1),
('dict-gender-female-000000001', 'gender', '女', 'FEMALE', 2),
('dict-edu-high-0000000000001', 'education', '高中及以下', 'HIGH_SCHOOL', 1),
('dict-edu-college-00000000001', 'education', '专科', 'COLLEGE', 2),
('dict-edu-bachelor-0000000001', 'education', '本科', 'BACHELOR', 3),
('dict-edu-master-000000000001', 'education', '硕士', 'MASTER', 4),
('dict-edu-doctor-000000000001', 'education', '博士', 'DOCTOR', 5)
) AS d("id", "dictType", "label", "value", "sortNo")
WHERE NOT EXISTS (
SELECT 1 FROM "DictItem" x WHERE x."tenantId" = '1' AND x."dictType" = d."dictType" AND x."value" = d."value"
);
@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "Contract" ADD COLUMN "partyA" TEXT;
ALTER TABLE "Contract" ADD COLUMN "partyB" TEXT;
@@ -0,0 +1,48 @@
-- CreateTable
CREATE TABLE "AttendancePunch" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"employeeId" TEXT NOT NULL,
"kind" TEXT NOT NULL,
"punchedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"remark" TEXT,
CONSTRAINT "AttendancePunch_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE "LeaveRequest" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"employeeId" TEXT NOT NULL,
"kind" TEXT NOT NULL,
"startAt" TIMESTAMP(3) NOT NULL,
"endAt" TIMESTAMP(3) NOT NULL,
"days" DECIMAL(6,2) NOT NULL,
"reason" TEXT NOT NULL,
"status" TEXT NOT NULL DEFAULT 'PENDING',
"comment" TEXT,
"decidedById" TEXT,
"decidedAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "LeaveRequest_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "AttendancePunch_employeeId_punchedAt_idx" ON "AttendancePunch"("employeeId", "punchedAt");
-- CreateIndex
CREATE INDEX "LeaveRequest_employeeId_idx" ON "LeaveRequest"("employeeId");
-- CreateIndex
CREATE INDEX "LeaveRequest_status_idx" ON "LeaveRequest"("status");
-- AddForeignKey
ALTER TABLE "AttendancePunch" ADD CONSTRAINT "AttendancePunch_employeeId_fkey" FOREIGN KEY ("employeeId") REFERENCES "Employee"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "LeaveRequest" ADD CONSTRAINT "LeaveRequest_employeeId_fkey" FOREIGN KEY ("employeeId") REFERENCES "Employee"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "LeaveRequest" ADD CONSTRAINT "LeaveRequest_decidedById_fkey" FOREIGN KEY ("decidedById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
@@ -0,0 +1,27 @@
-- CreateTable
CREATE TABLE "LaborContract" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"employeeId" TEXT NOT NULL,
"contractNo" TEXT,
"startAt" TIMESTAMP(3),
"endAt" TIMESTAMP(3),
"remark" TEXT,
"createdById" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "LaborContract_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "LaborContract_employeeId_idx" ON "LaborContract"("employeeId");
-- CreateIndex
CREATE INDEX "LaborContract_tenantId_createdAt_idx" ON "LaborContract"("tenantId", "createdAt");
-- AddForeignKey
ALTER TABLE "LaborContract" ADD CONSTRAINT "LaborContract_employeeId_fkey" FOREIGN KEY ("employeeId") REFERENCES "Employee"("id") ON DELETE CASCADE ON UPDATE CASCADE;
-- AddForeignKey
ALTER TABLE "LaborContract" ADD CONSTRAINT "LaborContract_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
@@ -0,0 +1,70 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "mustChangePassword" BOOLEAN NOT NULL DEFAULT true;
ALTER TABLE "User" ADD COLUMN IF NOT EXISTS "profileCompletedAt" TIMESTAMP(3);
-- AlterTable
ALTER TABLE "Contract" ADD COLUMN IF NOT EXISTS "kind" TEXT NOT NULL DEFAULT 'OTHER';
UPDATE "Contract" SET "kind" = 'TENDER' WHERE "bidCaseId" IS NOT NULL;
-- AlterTable
ALTER TABLE "BidCase" ADD COLUMN IF NOT EXISTS "needSurvey" BOOLEAN NOT NULL DEFAULT false;
-- AlterTable
ALTER TABLE "SealItem" ADD COLUMN IF NOT EXISTS "sealType" TEXT NOT NULL DEFAULT '公章';
ALTER TABLE "SealItem" ADD COLUMN IF NOT EXISTS "legalEntityId" TEXT;
-- CreateTable
CREATE TABLE IF NOT EXISTS "WorkAssignment" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"title" TEXT NOT NULL,
"content" TEXT NOT NULL DEFAULT '',
"assigneeId" TEXT NOT NULL,
"dueAt" TIMESTAMP(3),
"status" TEXT NOT NULL DEFAULT 'OPEN',
"createdById" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "WorkAssignment_pkey" PRIMARY KEY ("id")
);
-- CreateTable
CREATE TABLE IF NOT EXISTS "RegisteredAsset" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"kind" TEXT NOT NULL,
"name" TEXT NOT NULL,
"code" TEXT,
"spec" TEXT,
"keeper" TEXT,
"location" TEXT,
"amount" DECIMAL(18,2),
"remark" TEXT,
"legalEntityId" TEXT,
"createdById" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "RegisteredAsset_pkey" PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "WorkAssignment_assigneeId_idx" ON "WorkAssignment"("assigneeId");
CREATE INDEX IF NOT EXISTS "WorkAssignment_createdById_idx" ON "WorkAssignment"("createdById");
CREATE INDEX IF NOT EXISTS "RegisteredAsset_kind_idx" ON "RegisteredAsset"("kind");
CREATE INDEX IF NOT EXISTS "RegisteredAsset_legalEntityId_idx" ON "RegisteredAsset"("legalEntityId");
ALTER TABLE "WorkAssignment" DROP CONSTRAINT IF EXISTS "WorkAssignment_assigneeId_fkey";
ALTER TABLE "WorkAssignment" ADD CONSTRAINT "WorkAssignment_assigneeId_fkey" FOREIGN KEY ("assigneeId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE "WorkAssignment" DROP CONSTRAINT IF EXISTS "WorkAssignment_createdById_fkey";
ALTER TABLE "WorkAssignment" ADD CONSTRAINT "WorkAssignment_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE "RegisteredAsset" DROP CONSTRAINT IF EXISTS "RegisteredAsset_legalEntityId_fkey";
ALTER TABLE "RegisteredAsset" ADD CONSTRAINT "RegisteredAsset_legalEntityId_fkey" FOREIGN KEY ("legalEntityId") REFERENCES "LegalEntity"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "RegisteredAsset" DROP CONSTRAINT IF EXISTS "RegisteredAsset_createdById_fkey";
ALTER TABLE "RegisteredAsset" ADD CONSTRAINT "RegisteredAsset_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "SealItem" DROP CONSTRAINT IF EXISTS "SealItem_legalEntityId_fkey";
ALTER TABLE "SealItem" ADD CONSTRAINT "SealItem_legalEntityId_fkey" FOREIGN KEY ("legalEntityId") REFERENCES "LegalEntity"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- 系统管理员不强制改密/补档
UPDATE "User" u SET "mustChangePassword" = false, "profileCompletedAt" = CURRENT_TIMESTAMP
WHERE EXISTS (SELECT 1 FROM "UserRole" ur JOIN "Role" r ON r.id = ur."roleId" WHERE ur."userId" = u.id AND r.code = 'admin');
@@ -0,0 +1 @@
ALTER TABLE "Project" ADD COLUMN IF NOT EXISTS "partyName" TEXT;
@@ -0,0 +1,16 @@
CREATE TABLE IF NOT EXISTS "ProjectAcceptMaterial" (
"id" TEXT NOT NULL,
"projectId" TEXT NOT NULL,
"name" TEXT NOT NULL,
"remark" TEXT,
"required" BOOLEAN NOT NULL DEFAULT true,
"sortNo" INTEGER NOT NULL DEFAULT 0,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "ProjectAcceptMaterial_pkey" PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "ProjectAcceptMaterial_projectId_idx" ON "ProjectAcceptMaterial"("projectId");
ALTER TABLE "ProjectAcceptMaterial" DROP CONSTRAINT IF EXISTS "ProjectAcceptMaterial_projectId_fkey";
ALTER TABLE "ProjectAcceptMaterial" ADD CONSTRAINT "ProjectAcceptMaterial_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,51 @@
-- AlterTable
ALTER TABLE "AssetOccupancy" ADD COLUMN IF NOT EXISTS "registeredAssetId" TEXT;
CREATE INDEX IF NOT EXISTS "AssetOccupancy_registeredAssetId_idx" ON "AssetOccupancy"("registeredAssetId");
ALTER TABLE "AssetOccupancy" DROP CONSTRAINT IF EXISTS "AssetOccupancy_registeredAssetId_fkey";
ALTER TABLE "AssetOccupancy" ADD CONSTRAINT "AssetOccupancy_registeredAssetId_fkey" FOREIGN KEY ("registeredAssetId") REFERENCES "RegisteredAsset"("id") ON DELETE SET NULL ON UPDATE CASCADE;
-- CreateTable
CREATE TABLE IF NOT EXISTS "OfficeApply" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"kind" TEXT NOT NULL,
"title" TEXT NOT NULL,
"reason" TEXT,
"status" TEXT NOT NULL DEFAULT 'PENDING',
"assetKind" TEXT,
"registeredAssetId" TEXT,
"amount" DECIMAL(18,2),
"destination" TEXT,
"startAt" TIMESTAMP(3),
"endAt" TIMESTAMP(3),
"projectId" TEXT,
"purchaseId" TEXT,
"occupancyId" TEXT,
"applicantId" TEXT NOT NULL,
"decidedById" TEXT,
"decidedAt" TIMESTAMP(3),
"remark" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "OfficeApply_pkey" PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "OfficeApply_applicantId_idx" ON "OfficeApply"("applicantId");
CREATE INDEX IF NOT EXISTS "OfficeApply_status_idx" ON "OfficeApply"("status");
CREATE INDEX IF NOT EXISTS "OfficeApply_kind_idx" ON "OfficeApply"("kind");
ALTER TABLE "OfficeApply" DROP CONSTRAINT IF EXISTS "OfficeApply_applicantId_fkey";
ALTER TABLE "OfficeApply" ADD CONSTRAINT "OfficeApply_applicantId_fkey" FOREIGN KEY ("applicantId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
ALTER TABLE "OfficeApply" DROP CONSTRAINT IF EXISTS "OfficeApply_decidedById_fkey";
ALTER TABLE "OfficeApply" ADD CONSTRAINT "OfficeApply_decidedById_fkey" FOREIGN KEY ("decidedById") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "OfficeApply" DROP CONSTRAINT IF EXISTS "OfficeApply_registeredAssetId_fkey";
ALTER TABLE "OfficeApply" ADD CONSTRAINT "OfficeApply_registeredAssetId_fkey" FOREIGN KEY ("registeredAssetId") REFERENCES "RegisteredAsset"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "OfficeApply" DROP CONSTRAINT IF EXISTS "OfficeApply_projectId_fkey";
ALTER TABLE "OfficeApply" ADD CONSTRAINT "OfficeApply_projectId_fkey" FOREIGN KEY ("projectId") REFERENCES "Project"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "OfficeApply" DROP CONSTRAINT IF EXISTS "OfficeApply_purchaseId_fkey";
ALTER TABLE "OfficeApply" ADD CONSTRAINT "OfficeApply_purchaseId_fkey" FOREIGN KEY ("purchaseId") REFERENCES "PurchaseRequest"("id") ON DELETE SET NULL ON UPDATE CASCADE;
ALTER TABLE "OfficeApply" DROP CONSTRAINT IF EXISTS "OfficeApply_occupancyId_fkey";
ALTER TABLE "OfficeApply" ADD CONSTRAINT "OfficeApply_occupancyId_fkey" FOREIGN KEY ("occupancyId") REFERENCES "AssetOccupancy"("id") ON DELETE SET NULL ON UPDATE CASCADE;
@@ -0,0 +1,24 @@
ALTER TABLE "RegisteredAsset" ADD COLUMN IF NOT EXISTS "status" TEXT NOT NULL DEFAULT 'ACTIVE';
ALTER TABLE "RegisteredAsset" ADD COLUMN IF NOT EXISTS "usage" TEXT NOT NULL DEFAULT 'GENERAL';
ALTER TABLE "OfficeApply" ADD COLUMN IF NOT EXISTS "inboundAssetId" TEXT;
ALTER TABLE "OfficeApply" DROP CONSTRAINT IF EXISTS "OfficeApply_inboundAssetId_fkey";
ALTER TABLE "OfficeApply" ADD CONSTRAINT "OfficeApply_inboundAssetId_fkey" FOREIGN KEY ("inboundAssetId") REFERENCES "RegisteredAsset"("id") ON DELETE SET NULL ON UPDATE CASCADE;
CREATE TABLE IF NOT EXISTS "Notice" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"title" TEXT NOT NULL,
"content" TEXT NOT NULL,
"status" TEXT NOT NULL DEFAULT 'PUBLISHED',
"createdById" TEXT NOT NULL,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "Notice_pkey" PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "Notice_status_idx" ON "Notice"("status");
CREATE INDEX IF NOT EXISTS "Notice_createdAt_idx" ON "Notice"("createdAt");
ALTER TABLE "Notice" DROP CONSTRAINT IF EXISTS "Notice_createdById_fkey";
ALTER TABLE "Notice" ADD CONSTRAINT "Notice_createdById_fkey" FOREIGN KEY ("createdById") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
@@ -0,0 +1,29 @@
ALTER TABLE "Notice" ADD COLUMN IF NOT EXISTS "kind" TEXT NOT NULL DEFAULT 'ANNOUNCEMENT';
CREATE INDEX IF NOT EXISTS "Notice_kind_idx" ON "Notice"("kind");
ALTER TABLE "SmsSendLog" ADD COLUMN IF NOT EXISTS "eventKey" TEXT;
CREATE INDEX IF NOT EXISTS "SmsSendLog_eventKey_idx" ON "SmsSendLog"("eventKey");
CREATE TABLE IF NOT EXISTS "SmsEventBind" (
"id" TEXT NOT NULL,
"tenantId" TEXT NOT NULL DEFAULT '1',
"eventKey" TEXT NOT NULL,
"enabled" BOOLEAN NOT NULL DEFAULT true,
"templateCode" TEXT NOT NULL DEFAULT '',
"signName" TEXT,
"updatedAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "SmsEventBind_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX IF NOT EXISTS "SmsEventBind_eventKey_key" ON "SmsEventBind"("eventKey");
CREATE TABLE IF NOT EXISTS "SmsOtp" (
"id" TEXT NOT NULL,
"phone" TEXT NOT NULL,
"codeHash" TEXT NOT NULL,
"purpose" TEXT NOT NULL,
"expiresAt" TIMESTAMP(3) NOT NULL,
"usedAt" TIMESTAMP(3),
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
CONSTRAINT "SmsOtp_pkey" PRIMARY KEY ("id")
);
CREATE INDEX IF NOT EXISTS "SmsOtp_phone_purpose_idx" ON "SmsOtp"("phone", "purpose");
@@ -0,0 +1,2 @@
ALTER TABLE "Project" ADD COLUMN IF NOT EXISTS "projectType" TEXT NOT NULL DEFAULT '';
ALTER TABLE "Project" ADD COLUMN IF NOT EXISTS "amount" DECIMAL(18,2) NOT NULL DEFAULT 0;
@@ -0,0 +1,3 @@
ALTER TABLE "Notice" ADD COLUMN IF NOT EXISTS "audience" TEXT NOT NULL DEFAULT 'ALL';
ALTER TABLE "Notice" ADD COLUMN IF NOT EXISTS "departmentIds" TEXT[] NOT NULL DEFAULT ARRAY[]::TEXT[];
ALTER TABLE "Notice" ADD COLUMN IF NOT EXISTS "userIds" TEXT[] NOT NULL DEFAULT ARRAY[]::TEXT[];
@@ -0,0 +1 @@
ALTER TABLE "Role" ADD COLUMN IF NOT EXISTS "aclCustom" BOOLEAN NOT NULL DEFAULT false;
@@ -0,0 +1,17 @@
CREATE TABLE IF NOT EXISTS "PushDevice" (
"id" TEXT NOT NULL,
"userId" TEXT NOT NULL,
"vendor" TEXT NOT NULL,
"regId" TEXT NOT NULL,
"brand" TEXT,
"model" TEXT,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "PushDevice_pkey" PRIMARY KEY ("id")
);
CREATE UNIQUE INDEX IF NOT EXISTS "PushDevice_vendor_regId_key" ON "PushDevice"("vendor", "regId");
CREATE INDEX IF NOT EXISTS "PushDevice_userId_vendor_idx" ON "PushDevice"("userId", "vendor");
ALTER TABLE "PushDevice" ADD CONSTRAINT "PushDevice_userId_fkey"
FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
@@ -0,0 +1,3 @@
ALTER TABLE "ImMessage" ADD COLUMN IF NOT EXISTS "recalledAt" TIMESTAMP(3);
ALTER TABLE "ImMessage" ADD COLUMN IF NOT EXISTS "editedAt" TIMESTAMP(3);
CREATE INDEX IF NOT EXISTS "ImMessage_recalledAt_idx" ON "ImMessage"("recalledAt");
@@ -0,0 +1,3 @@
-- 项目筛选编号是人工填写的公告编号,不是系统单号;允许重复公告/分包再次筛选。
DROP INDEX IF EXISTS "BidCase_tenantId_bidNo_key";
CREATE INDEX IF NOT EXISTS "BidCase_tenantId_bidNo_idx" ON "BidCase"("tenantId", "bidNo");
@@ -0,0 +1,26 @@
-- Phase 1.1: 会话级单调递增 seq,用于消息排序、去重与断线补拉
ALTER TABLE "ImConversation" ADD COLUMN IF NOT EXISTS "nextSeq" INTEGER NOT NULL DEFAULT 1;
ALTER TABLE "ImMessage" ADD COLUMN IF NOT EXISTS "seq" INTEGER NOT NULL DEFAULT 0;
ALTER TABLE "ImReadCursor" ADD COLUMN IF NOT EXISTS "lastReadSeq" INTEGER NOT NULL DEFAULT 0;
-- 按 createdAt 回填历史 seq
WITH ranked AS (
SELECT id, ROW_NUMBER() OVER (PARTITION BY "conversationId" ORDER BY "createdAt", id) AS rn
FROM "ImMessage"
)
UPDATE "ImMessage" m SET seq = ranked.rn FROM ranked WHERE m.id = ranked.id;
UPDATE "ImConversation" c
SET "nextSeq" = COALESCE((
SELECT MAX(seq) + 1 FROM "ImMessage" WHERE "conversationId" = c.id
), 1);
UPDATE "ImReadCursor" rc
SET "lastReadSeq" = COALESCE((
SELECT MAX(seq) FROM "ImMessage" m
WHERE m."conversationId" = rc."conversationId" AND m."createdAt" <= rc."lastReadAt"
), 0);
CREATE INDEX IF NOT EXISTS "ImMessage_conversationId_seq_idx" ON "ImMessage"("conversationId", "seq");
@@ -0,0 +1,3 @@
# Please do not edit this file manually
# It should be added in your version-control system (e.g., Git)
provider = "postgresql"