- Add React/Vite frontend for login, dashboard, reports, templates, users, settings, AI, speech, and media workflows. - Add NestJS/Prisma/PostgreSQL backend with auth, dashboard stats, reports, templates, users, departments, settings, files, AI, speech, audit logs, and HTML sanitization. - Add Prisma schema, migrations, seed data, persistent app sessions, Docker/Nginx deployment files, and upload volume configuration. - Add Vitest, Playwright, backend integration tests, and project documentation for requirements, design, permissions, API contracts, testing, deployment, security, and progress. - Configure production local fallback switch and remove unused Gemini direct dependency/env wiring.
300 lines
10 KiB
SQL
300 lines
10 KiB
SQL
-- CreateEnum
|
|
CREATE TYPE "UserRole" AS ENUM ('SUPER', 'ADMIN', 'DOCTOR');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "UserStatus" AS ENUM ('ACTIVE', 'INACTIVE');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "ReportStatus" AS ENUM ('DRAFT', 'COMPLETED');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "TemplateScope" AS ENUM ('DEPARTMENT', 'PERSONAL');
|
|
|
|
-- CreateEnum
|
|
CREATE TYPE "FileKind" AS ENUM ('SIGNATURE', 'TEMPLATE_ASSET', 'VIDEO', 'FRAME', 'REPORT_EXPORT');
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Tenant" (
|
|
"id" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"code" TEXT NOT NULL,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "Tenant_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Department" (
|
|
"id" TEXT NOT NULL,
|
|
"tenantId" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"code" TEXT NOT NULL,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "Department_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "User" (
|
|
"id" TEXT NOT NULL,
|
|
"tenantId" TEXT NOT NULL,
|
|
"departmentId" TEXT NOT NULL,
|
|
"username" TEXT NOT NULL,
|
|
"passwordHash" TEXT NOT NULL,
|
|
"role" "UserRole" NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"status" "UserStatus" NOT NULL DEFAULT 'ACTIVE',
|
|
"phone" TEXT,
|
|
"email" TEXT,
|
|
"signatureFileId" TEXT,
|
|
"lastLoginAt" TIMESTAMP(3),
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "UserSession" (
|
|
"id" TEXT NOT NULL,
|
|
"userId" TEXT NOT NULL,
|
|
"tokenHash" TEXT NOT NULL,
|
|
"expiresAt" TIMESTAMP(3) NOT NULL,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "UserSession_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Template" (
|
|
"id" TEXT NOT NULL,
|
|
"tenantId" TEXT NOT NULL,
|
|
"name" TEXT NOT NULL,
|
|
"description" TEXT,
|
|
"content" TEXT NOT NULL,
|
|
"fields" JSONB NOT NULL DEFAULT '[]',
|
|
"scope" "TemplateScope" NOT NULL,
|
|
"ownerDepartmentId" TEXT,
|
|
"ownerUserId" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "Template_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "TemplateDepartmentPermission" (
|
|
"id" TEXT NOT NULL,
|
|
"templateId" TEXT NOT NULL,
|
|
"departmentId" TEXT NOT NULL,
|
|
"canUse" BOOLEAN NOT NULL DEFAULT true,
|
|
"canManage" BOOLEAN NOT NULL DEFAULT false,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "TemplateDepartmentPermission_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "Report" (
|
|
"id" TEXT NOT NULL,
|
|
"tenantId" TEXT NOT NULL,
|
|
"departmentId" TEXT NOT NULL,
|
|
"authorId" TEXT NOT NULL,
|
|
"templateId" TEXT,
|
|
"title" TEXT NOT NULL,
|
|
"patientName" TEXT NOT NULL,
|
|
"hospitalId" TEXT NOT NULL,
|
|
"status" "ReportStatus" NOT NULL DEFAULT 'DRAFT',
|
|
"revision" INTEGER NOT NULL DEFAULT 1,
|
|
"content" TEXT NOT NULL,
|
|
"deletedAt" TIMESTAMP(3),
|
|
"deletedBy" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "Report_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "ReportHistory" (
|
|
"id" TEXT NOT NULL,
|
|
"reportId" TEXT NOT NULL,
|
|
"revision" INTEGER NOT NULL,
|
|
"content" TEXT NOT NULL,
|
|
"action" TEXT NOT NULL,
|
|
"updatedById" TEXT NOT NULL,
|
|
"updatedBy" TEXT NOT NULL,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "ReportHistory_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "FileResource" (
|
|
"id" TEXT NOT NULL,
|
|
"tenantId" TEXT NOT NULL,
|
|
"ownerId" TEXT,
|
|
"reportId" TEXT,
|
|
"kind" "FileKind" NOT NULL,
|
|
"filename" TEXT NOT NULL,
|
|
"mimeType" TEXT NOT NULL,
|
|
"size" INTEGER NOT NULL,
|
|
"storageKey" TEXT NOT NULL,
|
|
"checksum" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "FileResource_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "SystemSetting" (
|
|
"id" TEXT NOT NULL,
|
|
"tenantId" TEXT NOT NULL,
|
|
"scope" TEXT NOT NULL,
|
|
"departmentId" TEXT,
|
|
"key" TEXT NOT NULL,
|
|
"value" JSONB NOT NULL,
|
|
"secretValue" TEXT,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
|
|
CONSTRAINT "SystemSetting_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateTable
|
|
CREATE TABLE "AuditLog" (
|
|
"id" TEXT NOT NULL,
|
|
"tenantId" TEXT NOT NULL,
|
|
"actorUserId" TEXT,
|
|
"actorRole" TEXT,
|
|
"action" TEXT NOT NULL,
|
|
"targetType" TEXT NOT NULL,
|
|
"targetId" TEXT,
|
|
"departmentId" TEXT,
|
|
"ip" TEXT,
|
|
"userAgent" TEXT,
|
|
"metadata" JSONB,
|
|
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
|
|
CONSTRAINT "AuditLog_pkey" PRIMARY KEY ("id")
|
|
);
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "Tenant_code_key" ON "Tenant"("code");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "Department_tenantId_code_key" ON "Department"("tenantId", "code");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "User_tenantId_departmentId_role_idx" ON "User"("tenantId", "departmentId", "role");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "User_tenantId_username_key" ON "User"("tenantId", "username");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "UserSession_tokenHash_key" ON "UserSession"("tokenHash");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Template_tenantId_scope_idx" ON "Template"("tenantId", "scope");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Template_tenantId_ownerDepartmentId_idx" ON "Template"("tenantId", "ownerDepartmentId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Template_tenantId_ownerUserId_idx" ON "Template"("tenantId", "ownerUserId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "TemplateDepartmentPermission_templateId_departmentId_key" ON "TemplateDepartmentPermission"("templateId", "departmentId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Report_tenantId_departmentId_status_idx" ON "Report"("tenantId", "departmentId", "status");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Report_tenantId_authorId_idx" ON "Report"("tenantId", "authorId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "Report_tenantId_deletedAt_idx" ON "Report"("tenantId", "deletedAt");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "ReportHistory_reportId_revision_idx" ON "ReportHistory"("reportId", "revision");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "FileResource_tenantId_kind_idx" ON "FileResource"("tenantId", "kind");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "FileResource_tenantId_reportId_idx" ON "FileResource"("tenantId", "reportId");
|
|
|
|
-- CreateIndex
|
|
CREATE UNIQUE INDEX "SystemSetting_tenantId_scope_departmentId_key_key" ON "SystemSetting"("tenantId", "scope", "departmentId", "key");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "AuditLog_tenantId_action_idx" ON "AuditLog"("tenantId", "action");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "AuditLog_tenantId_actorUserId_idx" ON "AuditLog"("tenantId", "actorUserId");
|
|
|
|
-- CreateIndex
|
|
CREATE INDEX "AuditLog_tenantId_targetType_targetId_idx" ON "AuditLog"("tenantId", "targetType", "targetId");
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Department" ADD CONSTRAINT "Department_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "User" ADD CONSTRAINT "User_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "User" ADD CONSTRAINT "User_departmentId_fkey" FOREIGN KEY ("departmentId") REFERENCES "Department"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "UserSession" ADD CONSTRAINT "UserSession_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Template" ADD CONSTRAINT "Template_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Template" ADD CONSTRAINT "Template_ownerDepartmentId_fkey" FOREIGN KEY ("ownerDepartmentId") REFERENCES "Department"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Template" ADD CONSTRAINT "Template_ownerUserId_fkey" FOREIGN KEY ("ownerUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "TemplateDepartmentPermission" ADD CONSTRAINT "TemplateDepartmentPermission_templateId_fkey" FOREIGN KEY ("templateId") REFERENCES "Template"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "TemplateDepartmentPermission" ADD CONSTRAINT "TemplateDepartmentPermission_departmentId_fkey" FOREIGN KEY ("departmentId") REFERENCES "Department"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Report" ADD CONSTRAINT "Report_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Report" ADD CONSTRAINT "Report_departmentId_fkey" FOREIGN KEY ("departmentId") REFERENCES "Department"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Report" ADD CONSTRAINT "Report_authorId_fkey" FOREIGN KEY ("authorId") REFERENCES "User"("id") ON DELETE RESTRICT ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "Report" ADD CONSTRAINT "Report_templateId_fkey" FOREIGN KEY ("templateId") REFERENCES "Template"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "ReportHistory" ADD CONSTRAINT "ReportHistory_reportId_fkey" FOREIGN KEY ("reportId") REFERENCES "Report"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "FileResource" ADD CONSTRAINT "FileResource_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "FileResource" ADD CONSTRAINT "FileResource_reportId_fkey" FOREIGN KEY ("reportId") REFERENCES "Report"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "SystemSetting" ADD CONSTRAINT "SystemSetting_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "SystemSetting" ADD CONSTRAINT "SystemSetting_departmentId_fkey" FOREIGN KEY ("departmentId") REFERENCES "Department"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "AuditLog" ADD CONSTRAINT "AuditLog_tenantId_fkey" FOREIGN KEY ("tenantId") REFERENCES "Tenant"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
|
|
-- AddForeignKey
|
|
ALTER TABLE "AuditLog" ADD CONSTRAINT "AuditLog_actorUserId_fkey" FOREIGN KEY ("actorUserId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|