From 6124c7abc604ba66b380f53a4de438ecaacecf3c Mon Sep 17 00:00:00 2001 From: HaHafeng Date: Fri, 27 Feb 2026 14:35:25 +0800 Subject: [PATCH] docs(platform): Add database documentation system and restructure deployment docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Completed: - Add 6 core database documents (docs/01-平台基础层/07-数据库/) Architecture overview, migration history, environment comparison, tech debt tracking, seed data management, PostgreSQL extensions - Restructure deployment docs: archive 20 legacy files to _archive-2025/ - Create unified daily operations manual (01-日常更新操作手册.md) - Add pending deployment change tracker (03-待部署变更清单.md) - Update database development standard to v3.0 (three iron rules) - Fix Prisma schema type drift: align @db.* annotations with actual DB IIT: UUID/Timestamptz(6), SSA: Timestamp(6)/VarChar(20/50/100) - Add migration: 20260227_align_schema_with_db_types (idempotent ALTER) - Add Cursor Rule for auto-reminding deployment change documentation - Update system status guide v6.4 with deployment and DB doc references - Add architecture consultation docs (Prisma guide, SAE deployment guide) Technical details: - Manual migration due to shadow DB limitation (TD-001 in tech debt) - Deployment docs reduced from 20+ scattered files to 3 core documents - Cursor Rule triggers on schema.prisma, package.json, Dockerfile changes Made-with: Cursor --- .cursor/rules/deployment-change-tracking.mdc | 34 + backend/Dockerfile | 4 + .../migration.sql | 27 + .../migration.sql | 229 ++++++ backend/prisma/schema.prisma | 52 +- .../00-系统当前状态与开发指南.md | 209 ++---- .../07-数据库/00-数据库架构总览.md | 163 +++++ .../07-数据库/01-Prisma迁移历史与变更日志.md | 179 +++++ .../07-数据库/02-环境状态对照表.md | 102 +++ .../07-数据库/03-技术债务追踪.md | 123 ++++ .../07-数据库/04-种子数据管理.md | 116 +++ .../07-数据库/05-PostgreSQL扩展与特性.md | 147 ++++ docs/04-开发规范/09-数据库开发规范.md | 107 ++- .../00-阿里云SAE最新真实状态记录.md | 64 +- docs/05-部署文档/01-日常更新操作手册.md | 265 +++++++ .../05-部署文档/0227部署/01-数据库迁移方案.md | 661 ++++++++++++++++++ docs/05-部署文档/0227部署/02-部署完成总结.md | 355 ++++++++++ docs/05-部署文档/03-待部署变更清单.md | 99 +++ docs/05-部署文档/README.md | 439 ++---------- .../01-快速部署SOP-零基础版.md | 0 .../02-SAE部署完全指南(产品经理版).md | 0 .../03-Dify-ECS部署完全指南.md | 0 .../04-Python微服务-SAE容器部署指南.md | 0 .../05-Node.js后端-SAE容器部署指南.md | 0 .../06-前端Nginx-SAE容器部署指南.md | 0 .../07-关键配置补充说明.md | 0 .../07-前端Nginx-SAE部署操作手册.md | 0 .../08-PostgreSQL数据库部署操作手册.md | 0 .../08-部署检查清单.md | 0 .../09-Python微服务-SAE部署操作手册.md | 0 .../10-Node.js后端-Docker镜像构建手册.md | 0 .../11-Node.js后端-SAE部署配置清单.md | 0 .../12-Node.js后端-SAE部署操作手册.md | 0 .../13-Node.js后端-镜像修复记录.md | 0 .../14-Node.js后端-pino-pretty问题修复.md | 0 .../15-Node.js后端-部署成功总结.md | 0 .../16-前端Nginx-部署成功总结.md | 0 .../17-完整部署实战手册-2025版.md | 0 .../18-部署文档使用指南.md | 0 .../19-日常更新快速操作手册.md | 0 .../CTO 代码审查报告:AI临床研究平台部署架构.md | 0 .../PostgreSQL部署策略-摸底报告.md | 0 .../SSL 证书域名SAE配置指南.md | 0 .../文档修正报告-20251214.md | 0 .../集成部署补充指南:填补最后的缝隙.md | 0 .../数据库同步规范与 Prisma 操作指南.md | 96 +++ .../阿里云 SAE 全栈部署与高并发弹性策略指南.md | 112 +++ .../src/modules/aia/styles/chat-workspace.css | 8 +- 48 files changed, 3009 insertions(+), 582 deletions(-) create mode 100644 .cursor/rules/deployment-change-tracking.mdc create mode 100644 backend/prisma/migrations/20260227_align_schema_with_db_types/migration.sql create mode 100644 backend/prisma/migrations/20260227_patch_db_push_drift/migration.sql create mode 100644 docs/01-平台基础层/07-数据库/00-数据库架构总览.md create mode 100644 docs/01-平台基础层/07-数据库/01-Prisma迁移历史与变更日志.md create mode 100644 docs/01-平台基础层/07-数据库/02-环境状态对照表.md create mode 100644 docs/01-平台基础层/07-数据库/03-技术债务追踪.md create mode 100644 docs/01-平台基础层/07-数据库/04-种子数据管理.md create mode 100644 docs/01-平台基础层/07-数据库/05-PostgreSQL扩展与特性.md create mode 100644 docs/05-部署文档/01-日常更新操作手册.md create mode 100644 docs/05-部署文档/0227部署/01-数据库迁移方案.md create mode 100644 docs/05-部署文档/0227部署/02-部署完成总结.md create mode 100644 docs/05-部署文档/03-待部署变更清单.md rename docs/05-部署文档/{ => _archive-2025首次部署}/01-快速部署SOP-零基础版.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/02-SAE部署完全指南(产品经理版).md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/03-Dify-ECS部署完全指南.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/04-Python微服务-SAE容器部署指南.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/05-Node.js后端-SAE容器部署指南.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/06-前端Nginx-SAE容器部署指南.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/07-关键配置补充说明.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/07-前端Nginx-SAE部署操作手册.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/08-PostgreSQL数据库部署操作手册.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/08-部署检查清单.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/09-Python微服务-SAE部署操作手册.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/10-Node.js后端-Docker镜像构建手册.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/11-Node.js后端-SAE部署配置清单.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/12-Node.js后端-SAE部署操作手册.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/13-Node.js后端-镜像修复记录.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/14-Node.js后端-pino-pretty问题修复.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/15-Node.js后端-部署成功总结.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/16-前端Nginx-部署成功总结.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/17-完整部署实战手册-2025版.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/18-部署文档使用指南.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/19-日常更新快速操作手册.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/CTO 代码审查报告:AI临床研究平台部署架构.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/PostgreSQL部署策略-摸底报告.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/SSL 证书域名SAE配置指南.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/文档修正报告-20251214.md (100%) rename docs/05-部署文档/{ => _archive-2025首次部署}/集成部署补充指南:填补最后的缝隙.md (100%) create mode 100644 docs/09-架构实施/J技术架构咨询/数据库同步规范与 Prisma 操作指南.md create mode 100644 docs/09-架构实施/J技术架构咨询/阿里云 SAE 全栈部署与高并发弹性策略指南.md diff --git a/.cursor/rules/deployment-change-tracking.mdc b/.cursor/rules/deployment-change-tracking.mdc new file mode 100644 index 00000000..50550447 --- /dev/null +++ b/.cursor/rules/deployment-change-tracking.mdc @@ -0,0 +1,34 @@ +--- +description: 当修改数据库Schema、依赖或配置时,提醒记录到待部署变更清单 +globs: backend/prisma/schema.prisma, backend/package.json, frontend-v2/package.json, extraction_service/requirements*.txt, r-statistics-service/**, backend/Dockerfile, frontend-v2/Dockerfile, extraction_service/Dockerfile, frontend-v2/nginx.conf, backend/.env.example +alwaysApply: false +--- + +# 部署变更追踪提醒 + +当你修改了以下文件,必须同步更新 `docs/05-部署文档/03-待部署变更清单.md`: + +## 触发条件 → 记录内容 + +| 修改的文件 | 清单区域 | 记录什么 | +|-----------|---------|---------| +| `schema.prisma` | 数据库变更 | 迁移文件名 + 变更描述 | +| `backend/package.json` (新依赖) | 后端变更 | 新增的 npm 包 | +| `backend/Dockerfile` | 后端变更 | Dockerfile 变更原因 | +| `frontend-v2/package.json` (新依赖) | 前端变更 | 新增的 npm 包 | +| `frontend-v2/nginx.conf` | 前端变更 | Nginx 配置变更 | +| `requirements*.txt` | Python 变更 | 新增/升级的 pip 包 | +| `r-statistics-service/**` | R 引擎变更 | R 包或工具变更 | + +## 操作步骤 + +1. 完成代码修改 +2. 打开 `docs/05-部署文档/03-待部署变更清单.md` +3. 在对应区域追加一行记录 +4. 提交代码时包含清单更新 + +## schema.prisma 额外规则 + +- 修改 Schema 后必须运行 `npx prisma migrate dev --name xxx` 生成迁移 +- 禁止使用 `prisma db push`(除非原型探索,事后必须补迁移) +- 迁移生成后同步更新 `docs/01-平台基础层/07-数据库/01-Prisma迁移历史与变更日志.md` diff --git a/backend/Dockerfile b/backend/Dockerfile index 0e91e1d4..219f9191 100644 --- a/backend/Dockerfile +++ b/backend/Dockerfile @@ -28,6 +28,10 @@ RUN npx prisma generate # 5. 复制本地已编译好的 dist 文件夹(跳过TypeScript编译) COPY dist ./dist +# 5a. tsc 不会复制 .json 文件,手动补充 src 中的 JSON 配置到 dist +COPY src/modules/ssa/config/*.json ./dist/modules/ssa/config/ +COPY src/modules/asl/fulltext-screening/prompts/*.json ./dist/modules/asl/fulltext-screening/prompts/ + # 6. 复制配置文件(agents.yaml等) COPY config ./config diff --git a/backend/prisma/migrations/20260227_align_schema_with_db_types/migration.sql b/backend/prisma/migrations/20260227_align_schema_with_db_types/migration.sql new file mode 100644 index 00000000..0bbd2bad --- /dev/null +++ b/backend/prisma/migrations/20260227_align_schema_with_db_types/migration.sql @@ -0,0 +1,27 @@ +-- ================================================================ +-- 对齐迁移:修正 prisma db push 造成的类型漂移 +-- 使 Schema 的 @db.* 注解与数据库实际类型一致 +-- 所有 ALTER 均为幂等操作(DB 已是目标类型,仅记录逻辑变更) +-- 日期:2026-02-27 +-- ================================================================ + +-- 1. ssa_workflows: 精度/长度对齐 +ALTER TABLE "ssa_schema"."ssa_workflows" + ALTER COLUMN "status" SET DATA TYPE VARCHAR(20), + ALTER COLUMN "created_at" SET DATA TYPE TIMESTAMP(6), + ALTER COLUMN "started_at" SET DATA TYPE TIMESTAMP(6), + ALTER COLUMN "completed_at" SET DATA TYPE TIMESTAMP(6); + +-- 2. ssa_workflow_steps: 精度/长度对齐 +ALTER TABLE "ssa_schema"."ssa_workflow_steps" + ALTER COLUMN "tool_code" SET DATA TYPE VARCHAR(50), + ALTER COLUMN "tool_name" SET DATA TYPE VARCHAR(100), + ALTER COLUMN "status" SET DATA TYPE VARCHAR(20), + ALTER COLUMN "started_at" SET DATA TYPE TIMESTAMP(6), + ALTER COLUMN "completed_at" SET DATA TYPE TIMESTAMP(6); + +-- 3. 清理重复外键(prisma db push 用 fk_ 前缀创建了额外 FK) +ALTER TABLE "ssa_schema"."ssa_workflow_steps" + DROP CONSTRAINT IF EXISTS "fk_ssa_workflow_step_workflow"; +ALTER TABLE "ssa_schema"."ssa_workflows" + DROP CONSTRAINT IF EXISTS "fk_ssa_workflow_session"; diff --git a/backend/prisma/migrations/20260227_patch_db_push_drift/migration.sql b/backend/prisma/migrations/20260227_patch_db_push_drift/migration.sql new file mode 100644 index 00000000..395f3946 --- /dev/null +++ b/backend/prisma/migrations/20260227_patch_db_push_drift/migration.sql @@ -0,0 +1,229 @@ +-- ================================================================ +-- 补丁迁移:覆盖 db push 创建的 6 张表 + 3 列 +-- 所有语句使用 IF NOT EXISTS 保证幂等(多次执行不报错) +-- 日期:2026-02-27 +-- ================================================================ + +-- ============ iit_schema: 4 张新表 + 1 列 + 1 索引 ============ + +-- 1. IIT 字段元数据表(REDCap 字段定义缓存) +CREATE TABLE IF NOT EXISTS "iit_schema"."field_metadata" ( + "id" TEXT NOT NULL, + "project_id" TEXT NOT NULL, + "field_name" TEXT NOT NULL, + "field_label" TEXT NOT NULL, + "field_type" TEXT NOT NULL, + "form_name" TEXT NOT NULL, + "section_header" TEXT, + "validation" TEXT, + "validation_min" TEXT, + "validation_max" TEXT, + "choices" TEXT, + "required" BOOLEAN NOT NULL DEFAULT false, + "branching" TEXT, + "alias" TEXT, + "rule_source" TEXT, + "synced_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "field_metadata_pkey" PRIMARY KEY ("id") +); + +CREATE UNIQUE INDEX IF NOT EXISTS "unique_iit_field_metadata" + ON "iit_schema"."field_metadata"("project_id", "field_name"); +CREATE INDEX IF NOT EXISTS "idx_iit_field_metadata_project" + ON "iit_schema"."field_metadata"("project_id"); +CREATE INDEX IF NOT EXISTS "idx_iit_field_metadata_form" + ON "iit_schema"."field_metadata"("project_id", "form_name"); + +-- 2. IIT 质控日志表 +CREATE TABLE IF NOT EXISTS "iit_schema"."qc_logs" ( + "id" TEXT NOT NULL, + "project_id" TEXT NOT NULL, + "record_id" TEXT NOT NULL, + "event_id" TEXT, + "qc_type" TEXT NOT NULL, + "form_name" TEXT, + "status" TEXT NOT NULL, + "issues" JSONB NOT NULL DEFAULT '[]', + "rules_evaluated" INTEGER NOT NULL DEFAULT 0, + "rules_skipped" INTEGER NOT NULL DEFAULT 0, + "rules_passed" INTEGER NOT NULL DEFAULT 0, + "rules_failed" INTEGER NOT NULL DEFAULT 0, + "rule_version" TEXT NOT NULL, + "inclusion_passed" BOOLEAN, + "exclusion_passed" BOOLEAN, + "triggered_by" TEXT NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "qc_logs_pkey" PRIMARY KEY ("id") +); + +CREATE INDEX IF NOT EXISTS "idx_iit_qc_log_record_time" + ON "iit_schema"."qc_logs"("project_id", "record_id", "created_at"); +CREATE INDEX IF NOT EXISTS "idx_iit_qc_log_status_time" + ON "iit_schema"."qc_logs"("project_id", "status", "created_at"); +CREATE INDEX IF NOT EXISTS "idx_iit_qc_log_type_time" + ON "iit_schema"."qc_logs"("project_id", "qc_type", "created_at"); + +-- 3. IIT 受试者记录汇总表 +CREATE TABLE IF NOT EXISTS "iit_schema"."record_summary" ( + "id" TEXT NOT NULL, + "project_id" TEXT NOT NULL, + "record_id" TEXT NOT NULL, + "enrolled_at" TIMESTAMP(3), + "enrolled_by" TEXT, + "last_updated_at" TIMESTAMP(3) NOT NULL, + "last_updated_by" TEXT, + "last_form_name" TEXT, + "form_status" JSONB NOT NULL DEFAULT '{}', + "total_forms" INTEGER NOT NULL DEFAULT 0, + "completed_forms" INTEGER NOT NULL DEFAULT 0, + "completion_rate" DOUBLE PRECISION NOT NULL DEFAULT 0, + "latest_qc_status" TEXT, + "latest_qc_at" TIMESTAMP(3), + "update_count" INTEGER NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "record_summary_pkey" PRIMARY KEY ("id") +); + +CREATE UNIQUE INDEX IF NOT EXISTS "unique_iit_record_summary" + ON "iit_schema"."record_summary"("project_id", "record_id"); +CREATE INDEX IF NOT EXISTS "idx_iit_record_summary_enrolled" + ON "iit_schema"."record_summary"("project_id", "enrolled_at"); +CREATE INDEX IF NOT EXISTS "idx_iit_record_summary_qc_status" + ON "iit_schema"."record_summary"("project_id", "latest_qc_status"); +CREATE INDEX IF NOT EXISTS "idx_iit_record_summary_completion" + ON "iit_schema"."record_summary"("project_id", "completion_rate"); + +-- 4. IIT 项目级质控统计汇总表 +CREATE TABLE IF NOT EXISTS "iit_schema"."qc_project_stats" ( + "id" TEXT NOT NULL, + "project_id" TEXT NOT NULL, + "total_records" INTEGER NOT NULL DEFAULT 0, + "passed_records" INTEGER NOT NULL DEFAULT 0, + "failed_records" INTEGER NOT NULL DEFAULT 0, + "warning_records" INTEGER NOT NULL DEFAULT 0, + "inclusion_met" INTEGER NOT NULL DEFAULT 0, + "exclusion_met" INTEGER NOT NULL DEFAULT 0, + "avg_completion_rate" DOUBLE PRECISION NOT NULL DEFAULT 0, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "qc_project_stats_pkey" PRIMARY KEY ("id") +); + +CREATE UNIQUE INDEX IF NOT EXISTS "qc_project_stats_project_id_key" + ON "iit_schema"."qc_project_stats"("project_id"); + +-- 5. IIT projects 表新增 knowledge_base_id 列 +ALTER TABLE "iit_schema"."projects" + ADD COLUMN IF NOT EXISTS "knowledge_base_id" TEXT; + +CREATE INDEX IF NOT EXISTS "idx_iit_project_kb" + ON "iit_schema"."projects"("knowledge_base_id"); + +-- ============ ssa_schema: 1 列 + 2 张新表 ============ + +-- 6a. SSA Session 新增 data_profile 列(Phase 2A) +ALTER TABLE "ssa_schema"."ssa_sessions" + ADD COLUMN IF NOT EXISTS "data_profile" JSONB; + +-- 6. SSA 工作流表 +CREATE TABLE IF NOT EXISTS "ssa_schema"."ssa_workflows" ( + "id" TEXT NOT NULL DEFAULT gen_random_uuid()::text, + "session_id" TEXT NOT NULL, + "message_id" TEXT, + "status" VARCHAR NOT NULL DEFAULT 'pending', + "total_steps" INTEGER NOT NULL, + "completed_steps" INTEGER NOT NULL DEFAULT 0, + "workflow_plan" JSONB NOT NULL, + "reasoning" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT now(), + "started_at" TIMESTAMP(3), + "completed_at" TIMESTAMP(3), + + CONSTRAINT "ssa_workflows_pkey" PRIMARY KEY ("id") +); + +CREATE INDEX IF NOT EXISTS "idx_ssa_workflow_session" + ON "ssa_schema"."ssa_workflows"("session_id"); +CREATE INDEX IF NOT EXISTS "idx_ssa_workflow_status" + ON "ssa_schema"."ssa_workflows"("status"); + +-- 外键:ssa_workflows.session_id → ssa_sessions.id +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.table_constraints + WHERE constraint_name = 'ssa_workflows_session_id_fkey' + ) THEN + ALTER TABLE "ssa_schema"."ssa_workflows" + ADD CONSTRAINT "ssa_workflows_session_id_fkey" + FOREIGN KEY ("session_id") + REFERENCES "ssa_schema"."ssa_sessions"("id") + ON DELETE CASCADE ON UPDATE CASCADE; + END IF; +END $$; + +-- 7. SSA 工作流步骤表 +CREATE TABLE IF NOT EXISTS "ssa_schema"."ssa_workflow_steps" ( + "id" TEXT NOT NULL DEFAULT gen_random_uuid()::text, + "workflow_id" TEXT NOT NULL, + "step_order" INTEGER NOT NULL, + "tool_code" VARCHAR NOT NULL, + "tool_name" VARCHAR NOT NULL, + "status" VARCHAR NOT NULL DEFAULT 'pending', + "input_params" JSONB, + "guardrail_checks" JSONB, + "output_result" JSONB, + "error_info" JSONB, + "execution_ms" INTEGER, + "started_at" TIMESTAMP(3), + "completed_at" TIMESTAMP(3), + + CONSTRAINT "ssa_workflow_steps_pkey" PRIMARY KEY ("id") +); + +CREATE INDEX IF NOT EXISTS "idx_ssa_workflow_step_workflow" + ON "ssa_schema"."ssa_workflow_steps"("workflow_id"); +CREATE INDEX IF NOT EXISTS "idx_ssa_workflow_step_status" + ON "ssa_schema"."ssa_workflow_steps"("status"); + +-- 外键:ssa_workflow_steps.workflow_id → ssa_workflows.id +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.table_constraints + WHERE constraint_name = 'ssa_workflow_steps_workflow_id_fkey' + ) THEN + ALTER TABLE "ssa_schema"."ssa_workflow_steps" + ADD CONSTRAINT "ssa_workflow_steps_workflow_id_fkey" + FOREIGN KEY ("workflow_id") + REFERENCES "ssa_schema"."ssa_workflows"("id") + ON DELETE CASCADE ON UPDATE CASCADE; + END IF; +END $$; + +-- ============ rvw_schema: review_tasks 缺失列 ============ + +-- 8. review_tasks 后续 prisma db push 新增的 8 个列 +ALTER TABLE "rvw_schema"."review_tasks" + ADD COLUMN IF NOT EXISTS "selected_agents" TEXT[] DEFAULT ARRAY['editorial','methodology']; +ALTER TABLE "rvw_schema"."review_tasks" + ADD COLUMN IF NOT EXISTS "editorial_score" DOUBLE PRECISION; +ALTER TABLE "rvw_schema"."review_tasks" + ADD COLUMN IF NOT EXISTS "methodology_score" DOUBLE PRECISION; +ALTER TABLE "rvw_schema"."review_tasks" + ADD COLUMN IF NOT EXISTS "methodology_status" TEXT; +ALTER TABLE "rvw_schema"."review_tasks" + ADD COLUMN IF NOT EXISTS "pico_extract" JSONB; +ALTER TABLE "rvw_schema"."review_tasks" + ADD COLUMN IF NOT EXISTS "context_data" JSONB; +ALTER TABLE "rvw_schema"."review_tasks" + ADD COLUMN IF NOT EXISTS "is_archived" BOOLEAN DEFAULT false; +ALTER TABLE "rvw_schema"."review_tasks" + ADD COLUMN IF NOT EXISTS "archived_at" TIMESTAMP(3); + +CREATE INDEX IF NOT EXISTS "review_tasks_is_archived_idx" + ON "rvw_schema"."review_tasks"("is_archived"); diff --git a/backend/prisma/schema.prisma b/backend/prisma/schema.prisma index d21e8969..5cb6e2ee 100644 --- a/backend/prisma/schema.prisma +++ b/backend/prisma/schema.prisma @@ -1430,7 +1430,8 @@ model IitQcProjectStats { /// eQuery 表 - AI 自动生成的电子质疑,具有完整生命周期 model IitEquery { - id String @id @default(uuid()) + // TODO: Tech Debt - DB 由 prisma db push 创建为 UUID 类型,未来大版本重构时统一为 String/TEXT + id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid projectId String @map("project_id") // 来源 @@ -1452,23 +1453,24 @@ model IitEquery { // CRC 回复 assignedTo String? @map("assigned_to") - respondedAt DateTime? @map("responded_at") + // TODO: Tech Debt - DB 由 prisma db push 创建为 TIMESTAMPTZ(6),与 Prisma 默认的 TIMESTAMP(3) 不同 + respondedAt DateTime? @map("responded_at") @db.Timestamptz(6) responseText String? @map("response_text") @db.Text responseData Json? @map("response_data") @db.JsonB // AI 复核 reviewResult String? @map("review_result") reviewNote String? @map("review_note") @db.Text - reviewedAt DateTime? @map("reviewed_at") + reviewedAt DateTime? @map("reviewed_at") @db.Timestamptz(6) // 关闭 - closedAt DateTime? @map("closed_at") + closedAt DateTime? @map("closed_at") @db.Timestamptz(6) closedBy String? @map("closed_by") resolution String? @db.Text // 时间线 - createdAt DateTime @default(now()) @map("created_at") - updatedAt DateTime @updatedAt @map("updated_at") + createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6) + updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz(6) @@index([projectId], map: "idx_iit_equery_project") @@index([projectId, status], map: "idx_iit_equery_project_status") @@ -1480,7 +1482,8 @@ model IitEquery { /// 重大事件归档表 - SAE、重大方案偏离等长期临床资产 model IitCriticalEvent { - id String @id @default(uuid()) + // TODO: Tech Debt - DB 由 prisma db push 创建为 UUID 类型,未来大版本重构时统一为 String/TEXT + id String @id @default(dbgenerated("gen_random_uuid()")) @db.Uuid projectId String @map("project_id") recordId String @map("record_id") @@ -1491,7 +1494,8 @@ model IitCriticalEvent { // 事件内容 title String description String @db.Text - detectedAt DateTime @map("detected_at") + // TODO: Tech Debt - DB 由 prisma db push 创建为 TIMESTAMPTZ(6) + detectedAt DateTime @map("detected_at") @db.Timestamptz(6) detectedBy String @default("ai") @map("detected_by") // 来源追溯 @@ -1502,15 +1506,15 @@ model IitCriticalEvent { // 处理状态 status String @default("open") handledBy String? @map("handled_by") - handledAt DateTime? @map("handled_at") + handledAt DateTime? @map("handled_at") @db.Timestamptz(6) handlingNote String? @map("handling_note") @db.Text // 上报追踪 reportedToEc Boolean @default(false) @map("reported_to_ec") - reportedAt DateTime? @map("reported_at") + reportedAt DateTime? @map("reported_at") @db.Timestamptz(6) - createdAt DateTime @default(now()) @map("created_at") - updatedAt DateTime @updatedAt @map("updated_at") + createdAt DateTime @default(now()) @map("created_at") @db.Timestamptz(6) + updatedAt DateTime @default(now()) @updatedAt @map("updated_at") @db.Timestamptz(6) @@index([projectId], map: "idx_iit_critical_event_project") @@index([projectId, eventType], map: "idx_iit_critical_event_type") @@ -2513,17 +2517,18 @@ model SsaInterpretation { /// SSA 多步骤流程 model SsaWorkflow { - id String @id @default(uuid()) + // TODO: Tech Debt - DB 由 prisma db push 创建,类型与 Prisma 默认不同,已手动对齐 + id String @id @default(dbgenerated("(gen_random_uuid())::text")) sessionId String @map("session_id") messageId String? @map("message_id") /// 关联的计划消息 - status String @default("pending") /// pending | running | completed | partial | error + status String @default("pending") @db.VarChar(20) /// pending | running | completed | partial | error totalSteps Int @map("total_steps") completedSteps Int @default(0) @map("completed_steps") workflowPlan Json @map("workflow_plan") /// 原始计划 JSON reasoning String? @db.Text /// LLM 规划理由 - createdAt DateTime @default(now()) @map("created_at") - startedAt DateTime? @map("started_at") - completedAt DateTime? @map("completed_at") + createdAt DateTime @default(now()) @map("created_at") @db.Timestamp(6) + startedAt DateTime? @map("started_at") @db.Timestamp(6) + completedAt DateTime? @map("completed_at") @db.Timestamp(6) session SsaSession @relation(fields: [sessionId], references: [id], onDelete: Cascade) steps SsaWorkflowStep[] @@ -2536,19 +2541,20 @@ model SsaWorkflow { /// SSA 流程步骤 model SsaWorkflowStep { - id String @id @default(uuid()) + // TODO: Tech Debt - DB 由 prisma db push 创建,类型与 Prisma 默认不同,已手动对齐 + id String @id @default(dbgenerated("(gen_random_uuid())::text")) workflowId String @map("workflow_id") stepOrder Int @map("step_order") /// 步骤顺序(1, 2, 3...) - toolCode String @map("tool_code") - toolName String @map("tool_name") - status String @default("pending") /// pending | running | success | warning | error | skipped + toolCode String @map("tool_code") @db.VarChar(50) + toolName String @map("tool_name") @db.VarChar(100) + status String @default("pending") @db.VarChar(20) /// pending | running | success | warning | error | skipped inputParams Json? @map("input_params") /// 输入参数 guardrailChecks Json? @map("guardrail_checks") /// JIT 护栏检验结果 outputResult Json? @map("output_result") /// 执行结果 errorInfo Json? @map("error_info") /// 错误信息 executionMs Int? @map("execution_ms") /// 执行耗时(毫秒) - startedAt DateTime? @map("started_at") - completedAt DateTime? @map("completed_at") + startedAt DateTime? @map("started_at") @db.Timestamp(6) + completedAt DateTime? @map("completed_at") @db.Timestamp(6) workflow SsaWorkflow @relation(fields: [workflowId], references: [id], onDelete: Cascade) diff --git a/docs/00-系统总体设计/00-系统当前状态与开发指南.md b/docs/00-系统总体设计/00-系统当前状态与开发指南.md index 1d00d918..6660897f 100644 --- a/docs/00-系统总体设计/00-系统当前状态与开发指南.md +++ b/docs/00-系统总体设计/00-系统当前状态与开发指南.md @@ -1,10 +1,11 @@ # AIclinicalresearch 系统当前状态与开发指南 -> **文档版本:** v6.3 +> **文档版本:** v6.4 > **创建日期:** 2025-11-28 > **维护者:** 开发团队 -> **最后更新:** 2026-02-26 +> **最后更新:** 2026-02-27 > **🎉 重大里程碑:** +> - **🆕 2026-02-27:数据库文档体系 + 部署文档体系 + Prisma Schema 对齐完成!** 6 篇数据库核心文档 + 部署文档归档整理 + 统一操作手册 + 数据库开发规范 v3.0 + Cursor Rule 自动提醒 + Schema 类型漂移修正 > - **🆕 2026-02-26:ASL 工具 4 SR 图表生成器 + 工具 5 Meta 分析引擎开发完成!** PRISMA 流程图(中英切换)+ 基线特征表 + Meta 分析(HR/二分类/连续型)+ 森林图/漏斗图 + R Docker meta 包 + E2E 36/36 通过 > - **🆕 2026-02-26:CRA Agent V3.0 P0+P1 全部完成!** 自驱动质控流水线 + ChatOrchestrator + LLM Function Calling + E2E 54/54 通过 > - **2026-02-24:ASL 工具 3 V2.0 架构升级至散装派发 + Aggregator!** 9 条研发红线 + 散装派发与轮询收口任务模式指南 v1.1 沉淀 @@ -30,12 +31,14 @@ > - **2026-01-24:Protocol Agent 框架完成!** 可复用Agent框架+5阶段对话流程 > - **2026-01-22:OSS 存储集成完成!** 阿里云 OSS 正式接入平台基础层 > -> **🆕 最新进展(ASL 工具 4+5 开发完成 2026-02-26):** -> - ✅ **🎉🆕 ASL 工具 4 SR 图表生成器完成** — PRISMA 2020 流程图(中英切换)+ 基线特征表 + 双通道数据源(项目流水线/Excel)+ SVG/PNG 导出 -> - ✅ **🎉🆕 ASL 工具 5 Meta 分析引擎完成** — HR/二分类/连续型 3 种数据类型 + 随机/固定效应模型 + 森林图/漏斗图 + R Docker meta 包 + E2E 36/36 通过 -> - ✅ **🆕 R Docker 镜像更新** — 新增 meta 包,工具总数从 12 增至 13(ST_META_ANALYSIS) -> - ✅ **🎉 ASL 工具 3 M1+M2 开发完成** — 散装派发+Aggregator + MinerU VLM + XML Prompt + HITL 审核抽屉 + Excel 导出 -> - ✅ **🎉 SSA Phase I-IV 全部开发完成** — Session 黑板 + 意图路由器 + 对话层 LLM + 方法咨询 + QPER 集成,E2E 107/107 +> **🆕 最新进展(数据库文档体系 + 部署文档整理 2026-02-27):** +> - ✅ **🆕 数据库文档体系建立** — 6 篇核心文档(架构总览/迁移历史/环境对照/技术债务/种子数据/PG扩展),位于 `docs/01-平台基础层/07-数据库/` +> - ✅ **🆕 Prisma Schema 类型漂移修正** — IIT/SSA 模型 @db.* 注解对齐 + 手动迁移 + Tech Debt 注释 +> - ✅ **🆕 部署文档体系整理** — 归档 2025 旧文档 + 统一操作手册 + 待部署变更清单 + README 重写 +> - ✅ **🆕 数据库开发规范 v3.0** — 三条铁律 + 变更记录规则 + Shadow DB 降级方案 + 事故案例 +> - ✅ **🆕 Cursor Rule 自动提醒** — 修改 Schema/依赖时自动提醒更新待部署变更清单 +> - ✅ **🎉 ASL 工具 4 SR 图表生成器完成** — PRISMA 2020 流程图(中英切换)+ 基线特征表 + 双通道数据源 + SVG/PNG 导出 +> - ✅ **🎉 ASL 工具 5 Meta 分析引擎完成** — HR/二分类/连续型 3 种数据类型 + 森林图/漏斗图 + R Docker meta 包 + E2E 36/36 > - ✅ **🎉 CRA Agent V3.0 P0+P1 完成** — ChatOrchestrator + LLM Function Calling + 4 工具 + E2E 54/54 > > **部署状态:** ✅ 生产环境运行中 | 公网地址:http://8.140.53.236/ @@ -155,14 +158,11 @@ - ✅ Node.js后端(v1.3)- 内网:172.17.173.73:3001 - ✅ 前端Nginx(v1.0)- 内网:172.17.173.72:80 - ✅ CLB负载均衡 - 公网:http://8.140.53.236/ -- RDS PostgreSQL 15(生产环境运行中) +- RDS PostgreSQL 15(生产环境运行中,14个Schema) - OSS对象存储(✅ 2026-01-22 已集成,4个Bucket) -- ACR容器镜像仓库(已推送3个镜像) -- 阿里云 ACR (容器镜像服务) ✅ 已推送3个镜像(Frontend、Backend、Python) -- 阿里云 RDS (PostgreSQL 15) ✅ 已迁移数据 -- RDS PostgreSQL 15 + OSS (对象存储) + NAT网关 -- ACR (容器镜像服务 - 个人版免费) -- **部署状态**:🚀 **进行中**(PostgreSQL✅、Python微服务✅、前端镜像✅、Node.js后端⏳) +- ACR容器镜像仓库(已推送 4 个镜像:Frontend、Backend、Python、R Statistics) +- **部署状态**:✅ **生产环境运行中** +- **部署文档**:`docs/05-部署文档/`(操作手册 + 待部署变更清单 + 归档) --- @@ -1109,9 +1109,9 @@ docs/03-业务模块/Redcap/ # REDCap文档体系(新增) --- -## 🚀 阿里云生产环境部署状态(2025-12-24) +## 🚀 阿里云生产环境部署状态(2026-02-27 更新) -### ✅ 已完成部署 +### ✅ 已完成部署(全部运行中) #### 1. 基础设施层 - ✅ **VPC网络**:`vpc-2ze055cptkew9c38w4r06`(172.17.0.0/16) @@ -1119,6 +1119,7 @@ docs/03-业务模块/Redcap/ # REDCap文档体系(新增) - ✅ **安全组**:`sg-2zedk6fi8sgmmcwdu7tu` - ✅ **交换机**:2个(可用区F + 可用区A) - ✅ **SAE命名空间**:`cn-beijing:test-airesearch` +- ✅ **CLB负载均衡** — 公网:http://8.140.53.236/ #### 2. 数据存储层 - ✅ **RDS PostgreSQL 15** @@ -1126,117 +1127,46 @@ docs/03-业务模块/Redcap/ # REDCap文档体系(新增) - 规格: 2核4GB - 内网地址: `pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432` - 数据库: `ai_clinical_research` - - **数据迁移**: ✅ 完成(90MB SQL文件,约12秒导入) - - **Schema验证**: ✅ 11个Schema全部迁移成功 - - **数据验证**: ✅ 用户3条、项目2条、文献1204条 - - **部署时间**: 2025-12-24 + - **Schema**: 14 个隔离 Schema(platform/aia/pkb/asl/dc/iit/ssa/ssa_schema/st/rvw/admin/common/capability/ekb) + - **扩展**: pgvector 0.8.1 + pg_bigm 1.2 + - **Prisma 迁移**: 15 个已应用(含 2026-02-27 类型对齐迁移) - ✅ **OSS对象存储** - - Bucket: `ai-clinical-research` - - 存储类型: 标准存储(同城冗余) + - 4 个 Bucket(生产/开发 × 数据/静态) - 内网域名: `ai-clinical-research.oss-cn-beijing-internal.aliyuncs.com` - - RAM用户: `oss-bucket-put-object@1991407246109125.onaliyun.com` - - AccessKey: 已配置(不公开) #### 3. 容器镜像服务(ACR) -- ✅ **命名空间**: `ai-clinical` - ✅ **Registry**: `crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com` -- ✅ **已推送镜像**: - - **前端Nginx**: `ai-clinical_frontend-nginx:v1.0`(约50MB) - - 构建时间: 2025-12-24 - - 基础镜像: `nginx:alpine` - - 功能: React SPA + Nginx反向代理 + 动态环境变量 - - 配置文件: `frontend-v2/Dockerfile`, `nginx.conf`, `.dockerignore` - - - **Python微服务**: `python-extraction:v1.0`(1.12GB) - - 构建时间: 2025-12-24 - - 基础镜像: `python:3-slim` - - 功能: PDF提取(PyMuPDF)+ 数据清洗(pandas/numpy/polars) - - 特性: 移除Nougat(减小1.5GB)、使用阿里云Debian源 - - 配置文件: `extraction_service/Dockerfile`, `requirements-prod.txt`, `.dockerignore` - - - **Node.js后端**: `backend-service:v1.0`(838MB,压缩后~186MB)✨ 新增! - - 构建时间: 2025-12-24(约5分钟) - - 基础镜像: `node:alpine` - - 构建策略: 改进版方案B(本地编译+Docker打包) - - 技术突破: 修复200+TypeScript错误、手动补全30+Prisma关系字段 - - 架构特性: Postgres-Only(pg-boss队列+PostgreSQL缓存) - - 配置文件: `backend/Dockerfile`, `backend/.dockerignore`, `backend/prisma/schema.prisma` +- ✅ **已推送镜像**: 4 个 + - **前端Nginx**: `ai-clinical_frontend-nginx` + - **Node.js后端**: `backend-service` + - **Python微服务**: `python-extraction` + - **R 统计引擎**: `r-statistics-service`(含 meta 包) -### 🚧 进行中 +#### 4. SAE 应用(全部运行中) +- ✅ **Python微服务** — 内网:`172.17.173.66:8000`(1核2GB) +- ✅ **Node.js后端** — 内网:`172.17.173.73:3001`(2核4GB) +- ✅ **前端Nginx** — 内网:`172.17.173.72:80`(1核2GB) +- ✅ **R 统计引擎** — 通过后端调用 -#### 4. SAE应用部署 -- ✅ **Python微服务**: 已成功部署到SAE轻量版 - - 应用名称: `python-extraction-test` - - 规格: 1核2GB - - 内网地址: `http://172.17.173.66:8000` - - 状态: 运行中 ✅ +### 📊 部署文档体系(2026-02-27 重构) -- ⏳ **Node.js后端**: 镜像已推送,待部署到SAE - - 目标规格: 1核2GB(测试环境) - - 端口: 8000 - - 健康检查: `/api/health` - -- ⏳ **Node.js后端**: Docker镜像待构建 - - 目标规格: 2核4GB - - 端口: 3001 - - 依赖: RDS PostgreSQL - -- ⏳ **前端Nginx**: 镜像已推送,待部署到SAE - - 目标规格: 1核2GB - - 端口: 80 - - 需配置: 后端API内网地址 +**核心文档**(位于 `docs/05-部署文档/`): +- ⭐ [00-阿里云SAE最新真实状态记录.md](../05-部署文档/00-阿里云SAE最新真实状态记录.md) — 生产环境实时状态 +- ⭐ [01-日常更新操作手册.md](../05-部署文档/01-日常更新操作手册.md) — 构建/推送/部署 SOP +- ⭐ [03-待部署变更清单.md](../05-部署文档/03-待部署变更清单.md) — 待部署变更追踪 -### 📋 待完成 +**历史文档**:已归档至 `docs/05-部署文档/_archive-2025首次部署/` -- [ ] Python微服务部署到SAE -- [ ] Node.js后端Docker镜像构建 -- [ ] Node.js后端部署到SAE -- [ ] 前端Nginx部署到SAE -- [ ] 配置服务间内网通信 -- [ ] 全链路验证测试 -- [ ] Dify AI服务部署(可选) +### 📚 数据库文档体系(2026-02-27 新建) -### 📊 部署文档 - -**部署进度总览**: -- [00-部署进度总览.md](../05-部署文档/00-部署进度总览.md) - 🎯 **一站式部署状态查看** - -**操作手册**: -- [07-前端Nginx-SAE部署操作手册.md](../05-部署文档/07-前端Nginx-SAE部署操作手册.md) -- [08-PostgreSQL数据库部署操作手册.md](../05-部署文档/08-PostgreSQL数据库部署操作手册.md) -- Python微服务SAE部署操作手册(待创建) - -**技术指南**: -- [01-快速部署SOP-零基础版.md](../05-部署文档/01-快速部署SOP-零基础版.md) - 完整部署流程 -- [04-Python微服务-SAE容器部署指南.md](../05-部署文档/04-Python微服务-SAE容器部署指南.md) -- [06-前端Nginx-SAE容器部署指南.md](../05-部署文档/06-前端Nginx-SAE容器部署指南.md) - -### 🎯 部署关键成就 - -1. **PostgreSQL数据迁移** ✅ - - 采用`pg_dump`全量导出/导入方案 - - 11个Schema完整迁移 - - 数据一致性验证通过 - - 安全加固(外网访问已关闭) - -2. **前端Nginx镜像优化** ✅ - - 解决Docker Hub网络问题(使用通用标签) - - 修复30个TypeScript编译错误 - - 多阶段构建优化 - - 健康检查通过 - -3. **Python微服务镜像优化** ✅ - - 移除Nougat OCR(减小1.5GB) - - 使用阿里云Debian镜像源(解决apt-get网络问题) - - 保留数据清洗功能(pandas/numpy/polars) - - 运行时依赖优化(libgl1、libglib2.0) - -4. **镜像配置文件Git管理** ✅ - - Dockerfile: ✅ 已提交Git(构建蓝图) - - .dockerignore: ✅ 已提交Git(优化构建) - - 依赖文件: ✅ 已提交Git(可复现) - - 敏感信息: ❌ 禁止提交(.env等) +**核心文档**(位于 `docs/01-平台基础层/07-数据库/`): +- [00-数据库架构总览.md](../01-平台基础层/07-数据库/00-数据库架构总览.md) — 14 个 Schema、表结构、扩展 +- [01-Prisma迁移历史与变更日志.md](../01-平台基础层/07-数据库/01-Prisma迁移历史与变更日志.md) — 15 个迁移记录 +- [02-环境状态对照表.md](../01-平台基础层/07-数据库/02-环境状态对照表.md) — 本地 vs 测试 RDS +- [03-技术债务追踪.md](../01-平台基础层/07-数据库/03-技术债务追踪.md) — 6 项技术债务 +- [04-种子数据管理.md](../01-平台基础层/07-数据库/04-种子数据管理.md) — Prompt/SSA/Agent 种子数据 +- [05-PostgreSQL扩展与特性.md](../01-平台基础层/07-数据库/05-PostgreSQL扩展与特性.md) — pgvector/pg_bigm/pg-boss ### 💰 当前运行成本估算 @@ -1247,10 +1177,10 @@ docs/03-业务模块/Redcap/ # REDCap文档体系(新增) | NAT网关 | 小型 | ¥60 | ✅ 运行中 | | EIP流量 | 5Mbps | ¥40 | ✅ 运行中 | | ACR镜像仓库 | 个人版 | ¥0(免费) | ✅ 运行中 | -| SAE - Python | 1核2GB×1 | ¥60 | ⏳ 待部署 | -| SAE - Node.js | 2核4GB×1 | ¥120 | ⏳ 待部署 | -| SAE - Frontend | 1核2GB×1 | ¥60 | ⏳ 待部署 | -| **总计** | - | **¥602/月** | 部署中 | +| SAE - Python | 1核2GB×1 | ¥60 | ✅ 运行中 | +| SAE - Node.js | 2核4GB×1 | ¥120 | ✅ 运行中 | +| SAE - Frontend | 1核2GB×1 | ¥60 | ✅ 运行中 | +| **总计** | - | **¥602/月** | ✅ 全部运行中 | --- @@ -1296,9 +1226,11 @@ AIclinicalresearch/ ├── docs/ # 📚 文档体系 │ ├── 00-系统总体设计/ # 架构设计 │ ├── 01-平台基础层/ # 平台能力 +│ │ └── 07-数据库/ # 🆕 数据库文档(6篇核心文档) │ ├── 02-通用能力层/ # LLM、RAG等 │ ├── 03-业务模块/ # 各模块文档 -│ ├── 04-开发规范/ # 云原生规范等 +│ ├── 04-开发规范/ # 云原生规范 + 数据库规范 v3.0 +│ ├── 05-部署文档/ # 🆕 部署操作手册 + 变更清单 │ └── 08-项目管理/ # 计划和进度 │ └── prisma/ @@ -1358,6 +1290,8 @@ AIclinicalresearch/ | **2026-01-21** | **🎉 Dify替换完成** | ✅ PKB 成功替换 Dify,完全使用自研 pgvector RAG 引擎 | | **2026-01-22** | **🆕 OSS存储集成** | ✅ 阿里云OSS接入,PKB文档存储云端化,建立存储开发规范 | | **2026-02-22** | **SSA Phase I-IV 完成** 🎉 | ✅ Session黑板+意图路由+对话LLM+方法咨询+QPER集成,E2E 107/107 | +| **2026-02-26** | **ASL 工具 4+5 完成** 🎉 | ✅ SR图表生成器+Meta分析引擎+R Docker meta包+E2E 36/36 | +| **2026-02-27** | **DB文档+部署体系** 📚 | ✅ 6篇数据库文档+部署归档+统一操作手册+开发规范v3.0+Schema对齐 | | **当前** | **PKB模块生产可用** | ✅ 核心功能全部实现(95%),自研RAG+OSS存储上线 | | **2026-01-07 晚** | **RVW模块开发完成** 🎉 | ✅ Phase 1-3完成(后端迁移+数据库扩展+前端重构) | @@ -1445,11 +1379,18 @@ AIclinicalresearch/ - [DC模块README](../03-业务模块/DC-数据清洗整理/README.md) - [DC Day3完成总结](../03-业务模块/DC-数据清洗整理/06-开发记录/Day3完成总结.md) -### 🚀 部署文档(新增) -- ⭐ [00-部署进度总览.md](../05-部署文档/00-部署进度总览.md) - **一站式部署状态查看** -- [01-快速部署SOP-零基础版.md](../05-部署文档/01-快速部署SOP-零基础版.md) - 完整部署流程 -- [07-前端Nginx-SAE部署操作手册.md](../05-部署文档/07-前端Nginx-SAE部署操作手册.md) -- [08-PostgreSQL数据库部署操作手册.md](../05-部署文档/08-PostgreSQL数据库部署操作手册.md) +### 🚀 部署文档 +- ⭐ [00-阿里云SAE最新真实状态记录.md](../05-部署文档/00-阿里云SAE最新真实状态记录.md) - 生产环境实时状态 +- ⭐ [01-日常更新操作手册.md](../05-部署文档/01-日常更新操作手册.md) - 构建/推送/部署 SOP +- ⭐ [03-待部署变更清单.md](../05-部署文档/03-待部署变更清单.md) - 待部署变更追踪 + +### 🗄️ 数据库文档(2026-02-27 新建) +- ⭐ [00-数据库架构总览.md](../01-平台基础层/07-数据库/00-数据库架构总览.md) - 14 个 Schema + 表结构 +- [01-Prisma迁移历史与变更日志.md](../01-平台基础层/07-数据库/01-Prisma迁移历史与变更日志.md) - 迁移记录 +- [02-环境状态对照表.md](../01-平台基础层/07-数据库/02-环境状态对照表.md) - 本地 vs RDS +- [03-技术债务追踪.md](../01-平台基础层/07-数据库/03-技术债务追踪.md) - 技术债务清单 +- [04-种子数据管理.md](../01-平台基础层/07-数据库/04-种子数据管理.md) - 种子数据维护 +- [05-PostgreSQL扩展与特性.md](../01-平台基础层/07-数据库/05-PostgreSQL扩展与特性.md) - pgvector/pg_bigm/pg-boss ### 🏗️ 架构设计 - [平台基础设施规划](../09-架构实施/04-平台基础设施规划.md) @@ -1542,11 +1483,11 @@ npm run dev # http://localhost:3000 - 📋 **未开始**:ST ### 部署完成度 -- ✅ **基础设施**:VPC(100%)、NAT网关(100%)、安全组(100%) -- ✅ **数据存储**:RDS PostgreSQL(100%)、OSS(100%) -- ✅ **容器镜像**:前端Nginx(100%)、Python微服务(100%)、Node.js后端(100%)✨ 新增! -- ✅ **SAE应用**:Python微服务(100%,已运行)、Node.js后端(镜像已推送,待部署)、前端Nginx(待部署) -- 📋 **验证测试**:全链路测试(待进行) +- ✅ **基础设施**:VPC(100%)、NAT网关(100%)、安全组(100%)、CLB(100%) +- ✅ **数据存储**:RDS PostgreSQL(100%,14 Schema)、OSS(100%,4 Bucket) +- ✅ **容器镜像**:前端Nginx + Node.js后端 + Python微服务 + R统计引擎(全部 100%) +- ✅ **SAE应用**:全部 4 个服务运行中(Python + Node.js + Frontend + R) +- ✅ **数据库文档**:6 篇核心文档 + 开发规范 v3.0 + 待部署变更清单 ### 测试覆盖率 - **平台基础层**:100%(8/8模块全部通过) @@ -1688,9 +1629,9 @@ if (items.length >= 50) { --- -**文档版本**:v6.3 -**最后更新**:2026-02-26 -**本次更新**:ASL 工具 4 SR 图表生成器 + 工具 5 Meta 分析引擎开发完成(PRISMA 中英切换 + Meta 分析 HR/二分类/连续型 + R Docker meta 包 + E2E 36/36) +**文档版本**:v6.4 +**最后更新**:2026-02-27 +**本次更新**:数据库文档体系建立(6 篇核心文档)+ 部署文档整理归档 + Prisma Schema 类型漂移修正 + 数据库开发规范 v3.0 + Cursor Rule 自动提醒 + 部署状态更新为全部运行中 --- diff --git a/docs/01-平台基础层/07-数据库/00-数据库架构总览.md b/docs/01-平台基础层/07-数据库/00-数据库架构总览.md new file mode 100644 index 00000000..b9228128 --- /dev/null +++ b/docs/01-平台基础层/07-数据库/00-数据库架构总览.md @@ -0,0 +1,163 @@ +# 数据库架构总览 + +> 版本: v1.0 +> 更新日期: 2026-02-27 +> 数据来源: 本地开发数据库实时查询 + +--- + +## 1. 基本信息 + +| 项目 | 值 | +|------|-----| +| 数据库引擎 | PostgreSQL 15.15 | +| ORM | Prisma 6.17.0 | +| 数据库名 | ai_clinical_research | +| Schema 数量 | 14 个(含 public) | +| 表总数 | 96 张 | +| 列总数 | 1217 个 | +| 索引总数 | 339 个 | +| 外键关系 | 53 条 | +| 扩展 | pgvector 0.8.1, pg_bigm 1.2 | +| 迁移历史 | 14 个已应用迁移 | + +--- + +## 2. Schema 全景图 + +``` + AI 临床研究平台 — 数据库 Schema 全景图 + ┌─────────────────────────────────────────────────────────────────────────┐ + │ platform_schema (19 表) │ + │ 用户、租户、权限、模块、pg-boss 队列 │ + │ tenants → users → tenant_members → departments │ + │ modules → permissions → role_permissions → user_modules │ + │ job / queue / schedule / subscription (pg-boss 异步任务) │ + ├─────────────────────────────────────────────────────────────────────────┤ + │ capability_schema (4 表) │ + │ Prompt 模板管理 + 系统知识库 │ + │ prompt_templates → prompt_versions │ + │ system_knowledge_bases → system_kb_documents │ + ├─────────────────────────────────────────────────────────────────────────┤ + │ agent_schema (6 表) │ ekb_schema (3 表) │ + │ 通用 Agent 定义/编排/追踪 │ 企业知识库(向量) │ + │ agent_definitions │ ekb_knowledge_base │ + │ → agent_stages │ → ekb_document │ + │ → agent_prompts │ → ekb_chunk (vector 1024) │ + │ → agent_sessions │ │ + │ → agent_traces │ │ + │ → reflexion_rules │ │ + ├───────────────────────────────┴────────────────────────────────────────┤ + │ admin_schema (2 表) │ + │ 运营管理:admin_operation_logs, simple_logs │ + ├─────────────────────────────────────────────────────────────────────────┤ + │ │ + │ ┌── 业务模块层 ──────────────────────────────────────────────────────┐ │ + │ │ │ │ + │ │ iit_schema (20 表) │ ssa_schema (11 表) │ │ + │ │ IIT 临床试验管理 Agent │ 智能统计分析 │ │ + │ │ projects (中心) │ ssa_sessions (中心) │ │ + │ │ → conversation_history │ → ssa_messages │ │ + │ │ → audit_logs │ → ssa_execution_logs │ │ + │ │ → pending_actions │ → ssa_workflows │ │ + │ │ → task_runs │ → ssa_workflow_steps │ │ + │ │ → user_mappings │ ssa_tools_library (vector 1024) │ │ + │ │ field_metadata, qc_logs │ ssa_r_code_library │ │ + │ │ equery, critical_events │ ssa_decision_table │ │ + │ │ skills, weekly_reports │ ssa_guardrail_config │ │ + │ │ agent_trace, record_summary│ ssa_param_mapping │ │ + │ │ qc_reports, qc_project_stats│ ssa_interpretation_templates │ │ + │ │ │ │ │ + │ │ asl_schema (11 表) │ rvw_schema (1 表) │ │ + │ │ AI 智能文献 │ 稿件审查 │ │ + │ │ screening_projects (中心) │ review_tasks │ │ + │ │ → literatures │ │ │ + │ │ → screening_tasks │ dc_schema (6 表) │ │ + │ │ → screening_results │ 数据清洗整理 │ │ + │ │ → fulltext_screening_* │ dc_templates │ │ + │ │ research_tasks │ → dc_extraction_tasks │ │ + │ │ extraction_templates │ → dc_extraction_items │ │ + │ │ → extraction_project_* │ dc_tool_c_sessions │ │ + │ │ → extraction_tasks │ dc_tool_c_ai_history │ │ + │ │ → extraction_results│ dc_health_checks │ │ + │ │ │ │ │ + │ │ aia_schema (3 表) │ protocol_schema (2 表) │ │ + │ │ AI 智能问答 │ 方案 Agent │ │ + │ │ projects → conversations │ protocol_contexts │ │ + │ │ → messages │ → protocol_generations │ │ + │ │ │ │ │ + │ │ pkb_schema (5 表) │ public (3 表) │ │ + │ │ 个人知识库 │ _prisma_migrations │ │ + │ │ knowledge_bases │ users (遗留), admin_logs (遗留) │ │ + │ │ → documents │ │ │ + │ │ → batch_tasks │ │ │ + │ │ → batch_results │ │ │ + │ │ task_templates │ │ │ + │ └─────────────────────────────┴──────────────────────────────────────┘ │ + └─────────────────────────────────────────────────────────────────────────┘ +``` + +--- + +## 3. Schema 清单 + +| # | Schema | 表数 | 列数 | 归属模块 | 职责描述 | +|---|--------|------|------|----------|---------| +| 1 | `platform_schema` | 19 | ~200 | 平台基础层 | 用户、租户、权限、pg-boss 任务队列 | +| 2 | `capability_schema` | 4 | ~38 | 通用能力层 | Prompt 模板管理、系统知识库 | +| 3 | `agent_schema` | 6 | ~71 | 通用能力层 | 通用 Agent 定义、编排、运行追踪 | +| 4 | `ekb_schema` | 3 | ~38 | 通用能力层 | 企业知识库(向量检索) | +| 5 | `admin_schema` | 2 | ~21 | 运营管理 | 操作日志、简单日志 | +| 6 | `iit_schema` | 20 | ~246 | IIT Manager Agent | 项目管理、质控、eQuery、重大事件 | +| 7 | `ssa_schema` | 11 | ~117 | 智能统计分析 | 会话、工作流、工具库、R 代码库 | +| 8 | `asl_schema` | 11 | ~235 | AI 智能文献 | 文献筛选、全文复筛、数据提取 | +| 9 | `rvw_schema` | 1 | ~26 | 稿件审查 | 审查任务 | +| 10 | `dc_schema` | 6 | ~83 | 数据清洗 | 模板、提取任务、AI 对话 | +| 11 | `aia_schema` | 3 | ~32 | AI 智能问答 | 项目、对话、消息 | +| 12 | `protocol_schema` | 2 | ~29 | 方案 Agent | 方案上下文、方案生成 | +| 13 | `pkb_schema` | 5 | ~66 | 个人知识库 | 知识库、文档、批处理 | +| 14 | `public` | 3 | ~31 | 系统/遗留 | Prisma 迁移表 + 遗留 users/admin_logs | + +**合计:14 个 Schema,96 张表,~1217 列** + +--- + +## 4. 向量检索表 + +| Schema | 表 | 向量列 | 维度 | 用途 | +|--------|-----|--------|------|------| +| `iit_schema` | `conversation_history` | `embedding` | 1536 | IIT 对话语义搜索 | +| `ekb_schema` | `ekb_chunk` | `embedding` | 1024 | 企业知识库 RAG 检索 | +| `ssa_schema` | `ssa_tools_library` | `embedding` | 1024 | SSA 工具语义匹配 | + +--- + +## 5. pg-boss 任务队列表 + +`platform_schema` 中有 5 张 pg-boss 管理的表: + +| 表 | 职责 | +|-----|------| +| `job` | 活跃任务 | +| `job_common` | 公共任务配置 | +| `queue` | 队列定义 | +| `schedule` | 定时任务调度 | +| `subscription` | 事件订阅 | + +> 详细使用指南见 `docs/07-运维文档/01-PgBoss队列监控与维护.md` + +--- + +## 6. 跨文档索引 + +| 关注点 | 文档位置 | +|--------|---------| +| 数据库开发规范 | `docs/04-开发规范/09-数据库开发规范.md` | +| 迁移历史 | `docs/01-平台基础层/07-数据库/01-Prisma迁移历史与变更日志.md` | +| 环境差异 | `docs/01-平台基础层/07-数据库/02-环境状态对照表.md` | +| 技术债务 | `docs/01-平台基础层/07-数据库/03-技术债务追踪.md` | +| 种子数据 | `docs/01-平台基础层/07-数据库/04-种子数据管理.md` | +| 扩展特性 | `docs/01-平台基础层/07-数据库/05-PostgreSQL扩展与特性.md` | +| 部署迁移 | `docs/05-部署文档/*/01-数据库迁移方案.md` | +| 运维注意事项 | `docs/07-运维文档/03-数据库迁移注意事项.md` | +| Prisma 操作指南 | `docs/09-架构实施/J技术架构咨询/数据库同步规范与Prisma操作指南.md` | diff --git a/docs/01-平台基础层/07-数据库/01-Prisma迁移历史与变更日志.md b/docs/01-平台基础层/07-数据库/01-Prisma迁移历史与变更日志.md new file mode 100644 index 00000000..5e136d87 --- /dev/null +++ b/docs/01-平台基础层/07-数据库/01-Prisma迁移历史与变更日志.md @@ -0,0 +1,179 @@ +# Prisma 迁移历史与变更日志 + +> 版本: v1.0 +> 更新日期: 2026-02-27 +> 维护说明: 每次新增迁移后,在此文档追加记录 + +--- + +## 1. 迁移时间线总览 + +当前共 **14 个已应用迁移**,覆盖 2025-10 至 2026-02 的演进过程。 + +``` +2025-10 ████ init + conversations + batch + review_tasks +2025-12 █ column_mapping +2026-01 █ system_knowledge_base +2026-02 ████████ IIT agent + CRA QC + SSA module + DeepResearch V2 + + extraction template + db push drift patch + + eQuery/critical events + type alignment +``` + +--- + +## 2. 完整迁移清单 + +### #1 — 20251010075003_init + +| 属性 | 值 | +|------|-----| +| 应用时间 | 2026-01-26 08:17:06 | +| 影响 Schema | public, platform_schema, aia_schema, pkb_schema, dc_schema, iit_schema, asl_schema, ekb_schema, agent_schema | +| 核心内容 | 系统初始化,创建全部 schema + 核心表(users, tenants, conversations, knowledge_bases, documents, screening_projects, literatures, agent_definitions 等) | +| 说明 | 全量初始化迁移,包含 pgvector 和 pg_bigm 扩展安装 | + +### #2 — 20251010122727_add_conversation_metadata_deleted_at + +| 属性 | 值 | +|------|-----| +| 应用时间 | 2026-01-26 08:17:14 | +| 影响 Schema | iit_schema | +| 核心内容 | conversation_history 表增加 metadata(JSONB) 和 deleted_at(TIMESTAMP) 列 | + +### #3 — 20251012124747_add_batch_processing_module + +| 属性 | 值 | +|------|-----| +| 应用时间 | 2026-01-26 08:17:16 | +| 影响 Schema | pkb_schema | +| 核心内容 | 新增 batch_tasks 和 batch_results 表,支持批处理功能 | + +### #4 — 20251014120128_add_review_tasks + +| 属性 | 值 | +|------|-----| +| 应用时间 | 2026-01-26 08:17:17 | +| 影响 Schema | rvw_schema | +| 核心内容 | 创建 rvw_schema 和 review_tasks 表 | + +### #5 — 20251208_add_column_mapping + +| 属性 | 值 | +|------|-----| +| 应用时间 | 2026-01-26 08:17:19 | +| 影响 Schema | dc_schema | +| 核心内容 | dc_extraction_tasks 表增加 column_mapping(JSONB) 列 | + +### #6 — 20260128_add_system_knowledge_base + +| 属性 | 值 | +|------|-----| +| 应用时间 | 2026-01-28 12:36:17 | +| 影响 Schema | capability_schema | +| 核心内容 | 创建 system_knowledge_bases 和 system_kb_documents 表,支持系统级知识库管理 | + +### #7 — 20260207112544_add_iit_manager_agent_tables + +| 属性 | 值 | +|------|-----| +| 应用时间 | 2026-02-07 03:26:29 | +| 影响 Schema | iit_schema | +| 核心内容 | IIT Manager Agent V2.x 表结构:record_summary, weekly_reports, project_memory, agent_trace, skills, pii_audit_log, qc_project_stats 等 | + +### #8 — 20260208134925_add_cra_qc_engine_support + +| 属性 | 值 | +|------|-----| +| 应用时间 | 2026-02-08 05:49:47 | +| 影响 Schema | iit_schema | +| 核心内容 | CRA 质控引擎支持:qc_logs, qc_reports, form_templates 表 + projects 表增加质控相关列 | + +### #9 — 20260219_add_ssa_module + +| 属性 | 值 | +|------|-----| +| 应用时间 | 2026-02-19 06:21:29 | +| 影响 Schema | ssa_schema | +| 核心内容 | 创建 ssa_schema 及 9 张表:ssa_sessions, ssa_messages, ssa_execution_logs, ssa_tools_library, ssa_r_code_library, ssa_decision_table, ssa_guardrail_config, ssa_param_mapping, ssa_interpretation_templates | + +### #10 — 20260223_add_deep_research_v2_fields + +| 属性 | 值 | +|------|-----| +| 应用时间 | 2026-02-23 01:44:19 | +| 影响 Schema | asl_schema | +| 核心内容 | research_tasks 表增加 6 列:target_sources, confirmed_requirement, ai_intent_summary, execution_logs, synthesis_report, result_list | +| ⚠️ 注意 | 此迁移依赖 research_tasks 表(由 prisma db push 创建),Shadow DB 重放会失败 | + +### #11 — 20260225_add_extraction_template_engine + +| 属性 | 值 | +|------|-----| +| 应用时间 | 2026-02-25 00:07:57 | +| 影响 Schema | asl_schema | +| 核心内容 | 全文提取模板引擎:extraction_templates, extraction_project_templates, extraction_tasks, extraction_results 4 张表 | + +### #12 — 20260227_patch_db_push_drift + +| 属性 | 值 | +|------|-----| +| 应用时间 | 2026-02-27 01:11:55 | +| 影响 Schema | iit_schema, ssa_schema, rvw_schema | +| 核心内容 | 补丁迁移,覆盖 prisma db push 创建的结构:field_metadata, qc_logs, qc_reports, form_templates(iit), ssa_workflows, ssa_workflow_steps(ssa), review_tasks 新增 8 列 + 1 索引(rvw) | +| 性质 | 使用 `CREATE TABLE IF NOT EXISTS` 和 `ADD COLUMN IF NOT EXISTS` 保证幂等 | + +### #13 — 20260226_add_equery_critical_events_cron + +| 属性 | 值 | +|------|-----| +| 应用时间 | 2026-02-27 01:12:08 | +| 影响 Schema | iit_schema | +| 核心内容 | eQuery 电子质疑表 + critical_events 重大事件表 + projects 增加 cron_enabled/cron_expression 列 | +| 特殊类型 | id 使用 PostgreSQL 原生 UUID,时间戳使用 TIMESTAMPTZ | + +### #14 — 20260227_align_schema_with_db_types + +| 属性 | 值 | +|------|-----| +| 应用时间 | 2026-02-27 05:44:11 | +| 影响 Schema | ssa_schema | +| 核心内容 | 对齐 Schema 类型注解与数据库实际类型:ssa_workflows/ssa_workflow_steps 的 VARCHAR 长度和 TIMESTAMP 精度 + 清理 2 个重复外键 | +| 性质 | Schema 精度对齐,SQL 对实际数据库为幂等操作 | + +--- + +## 3. 迁移创建方式说明 + +| 方式 | 适用场景 | 涉及迁移 | +|------|---------|---------| +| `prisma migrate dev` | 标准开发流程 | #1 ~ #9 | +| `prisma migrate dev --create-only` | 仅生成不执行 | — | +| 手动创建 + `prisma migrate resolve --applied` | Shadow DB 无法重放时 | #12, #13, #14 | +| `prisma db push` (⚠️ 非标准) | 快速原型,不产生迁移记录 | 造成了 drift patch 的必要性 | + +--- + +## 4. 维护规则 + +### 新增迁移时,在本文档追加: + +```markdown +### #N — YYYYMMDD_migration_name + +| 属性 | 值 | +|------|-----| +| 应用时间 | YYYY-MM-DD HH:MM:SS | +| 影响 Schema | xxx_schema | +| 核心内容 | 简述变更 | +``` + +### 检查迁移状态: + +```bash +# 查看本地已应用迁移 +docker exec ai-clinical-postgres psql -U postgres -d ai_clinical_research \ + -c "SELECT migration_name, finished_at FROM _prisma_migrations ORDER BY started_at;" + +# 查看 RDS 已应用迁移 +npx prisma migrate status +``` diff --git a/docs/01-平台基础层/07-数据库/02-环境状态对照表.md b/docs/01-平台基础层/07-数据库/02-环境状态对照表.md new file mode 100644 index 00000000..17dce134 --- /dev/null +++ b/docs/01-平台基础层/07-数据库/02-环境状态对照表.md @@ -0,0 +1,102 @@ +# 环境状态对照表 + +> 版本: v1.0 +> 更新日期: 2026-02-27 +> 维护说明: 每次部署后更新此表,确保三环境状态可追溯 + +--- + +## 1. 环境概览 + +| 环境 | 数据库类型 | 地址 | 数据库名 | 用户 | +|------|----------|------|---------|------| +| **本地开发** | Docker (pgvector/pgvector:pg15) | localhost:5432 | ai_clinical_research | postgres | +| **测试环境** | 阿里云 RDS PostgreSQL 15 | pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432 | ai_clinical_research_test | airesearch | +| **生产环境** | 待部署 | — | — | — | + +--- + +## 2. 迁移状态对比 + +> 截止日期:2026-02-27 + +| # | 迁移名 | 本地开发 | 测试 RDS | 说明 | +|---|--------|---------|---------|------| +| 1 | 20251010075003_init | ✅ | ✅ | | +| 2 | 20251010122727_add_conversation_metadata_deleted_at | ✅ | ✅ | | +| 3 | 20251012124747_add_batch_processing_module | ✅ | ✅ | | +| 4 | 20251014120128_add_review_tasks | ✅ | ✅ | | +| 5 | 20251208_add_column_mapping | ✅ | ✅ | | +| 6 | 20260128_add_system_knowledge_base | ✅ | ✅ | | +| 7 | 20260207112544_add_iit_manager_agent_tables | ✅ | ✅ | 0227 部署时应用 | +| 8 | 20260208134925_add_cra_qc_engine_support | ✅ | ✅ | 0227 部署时应用 | +| 9 | 20260219_add_ssa_module | ✅ | ✅ | 0227 部署时应用 | +| 10 | 20260223_add_deep_research_v2_fields | ✅ | ✅ | 0227 部署时应用 | +| 11 | 20260225_add_extraction_template_engine | ✅ | ✅ | 0227 部署时应用 | +| 12 | 20260227_patch_db_push_drift | ✅ | ✅ | 0227 部署时应用 | +| 13 | 20260226_add_equery_critical_events_cron | ✅ | ✅ | 0227 部署时应用 | +| 14 | 20260227_align_schema_with_db_types | ✅ | ❌ | 本地对齐,尚未部署到 RDS | + +--- + +## 3. PostgreSQL 扩展对比 + +| 扩展 | 本地开发 | 测试 RDS | 说明 | +|------|---------|---------|------| +| plpgsql | 1.0 | 1.0 | PostgreSQL 内置 | +| pgvector (vector) | 0.8.1 | 0.8.0 | 向量搜索,RDS 版本略低 | +| pg_bigm | 1.2 | 1.2 | 中文全文检索 | + +--- + +## 4. Schema 结构对比 + +| Schema | 本地开发 表数 | 测试 RDS 表数 | 差异说明 | +|--------|-------------|-------------|---------| +| platform_schema | 19 | 19 | 一致 | +| capability_schema | 4 | 4 | 一致 | +| agent_schema | 6 | 6 | 一致 | +| ekb_schema | 3 | 3 | 一致 | +| admin_schema | 2 | 2 | 一致 | +| iit_schema | 20 | 20 | 一致(0227 部署后) | +| ssa_schema | 11 | 11 | RDS 缺少 #14 的类型对齐 | +| asl_schema | 11 | 11 | 一致 | +| rvw_schema | 1 | 1 | 一致(0227 补 8 列后) | +| dc_schema | 6 | 6 | 一致 | +| aia_schema | 3 | 3 | 一致 | +| protocol_schema | 2 | 2 | 一致 | +| pkb_schema | 5 | 5 | 一致 | +| public | 3 | 3 | 一致 | + +--- + +## 5. 已知的环境差异 + +### 5.1 测试 RDS 待部署项 + +| 项目 | 内容 | 优先级 | 风险 | +|------|------|--------|------| +| 迁移 #14 | ssa_workflows 类型精度对齐 + 重复 FK 清理 | 低 | 无数据影响,幂等 SQL | + +### 5.2 本地开发特有 + +| 项目 | 说明 | +|------|------| +| `prisma db push` 产生的额外结构 | 部分表/列未通过迁移创建,已由 #12 drift patch 覆盖 | +| Shadow DB 重放失败 | #10 迁移依赖 `research_tasks`(非迁移创建),影响 `prisma migrate dev` | + +--- + +## 6. 更新日志 + +| 日期 | 操作人 | 变更 | +|------|--------|------| +| 2026-02-27 | AI 助手 | 初始化文档,记录 0227 部署后状态 | + +--- + +## 7. 维护规则 + +- **每次部署后**:更新第 2 节迁移状态和第 4 节表数 +- **新增扩展后**:更新第 3 节扩展对比 +- **发现差异时**:记录在第 5 节,标注优先级和风险 diff --git a/docs/01-平台基础层/07-数据库/03-技术债务追踪.md b/docs/01-平台基础层/07-数据库/03-技术债务追踪.md new file mode 100644 index 00000000..18759e8b --- /dev/null +++ b/docs/01-平台基础层/07-数据库/03-技术债务追踪.md @@ -0,0 +1,123 @@ +# 数据库技术债务追踪 + +> 版本: v1.0 +> 更新日期: 2026-02-27 +> 维护说明: 发现新债务时立即记录,修复后标记状态 + +--- + +## 1. 债务总览 + +| 状态 | 数量 | +|------|------| +| 🔴 待修复 | 2 | +| 🟡 已缓解(带 workaround) | 2 | +| 🟢 已修复 | 2 | + +--- + +## 2. 当前债务清单 + +### TD-001: Shadow DB 重放失败(prisma migrate dev 不可用) + +| 属性 | 值 | +|------|-----| +| 状态 | 🔴 待修复 | +| 发现日期 | 2026-02-27 | +| 影响范围 | 本地开发环境 | +| 严重程度 | 中 — 不影响部署(`prisma migrate deploy` 不使用 Shadow DB) | +| 根因 | 迁移 #10 (`20260223_add_deep_research_v2_fields`) 对 `asl_schema.research_tasks` 执行 ALTER TABLE,但该表由 `prisma db push` 创建,无对应迁移记录。Shadow DB 重放到 #10 时找不到表 | +| 当前影响 | 无法使用 `prisma migrate dev` 生成新迁移,需手动创建 + `prisma migrate resolve` | +| 修复方案 | 在 #10 之前插入补全迁移,创建 `research_tasks` 及其他 `prisma db push` 表。需同时更新 `_prisma_migrations` 表的记录顺序 | +| 修复难度 | 高 — 需仔细梳理所有 `db push` 创建的表,确保不遗漏 | + +### TD-002: equery / critical_events 使用非标准 ID 类型 + +| 属性 | 值 | +|------|-----| +| 状态 | 🟡 已缓解 | +| 发现日期 | 2026-02-27 | +| 影响范围 | iit_schema | +| 严重程度 | 低 — 不影响功能,仅类型不统一 | +| 根因 | 迁移 #13 使用 PostgreSQL 原生 `UUID` 类型和 `TIMESTAMPTZ`,而系统其他表统一使用 `TEXT` + `TIMESTAMP(3)` | +| Workaround | Schema 中已添加 `@db.Uuid` 和 `@db.Timestamptz(6)` 注解对齐,并标注 `// TODO: Tech Debt` | +| 最终修复 | 未来大版本重构时统一 ID 策略(全部 TEXT 或全部 UUID) | + +### TD-003: ssa_workflows / ssa_workflow_steps 类型精度不一致 + +| 属性 | 值 | +|------|-----| +| 状态 | 🟢 已修复 | +| 发现日期 | 2026-02-27 | +| 修复日期 | 2026-02-27 | +| 修复方式 | 迁移 #14 (`20260227_align_schema_with_db_types`) 对齐了 VARCHAR 长度和 TIMESTAMP 精度,清理了 2 个重复 FK | + +### TD-004: Prisma diff 引擎的 vector 类型噪音 + +| 属性 | 值 | +|------|-----| +| 状态 | 🟡 已缓解 | +| 发现日期 | 2026-02-27 | +| 影响范围 | ekb_schema, iit_schema, ssa_schema | +| 严重程度 | 低 — 纯噪音,不影响任何功能 | +| 根因 | Prisma 的 `Unsupported("vector(1024)")` 类型无法被 diff 引擎正确比较,每次 diff 都会输出 3 条 `ALTER COLUMN SET DATA TYPE` 假变更 | +| Workaround | 已知噪音,运行 diff 时忽略 vector 相关行 | +| 最终修复 | 等待 Prisma 原生支持 pgvector 类型 | + +### TD-005: prisma db push 历史遗留 + +| 属性 | 值 | +|------|-----| +| 状态 | 🟢 已修复 | +| 发现日期 | 2026-02-27 | +| 修复日期 | 2026-02-27 | +| 影响范围 | iit_schema, ssa_schema, rvw_schema | +| 修复方式 | 迁移 #12 (`20260227_patch_db_push_drift`) 使用 `CREATE TABLE IF NOT EXISTS` 和 `ADD COLUMN IF NOT EXISTS` 将所有 db push 创建的结构纳入迁移体系 | + +### TD-006: public schema 遗留表 + +| 属性 | 值 | +|------|-----| +| 状态 | 🔴 待修复 | +| 发现日期 | 2026-02-27 | +| 影响范围 | public schema | +| 严重程度 | 极低 — 不影响任何功能 | +| 根因 | `public.users` 和 `public.admin_logs` 是系统早期创建的遗留表,在引入 multi-schema 后已被 `platform_schema.users` 和 `admin_schema.admin_operation_logs` 替代 | +| 修复方案 | 确认无引用后安全删除遗留表 | +| 修复难度 | 低 | + +--- + +## 3. 债务产生根因分析 + +``` +prisma db push 的不规范使用 + ├── 表/列未纳入迁移体系 → TD-005 (已修复) + ├── Shadow DB 无法重放 → TD-001 (待修复) + └── 非标准类型创建 → TD-002, TD-003 (已缓解/已修复) + +Prisma ORM 限制 + └── Unsupported 类型 diff 噪音 → TD-004 (已缓解) + +历史架构演进 + └── multi-schema 前的遗留表 → TD-006 (待修复) +``` + +--- + +## 4. 预防措施 + +| 措施 | 对应规范 | +|------|---------| +| **禁止** 在开发中使用 `prisma db push`(仅限原型探索) | `docs/04-开发规范/09-数据库开发规范.md` | +| 所有 Schema 变更必须通过 `prisma migrate dev` | 同上 | +| 新增迁移后立即更新迁移日志 | `docs/01-平台基础层/07-数据库/01-Prisma迁移历史与变更日志.md` | +| 部署前对比环境差异 | `docs/01-平台基础层/07-数据库/02-环境状态对照表.md` | + +--- + +## 5. 更新日志 + +| 日期 | 操作人 | 变更 | +|------|--------|------| +| 2026-02-27 | AI 助手 | 初始化文档,记录 6 项技术债务 | diff --git a/docs/01-平台基础层/07-数据库/04-种子数据管理.md b/docs/01-平台基础层/07-数据库/04-种子数据管理.md new file mode 100644 index 00000000..219a5d1a --- /dev/null +++ b/docs/01-平台基础层/07-数据库/04-种子数据管理.md @@ -0,0 +1,116 @@ +# 种子数据管理 + +> 版本: v1.0 +> 更新日期: 2026-02-27 +> 维护说明: 新增种子数据类型时,在此文档登记 + +--- + +## 1. 什么是种子数据 + +种子数据(Seed Data)是系统正常运行所必需的初始/模板数据。与用户产生的业务数据不同,种子数据: + +- 在新环境部署时必须初始化 +- 在版本升级时可能需要同步更新 +- 跨环境需要保持一致(或有明确的差异策略) + +--- + +## 2. 种子数据清单 + +### 2.1 Prompt 模板(capability_schema) + +| 表 | 数据内容 | 同步策略 | 说明 | +|-----|---------|---------|------| +| `prompt_templates` | Prompt 定义(SSA_BASE_SYSTEM, SSA_INTENT_ANALYZE 等) | 手动同步 | 每个模块的 AI Prompt 模板 | +| `prompt_versions` | 各 Prompt 的版本记录(v1, v2, ACTIVE 标记) | 跟随模板同步 | 支持版本回退 | + +**当前 Prompt 列表**(需跨环境同步的关键项): + +| Prompt Key | 所属模块 | 说明 | +|------------|---------|------| +| SSA_BASE_SYSTEM | SSA | SSA 基础系统 Prompt | +| SSA_INTENT_ANALYZE | SSA | SSA 意图分析 Prompt | +| IIT_* | IIT | IIT Agent 系列 Prompt | +| RVW_* | RVW | 稿件审查系列 Prompt | +| AIA_* | AIA | AI 智能问答 Prompt | +| PROTOCOL_* | Protocol | 方案 Agent Prompt | + +> 完整 Prompt 清单维护在运营管理后台,此处仅列出关键类别。 + +### 2.2 SSA 工具库(ssa_schema) + +| 表 | 数据内容 | 同步策略 | 说明 | +|-----|---------|---------|------| +| `ssa_tools_library` | 统计工具定义(13 个工具) | SQL INSERT 脚本 | 含 tool_code, params_schema, guardrails 等 | +| `ssa_decision_table` | 统计方法决策表 | SQL INSERT 脚本 | 根据数据特征选择分析方法的规则 | +| `ssa_guardrail_config` | 护栏配置 | SQL INSERT 脚本 | 各工具的前置检验规则 | +| `ssa_param_mapping` | 参数映射 | SQL INSERT 脚本 | LLM 输出到 R 参数的映射 | +| `ssa_interpretation_templates` | 解释模板 | SQL INSERT 脚本 | 统计结果的自然语言解释模板 | +| `ssa_r_code_library` | R 代码模板 | SQL INSERT 脚本 | 13 个统计工具的 R 代码片段 | + +### 2.3 Agent 定义(agent_schema) + +| 表 | 数据内容 | 同步策略 | 说明 | +|-----|---------|---------|------| +| `agent_definitions` | Agent 类型定义 | 手动同步 | IIT Agent、Protocol Agent 等 | +| `agent_stages` | Agent 运行阶段定义 | 跟随 agent 同步 | | +| `reflexion_rules` | Agent 反思规则 | 跟随 agent 同步 | | + +### 2.4 平台基础数据(platform_schema) + +| 表 | 数据内容 | 同步策略 | 说明 | +|-----|---------|---------|------| +| `modules` | 系统模块定义 | 代码内置 | AIA, IIT, ASL, SSA, RVW, DC, PKB 等 | +| `permissions` | 权限定义 | 代码内置 | 各模块的操作权限 | +| `tenants` | 初始租户 | 首次部署时创建 | 至少一个默认租户 | +| `users` | 管理员账号 | 首次部署时创建 | 超级管理员 | + +--- + +## 3. 同步操作指南 + +### 3.1 新环境初始化 + +```bash +# 1. 运行 Prisma 迁移(创建表结构) +npx prisma migrate deploy + +# 2. 运行种子脚本(插入种子数据) +npx prisma db seed +# 或手动执行 SQL 脚本 +``` + +### 3.2 版本升级时同步 + +```bash +# 1. 检查本次升级是否涉及种子数据变更 +# 查看 docs/01-平台基础层/07-数据库/01-Prisma迁移历史与变更日志.md + +# 2. 如有新增 Prompt 或工具定义,准备 INSERT 脚本 +# 3. 在目标环境执行 INSERT ... ON CONFLICT DO UPDATE +``` + +### 3.3 Prompt 同步注意事项 + +- Prompt 数据由**运营管理后台**管理(ADMIN 模块) +- 开发环境的 Prompt 可能带有调试版本,同步到生产前需确认使用 ACTIVE 版本 +- 知识库配置(system_knowledge_bases)跟随 Prompt 同步 + +--- + +## 4. 待建设项 + +| 项目 | 优先级 | 说明 | +|------|--------|------| +| 自动化 seed 脚本 | 高 | 将关键种子数据编写为 `prisma/seed.ts`,支持 `npx prisma db seed` | +| Prompt 导出/导入工具 | 中 | 从运营管理后台导出 JSON,在目标环境导入 | +| SSA 工具库 seed SQL | 中 | 将 13 个工具的定义整理为标准 INSERT 脚本 | + +--- + +## 5. 更新日志 + +| 日期 | 操作人 | 变更 | +|------|--------|------| +| 2026-02-27 | AI 助手 | 初始化文档,梳理种子数据类型和同步策略 | diff --git a/docs/01-平台基础层/07-数据库/05-PostgreSQL扩展与特性.md b/docs/01-平台基础层/07-数据库/05-PostgreSQL扩展与特性.md new file mode 100644 index 00000000..ec0af59c --- /dev/null +++ b/docs/01-平台基础层/07-数据库/05-PostgreSQL扩展与特性.md @@ -0,0 +1,147 @@ +# PostgreSQL 扩展与特性 + +> 版本: v1.0 +> 更新日期: 2026-02-27 +> 维护说明: 新增扩展或变更配置时更新此文档 + +--- + +## 1. 扩展总览 + +| 扩展 | 版本 | 用途 | 安装方式 | 依赖模块 | +|------|------|------|---------|---------| +| **pgvector** (vector) | 0.8.1 | 向量存储与相似度检索 | Docker 镜像内置 | EKB, IIT, SSA | +| **pg_bigm** | 1.2 | 中文/日文双字节全文检索 | Docker 镜像内置 | EKB | +| **plpgsql** | 1.0 | PostgreSQL 过程语言 | 系统内置 | 全局 | + +--- + +## 2. pgvector — 向量搜索 + +### 2.1 基本信息 + +- **Docker 镜像**: `pgvector/pgvector:pg15`(本地开发基础镜像) +- **用途**: 存储文本 embedding 向量,支持语义相似度检索 +- **算法**: 支持 L2 距离、内积、余弦相似度 + +### 2.2 使用表 + +| Schema | 表 | 列 | 维度 | 模型 | 用途 | +|--------|-----|-----|------|------|------| +| `ekb_schema` | `ekb_chunk` | `embedding` | 1024 | 通义千问 Embedding | 企业知识库 RAG 检索 | +| `iit_schema` | `conversation_history` | `embedding` | 1536 | OpenAI ada-002 | IIT 对话历史语义搜索 | +| `ssa_schema` | `ssa_tools_library` | `embedding` | 1024 | 通义千问 Embedding | SSA 工具语义匹配 | + +### 2.3 Prisma 中的声明方式 + +pgvector 在 Prisma 中通过 `Unsupported` 类型声明: + +```prisma +embedding Unsupported("vector(1024)")? +``` + +> ⚠️ 已知限制:Prisma diff 引擎无法正确比较 `Unsupported` 类型,每次 diff 会产生假变更。详见 `03-技术债务追踪.md` TD-004。 + +### 2.4 索引建议 + +对于高频检索的向量列,建议创建 HNSW 索引: + +```sql +CREATE INDEX idx_ekb_chunk_embedding ON ekb_schema.ekb_chunk + USING hnsw (embedding vector_cosine_ops) + WITH (m = 16, ef_construction = 64); +``` + +当前状态:暂未创建向量索引,数据量较小时顺序扫描即可满足性能要求。 + +--- + +## 3. pg_bigm — 中文全文检索 + +### 3.1 基本信息 + +- **用途**: 基于双字节 gram 的模糊搜索,特别适合中文、日文 +- **优势**: 无需分词器,开箱即用,支持 LIKE '%关键词%' 加速 + +### 3.2 使用场景 + +| Schema | 表 | 列 | 用途 | +|--------|-----|-----|------| +| `ekb_schema` | `ekb_chunk` | `content` | 知识库文本块的关键词搜索 | + +### 3.3 索引创建示例 + +```sql +CREATE INDEX idx_ekb_chunk_content_bigm ON ekb_schema.ekb_chunk + USING gin (content gin_bigm_ops); +``` + +> 详细安装指南见 `docs/02-通用能力层/03-RAG引擎/06-pg_bigm安装指南.md` + +--- + +## 4. pg-boss — PostgreSQL 原生任务队列 + +### 4.1 基本信息 + +- **类型**: Node.js 库(非 PostgreSQL 扩展),利用 PostgreSQL 实现任务队列 +- **表位置**: `platform_schema` 下的 5 张表(job, job_common, queue, schedule, subscription) +- **用途**: 异步任务处理,替代 Redis + BullMQ + +### 4.2 核心特性 + +| 特性 | 说明 | +|------|------| +| 延迟任务 | 支持定时执行 | +| 重试机制 | 失败自动重试,支持配置重试次数和退避策略 | +| 优先级 | 支持任务优先级 | +| 死信队列 | 超过重试次数的任务进入死信队列 | +| 定时调度 | 通过 schedule 表支持 cron 表达式 | + +### 4.3 使用模块 + +| 模块 | 用途 | +|------|------| +| ASL | 文献筛选批处理、全文提取分发 | +| PKB | 文档批处理任务 | +| IIT | 定时质控任务(cron) | + +> 详细运维指南见 `docs/07-运维文档/01-PgBoss队列监控与维护.md` +> 架构设计见 `docs/02-通用能力层/Postgres-Only异步任务处理指南.md` + +--- + +## 5. Docker 镜像配置 + +### 5.1 本地开发 (docker-compose.yml) + +```yaml +services: + postgres: + image: pgvector/pgvector:pg15 # 内含 pgvector 扩展 + container_name: ai-clinical-postgres + environment: + POSTGRES_USER: postgres + POSTGRES_PASSWORD: postgres123 + POSTGRES_DB: ai_clinical_research + ports: + - "5432:5432" + volumes: + - pgdata:/var/lib/postgresql/data +``` + +> pg_bigm 需在 Docker 构建时额外安装,见项目根目录的 Docker 配置。 + +### 5.2 阿里云 RDS + +- **实例类型**: RDS PostgreSQL 15 基础版 +- **扩展管理**: 通过 RDS 控制台 → 插件管理启用 +- **已启用**: pgvector, pg_bigm + +--- + +## 6. 更新日志 + +| 日期 | 操作人 | 变更 | +|------|--------|------| +| 2026-02-27 | AI 助手 | 初始化文档,记录 3 个扩展 + pg-boss 特性 | diff --git a/docs/04-开发规范/09-数据库开发规范.md b/docs/04-开发规范/09-数据库开发规范.md index 49614889..f9e7dfbf 100644 --- a/docs/04-开发规范/09-数据库开发规范.md +++ b/docs/04-开发规范/09-数据库开发规范.md @@ -1,8 +1,8 @@ # 数据库开发规范 -> 版本: v2.0 -> 更新日期: 2026-01-26 -> 重要更新: 统一使用 Prisma Schema 管理所有数据库变更 +> 版本: v3.0 +> 更新日期: 2026-02-27 +> v3.0 更新: 新增部署变更实时记录规则、Shadow DB 降级方案、0227 事故教训 --- @@ -10,14 +10,27 @@ ``` ┌─────────────────────────────────────────────────────────────────────┐ -│ 🎯 统一原则:所有数据库变更必须通过 Prisma Schema 管理 │ +│ 🎯 三条铁律 │ │ │ -│ ✅ 使用 prisma migrate dev/deploy 进行变更 │ -│ ❌ 禁止直接执行手工 SQL 修改表结构 │ -│ ❌ 禁止使用 prisma db push(仅用于原型开发) │ +│ 1. ✅ 所有数据库变更必须通过 Prisma migrate 管理 │ +│ 2. ✅ 变更同时必须记录到「待部署变更清单」 │ +│ 3. ❌ 绝对禁止 prisma db push(除非你愿意花一天修 drift) │ └─────────────────────────────────────────────────────────────────────┘ ``` +### 变更记录规则(v3.0 新增) + +**每次修改 schema.prisma 并生成迁移后,立即做两件事**: + +1. 提交迁移文件到 Git +2. 在 `docs/05-部署文档/03-待部署变更清单.md` 追加一行记录 + +```markdown +| DB-N | 简述变更 | `迁移文件名` | 高/中/低 | 备注 | +``` + +> Cursor Rule `.cursor/rules/deployment-change-tracking.mdc` 会在你修改 schema.prisma 时自动提醒。 + --- ## 1. 开发流程规范 @@ -273,21 +286,24 @@ cat backup_before_migration.sql | docker exec -i ai-clinical-postgres psql -U po ### 5.1 当前 Schema 列表 +> 完整的表级清单见 `docs/01-平台基础层/07-数据库/00-数据库架构总览.md` + | Schema | 用途 | 表数量 | 管理方式 | |--------|------|--------|----------| | `platform_schema` | 平台基础设施(用户、租户、pg-boss) | 19 | Prisma + pg-boss | -| `aia_schema` | AI智能问答 | 3 | Prisma | -| `asl_schema` | 文献筛选 | 7 | Prisma | -| `pkb_schema` | 个人知识库 | 5 | Prisma | +| `iit_schema` | IIT 临床试验管理 Agent | 20 | Prisma | +| `asl_schema` | AI 智能文献 | 11 | Prisma | +| `ssa_schema` | 智能统计分析 | 11 | Prisma | | `dc_schema` | 数据清洗 | 6 | Prisma | -| `iit_schema` | IIT项目管理 | 5 | Prisma | -| `agent_schema` | Agent框架 | 6 | Prisma | -| `ekb_schema` | 企业知识库 | 3 | Prisma | -| `capability_schema` | 通用能力 | 2 | Prisma | -| `protocol_schema` | 方案设计 | 2 | Prisma | -| `rvw_schema` | 论文预审 | 1 | Prisma | +| `agent_schema` | 通用 Agent 框架 | 6 | Prisma | +| `pkb_schema` | 个人知识库 | 5 | Prisma | +| `capability_schema` | Prompt 管理 + 系统知识库 | 4 | Prisma | +| `aia_schema` | AI 智能问答 | 3 | Prisma | +| `ekb_schema` | 企业知识库(向量) | 3 | Prisma | | `admin_schema` | 运营管理 | 2 | Prisma | -| `public` | 兼容旧数据 | 2 | Prisma | +| `protocol_schema` | 方案 Agent | 2 | Prisma | +| `rvw_schema` | 稿件审查 | 1 | Prisma | +| `public` | 遗留 + Prisma 迁移表 | 3 | Prisma | ### 5.2 新增 Schema 规范 @@ -492,6 +508,32 @@ npx prisma migrate dev # 从 Schema 推送 --- +## 10. Shadow DB 失败时的降级方案(v3.0 新增) + +当 `prisma migrate dev` 因 Shadow DB 重放失败时(例如引用了 `db push` 创建的表),使用以下降级流程: + +```bash +# 1. 手动创建迁移目录 +mkdir prisma/migrations/YYYYMMDD_migration_name + +# 2. 编写迁移 SQL(参考 prisma migrate diff 的输出) +npx prisma migrate diff \ + --from-url "$DATABASE_URL" \ + --to-schema-datamodel prisma/schema.prisma \ + --script > prisma/migrations/YYYYMMDD_migration_name/migration.sql + +# 3. 审查 SQL,确认无破坏性操作 + +# 4. 手动执行 SQL 到数据库 + +# 5. 标记为已应用 +npx prisma migrate resolve --applied YYYYMMDD_migration_name +``` + +> 详见 `docs/01-平台基础层/07-数据库/03-技术债务追踪.md` TD-001 + +--- + ## 附录:历史事故 ### 案例1:2026-01-11 数据库重置事故 @@ -506,7 +548,36 @@ npx prisma migrate dev # 从 Schema 推送 **影响**:Prisma Schema 与数据库不一致,后续迁移失败 **教训**:所有变更必须通过 Prisma Schema +### 案例3:2026-02-27 prisma db push 引发的部署 drift(v3.0 新增) + +**原因**:开发过程中大量使用 `prisma db push` 快速迭代,绕过了迁移系统 +**影响**: +- 部署到测试环境时发现 6 张表 + 10 个列不在任何迁移文件中 +- 部署后运行时报错 `column does not exist`(ssa_sessions.data_profile, review_tasks.context_data) +- 需要紧急编写 drift patch 迁移 + 线上热修 SQL +- Shadow DB 重放失败,`prisma migrate dev` 不可用 + +**修复耗时**:约 3 小时(drift 分析 + patch 编写 + 线上热修 + Schema 类型对齐) +**教训**: +1. `prisma db push` 是"技术债 ATM"——每用一次就欠一笔 +2. 即使是快速原型,也应使用 `prisma migrate dev --create-only` 生成迁移后再审查执行 +3. 变更后必须立即记录到 `03-待部署变更清单.md` + +--- + +## 附录:相关文档索引 + +| 文档 | 位置 | +|------|------| +| 数据库架构全景(96 张表) | `docs/01-平台基础层/07-数据库/00-数据库架构总览.md` | +| 迁移历史(14 个迁移) | `docs/01-平台基础层/07-数据库/01-Prisma迁移历史与变更日志.md` | +| 环境差异对照 | `docs/01-平台基础层/07-数据库/02-环境状态对照表.md` | +| 技术债务追踪 | `docs/01-平台基础层/07-数据库/03-技术债务追踪.md` | +| 种子数据管理 | `docs/01-平台基础层/07-数据库/04-种子数据管理.md` | +| 待部署变更清单 | `docs/05-部署文档/03-待部署变更清单.md` | + --- > 📌 **记住**:Prisma Schema 是唯一真相来源(Single Source of Truth) -> 所有数据库结构变更必须先修改 Schema,再通过迁移应用到数据库 +> 所有数据库结构变更必须先修改 Schema,再通过迁移应用到数据库 +> **v3.0 补充**:变更后必须同步更新「待部署变更清单」,否则部署时一定会遗漏 diff --git a/docs/05-部署文档/00-阿里云SAE最新真实状态记录.md b/docs/05-部署文档/00-阿里云SAE最新真实状态记录.md index e2c00f7e..331d93f6 100644 --- a/docs/05-部署文档/00-阿里云SAE最新真实状态记录.md +++ b/docs/05-部署文档/00-阿里云SAE最新真实状态记录.md @@ -1,7 +1,7 @@ # 🚀 AI临床研究平台 - 阿里云SAE最新真实状态记录 > **文档用途**:记录阿里云SAE服务器最新真实状态 + 每次部署记录 -> **最后更新**:2026-01-27 08:05 +> **最后更新**:2026-02-27 > **维护人员**:开发团队 > **说明**:本文档准确记录SAE上所有应用的当前状态,包括内网地址、镜像版本、用户名密码等关键资源信息 @@ -11,10 +11,11 @@ | 服务名称 | 部署状态 | 镜像版本 | 部署位置 | 最后更新时间 | |---------|---------|---------|---------|-------------| -| **PostgreSQL数据库** | ✅ 运行中 | PostgreSQL 15 + 插件 | RDS | 2026-01-27 | -| **前端Nginx服务** | ✅ 运行中 | v1.3 | SAE | 2026-01-27 | -| **Python微服务** | ✅ 运行中 | v1.1 | SAE | 2026-01-26 | -| **Node.js后端** | ✅ 运行中 | v1.7 | SAE | 2026-01-27 | +| **PostgreSQL数据库** | ✅ 运行中 | PostgreSQL 15 + 插件 | RDS | 2026-02-27 | +| **前端Nginx服务** | ✅ 运行中 | **v1.8** | SAE | 2026-02-27 | +| **Python微服务** | ✅ 运行中 | **v1.2** | SAE | 2026-02-27 | +| **Node.js后端** | ✅ 运行中 | **v2.1** | SAE | 2026-02-27 | +| **R统计引擎** | ✅ 运行中 | **v1.0.1** | SAE | 2026-02-27 | | **Dify AI服务** | ⚠️ 已废弃 | - | - | 使用pgvector替代 | --- @@ -34,9 +35,10 @@ | 仓库名称 | 最新版本 | 镜像大小 | VPC地址 | |---------|---------|---------|---------| -| **python-extraction** | v1.0 | 1.12GB | `crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction:v1.0` | -| **ai-clinical_frontend-nginx** | v1.2 | ~50MB | `crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:v1.2` | -| **backend-service** | v1.3 | 838MB | `crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.3` | +| **python-extraction** | **v1.2** | ~1.1GB | `crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction:v1.2` | +| **ssa-r-statistics** | **v1.0.1** | ~1.8GB | `crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ssa-r-statistics:v1.0.1` | +| **ai-clinical_frontend-nginx** | v1.3 | ~50MB | `crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:v1.3` | +| **backend-service** | v1.7 | ~838MB | `crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.7` | --- @@ -89,7 +91,7 @@ postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5.pg.rds.aliyun | 数据库 | 环境 | Schema数量 | 表数量 | 插件 | 用途 | |--------|------|-----------|-------|------|------| -| `ai_clinical_research_test` | 测试环境(当前) | 16 | 63 | pg_bigm, pgvector | SAE测试环境 | +| `ai_clinical_research_test` | 测试环境(当前) | 16 | **84** | pg_bigm, pgvector | SAE测试环境 | | `ai_clinical_research` | 生产环境(备用) | 11 | ~34 | pg_bigm, pgvector | 未来正式上线 | **Schema架构**(16个业务Schema - 测试数据库): @@ -125,9 +127,10 @@ postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5.pg.rds.aliyun | 应用名称 | 状态 | 规格 | 实例数 | 端口 | 内网地址 | 镜像版本 | |---------|------|------|-------|------|---------|---------| -| **python-extraction-test** | ✅ 运行中 | 1核2GB | 1 | 8000 | `http://172.17.173.84:8000` | v1.1 | -| **nodejs-backend-test** | ✅ 运行中 | 1核2GB | 1 | 3001 | `http://172.17.173.89:3001` | v1.7 | -| **frontend-nginx-service** | ✅ 运行中 | 0.5核1GB | 1 | 80 | `http://172.17.173.90:80` | v1.3 | +| **r-statistics-test** | ✅ 运行中 | 1核2GB | 1 | 8080 | `http://172.17.173.101:8080` | **v1.0.1** | +| **python-extraction-test** | ✅ 运行中 | **2核4GB** | 1 | 8000 | `http://172.17.173.102:8000` | **v1.2** | +| **nodejs-backend-test** | ✅ 运行中 | **2核4GB** | 1 | 3001 | `http://172.17.197.28:3001` | **v2.2** | +| **frontend-nginx-service** | ✅ 运行中 | 0.5核1GB | 1 | 80 | `http://172.17.197.29:80` | **v1.8** | **环境变量配置**: @@ -350,6 +353,39 @@ AIclinicalresearch/extraction_service/ ## 🔄 四、部署历史记录 +### 2026-02-27(0227部署 - 数据库迁移 + R统计引擎 + Python更新) + +#### 部署概览 +- **部署时间**:2026-02-27 +- **部署范围**:数据库Schema迁移、R统计引擎全新部署、Python微服务更新 +- **主要变更**:6个Prisma迁移(含1个drift补丁)、新增R Docker服务、Python新增scipy + +#### 数据库迁移 +- ✅ 应用 5 个业务迁移 + 1 个drift补丁迁移 +- ✅ RDS 表数量从 63 增至 84(新增 21 张表) +- ✅ 同步 Seed 数据:SSA工具库 13条 + IIT技能库 8条 +- ✅ 已有数据完整性验证通过(Prompt模板、用户数据零丢失) + +#### R统计引擎(全新部署) +- ✅ 镜像构建并推送:`ssa-r-statistics:v1.0.1`(~1.8GB) +- ✅ SAE应用创建:`r-statistics-test`,1核2GB +- ✅ 内网地址:`http://172.17.173.101:8080` +- ✅ 内置 13 个统计工具(描述统计、T检验、卡方检验、回归、Meta分析等) +- ✅ 健康检查配置完成(HTTP /health) + +#### Python微服务更新(v1.1 → v1.2) +- ✅ 新增依赖:scipy(RVW V2.0 数据取证) +- ✅ 新增代码:forensics 数据取证模块 +- ✅ 实例规格升级:1核2GB → 2核4GB +- ✅ 内网地址变更:`172.17.173.84` → `172.17.173.102` + +#### 文档产出 +- ✅ `0227部署/01-数据库迁移方案.md` +- ✅ `0227部署/02-部署完成总结.md` +- ✅ `00-阿里云SAE最新真实状态记录.md`(更新) + +--- + ### 2026-01-27(0126部署 - 数据库升级 + 全量服务更新)🎉 #### 部署概览 @@ -511,5 +547,5 @@ AIclinicalresearch/extraction_service/ --- > **提示**:本文档记录SAE服务器的最新真实状态,每次部署后必须更新! -> **最后更新**:2026-01-01 14:00 -> **当前版本**:前端v1.2 | 后端v1.3 | Python v1.0 | PostgreSQL 15 +> **最后更新**:2026-02-27 +> **当前版本**:前端v1.8 | 后端v2.1 | Python v1.2 | R统计v1.0.1 | PostgreSQL 15 diff --git a/docs/05-部署文档/01-日常更新操作手册.md b/docs/05-部署文档/01-日常更新操作手册.md new file mode 100644 index 00000000..f3da418a --- /dev/null +++ b/docs/05-部署文档/01-日常更新操作手册.md @@ -0,0 +1,265 @@ +# 日常更新操作手册 + +> 版本: v2.0(合并自旧版 19-日常更新快速操作手册 + 0227 部署实战经验) +> 更新日期: 2026-02-27 +> 适用: 日常代码更新、功能迭代、配置变更 + +--- + +## 0. 部署前检查 + +``` +□ 打开 03-待部署变更清单.md,确认本次要部署哪些变更 +□ 打开 00-阿里云SAE最新真实状态记录.md,确认当前版本号 +□ 确认新版本号(当前版本 +1) +□ 如有数据库变更,先执行数据库迁移 +``` + +--- + +## 1. ACR 登录(首次 / 过期后) + +```powershell +docker login --username=gofeng117@163.com --password=fengzhibo117 crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com +``` + +--- + +## 2. Node.js 后端更新(~25 分钟) + +**当前版本**: v2.2 → 下个版本: v2.3 + +### 2.1 构建 + +```powershell +cd D:\MyCursor\AIclinicalresearch\backend + +# TypeScript 编译(有类型错误时用 --noCheck) +npm run build +# 或: npx tsc --noCheck + +# 构建 Docker 镜像 +docker build -t backend-service:v2.3 . +``` + +> **0227 经验**: `tsc` 不会拷贝 `.json` 配置文件,Dockerfile 中已有 `COPY src/modules/ssa/config/*.json` 等补丁步骤。如新模块有 JSON 配置文件需要确认 Dockerfile 覆盖到。 + +### 2.2 推送 + +```powershell +docker tag backend-service:v2.3 crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v2.3 + +docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v2.3 +``` + +推送约 10 分钟(~840MB),看到 `digest: sha256:...` 表示成功。 + +### 2.3 SAE 部署 + +1. SAE 控制台 → `nodejs-backend-test` → 部署应用 +2. 选择镜像 `backend-service:v2.3` +3. 确认部署,等待 5-8 分钟 + +### 2.4 验证 + +``` +□ SAE 实例状态为 Running +□ 日志中出现启动成功信息 +□ 健康检查: curl http://<新IP>:3001/health +□ 前端功能测试 +``` + +> **重要**: 部署后 IP 会变更!需同步更新 `frontend-nginx-service` 的 `BACKEND_SERVICE_HOST` 环境变量。 + +--- + +## 3. 前端 Nginx 更新(~15 分钟) + +**当前版本**: v1.8 → 下个版本: v1.9 + +### 3.1 构建 + +```powershell +cd D:\MyCursor\AIclinicalresearch\frontend-v2 + +docker build -t ai-clinical_frontend-nginx:v1.9 . +``` + +构建约 5 分钟(含 React 编译)。 + +### 3.2 推送 + +```powershell +docker tag ai-clinical_frontend-nginx:v1.9 crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:v1.9 + +docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ai-clinical_frontend-nginx:v1.9 +``` + +推送约 2 分钟(~50MB)。 + +### 3.3 SAE 部署 + +1. SAE 控制台 → `frontend-nginx-service` → 部署应用 +2. 选择镜像版本 `v1.9` +3. **检查环境变量**: `BACKEND_SERVICE_HOST` 指向最新后端 IP + +### 3.4 验证 + +``` +□ 访问 https://iit.xunzhengyixue.com/ 页面正常 +□ 登录功能正常(排除 504 超时) +□ 测试核心功能 +``` + +--- + +## 4. Python 微服务更新(~30 分钟) + +**当前版本**: v1.2 → 下个版本: v1.3 + +### 4.1 构建 + +```powershell +cd D:\MyCursor\AIclinicalresearch\extraction_service + +docker build -t python-extraction:v1.3 . +``` + +构建约 15 分钟(镜像 ~1.1GB)。 + +### 4.2 推送 + +```powershell +docker tag python-extraction:v1.3 crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction:v1.3 + +docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction:v1.3 +``` + +### 4.3 SAE 部署 + +1. SAE 控制台 → `python-extraction-test` → 部署应用 +2. 选择新版本 + +### 4.4 验证 + +``` +□ 健康检查: curl http://<新IP>:8000/api/health +□ 如 IP 变更,更新后端的 EXTRACTION_SERVICE_URL +``` + +--- + +## 5. R 统计引擎更新(~40 分钟) + +**当前版本**: v1.0.1 → 下个版本: v1.0.2 + +### 5.1 构建 + +```powershell +cd D:\MyCursor\AIclinicalresearch\r-statistics-service + +docker build -t ssa-r-statistics:v1.0.2 . +``` + +构建约 20 分钟(镜像 ~1.8GB,R 包编译耗时)。 + +### 5.2 推送 + +```powershell +docker tag ssa-r-statistics:v1.0.2 crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ssa-r-statistics:v1.0.2 + +docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ssa-r-statistics:v1.0.2 +``` + +### 5.3 SAE 部署 + +1. SAE 控制台 → `r-statistics-test` → 部署应用 +2. 选择新版本 + +### 5.4 验证 + +``` +□ 健康检查: curl http://<新IP>:8080/health +□ 如 IP 变更,更新后端的 R_STATISTICS_SERVICE_URL +``` + +--- + +## 6. 数据库迁移 + +### 6.1 标准迁移(Prisma migration 文件) + +```powershell +# 通过后端 SAE Webshell 执行(推荐) +npx prisma migrate deploy + +# 或手动执行 SQL +# 将 migration.sql 内容粘贴到 Webshell psql 中 +``` + +### 6.2 手动 SQL 补丁 + +```powershell +# 在 SAE nodejs-backend-test 的 Webshell 中 +node -e " +const { execSync } = require('child_process'); +execSync('PGPASSWORD=Xibahe@fengzhibo117 psql -h pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com -U airesearch -d ai_clinical_research_test -c \"你的SQL\"', {stdio:'inherit'}); +" +``` + +### 6.3 标记手动迁移 + +```powershell +npx prisma migrate resolve --applied +``` + +--- + +## 7. 环境变量修改(5 分钟) + +**核心规则: 只改环境变量时用「重启应用」,不要「部署应用」!** + +| 操作 | 用途 | IP 是否变 | +|------|------|----------| +| 重启应用 | 改配置/环境变量 | 不变 | +| 部署应用 | 更新镜像版本 | 会变 | + +步骤: SAE 控制台 → 应用 → 应用配置 → 环境变量 → 编辑 → 保存 → **重启应用** + +--- + +## 8. 部署后收尾 + +``` +□ 更新 00-阿里云SAE最新真实状态记录.md(新IP/版本) +□ 清零 03-待部署变更清单.md(已部署项移到历史区域) +□ 如果是大版本部署,创建 MMDD部署/ 文件夹记录过程 +□ 如有服务 IP 变更,检查相互依赖的环境变量是否已更新 +``` + +--- + +## 9. 常见问题速查 + +| 现象 | 原因 | 解决 | +|------|------|------| +| 前端 504 Gateway Timeout | 后端 IP 变更但前端环境变量未更新 | 更新 `BACKEND_SERVICE_HOST` 并重启 | +| `column does not exist` | 数据库迁移遗漏 | 检查 `03-待部署变更清单.md` 中是否有未执行的 DB 变更 | +| `ENOENT .json` 文件 | tsc 不拷贝非 .ts 文件 | 在 Dockerfile 中添加 `COPY` 指令 | +| 健康检查失败 404 | 健康检查路径配置错误 | 确认 HTTP 路径为 `/health` | +| 镜像推送超时 | 网络问题 | 重试,或换网络环境 | +| `prisma db push` 遗留 drift | 开发时绕过了迁移系统 | 创建 patch migration + `resolve --applied` | + +--- + +## 10. 部署顺序参考 + +如果多个服务同时更新: + +``` +1. 数据库迁移(先行,确保表结构就绪) +2. R 统计引擎(独立服务,不影响其他) +3. Python 微服务(独立服务) +4. Node.js 后端(依赖上游服务 IP,需更新环境变量) +5. 前端 Nginx(最后部署,需要最新的后端 IP) +``` diff --git a/docs/05-部署文档/0227部署/01-数据库迁移方案.md b/docs/05-部署文档/0227部署/01-数据库迁移方案.md new file mode 100644 index 00000000..095cf2d3 --- /dev/null +++ b/docs/05-部署文档/0227部署/01-数据库迁移方案.md @@ -0,0 +1,661 @@ +# 数据库迁移方案:开发环境 → RDS 结构同步 + +> **日期**:2026-02-27 +> **目标**:将开发环境(localhost Docker)的数据库结构和必要 Seed 数据同步到阿里云 RDS 测试环境 +> **核心原则**:只做增量,不动存量;结构先行,数据后补;每步可回滚 + +--- + +## 1. 环境信息 + +### 1.1 源环境(开发) + +``` +Host: localhost +Port: 5432 +Database: ai_clinical_research +User: postgres +Password: postgres123 +容器名: ai-clinical-postgres +表数量: 96 +迁移数: 11(+ 1 个文件未 apply) +``` + +### 1.2 目标环境(RDS 测试) + +``` +Host: pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com(外网) +Host: pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com(内网/SAE) +Port: 5432 +Database: ai_clinical_research_test +User: airesearch +Password: Xibahe@fengzhibo117 +表数量: 66 +迁移数: 6 +``` + +### 1.3 DATABASE_URL(操作时使用) + +```bash +# 外网(本地操作用) +postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test + +# 内网(SAE 部署用) +postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical_research_test?connection_limit=18&pool_timeout=10 +``` + +--- + +## 2. 差异分析总览 + +### 2.1 Prisma 迁移差距 + +| # | 迁移文件 | 本地 | RDS | 内容 | +|---|---------|------|-----|------| +| 1 | 20251010_init | ✅ | ✅ | 初始化 | +| 2 | 20251010_conversation_metadata | ✅ | ✅ | AIA 对话 | +| 3 | 20251012_batch_processing | ✅ | ✅ | 批处理 | +| 4 | 20251014_review_tasks | ✅ | ✅ | 论文预审 | +| 5 | 20251208_column_mapping | ✅ | ✅ | 列映射 | +| 6 | 20260128_system_knowledge_base | ✅ | ✅ | 系统知识库 | +| **7** | **20260207_add_iit_manager_agent_tables** | ✅ | ❌ | IIT Agent 8 张新表 | +| **8** | **20260208_add_cra_qc_engine_support** | ✅ | ❌ | CRA 质控 + skills 扩展 | +| **9** | **20260219_add_ssa_module** | ✅ | ❌ | SSA 模块 9 张表 | +| **10** | **20260223_add_deep_research_v2_fields** | ✅ | ❌ | research_tasks 加 6 列 | +| **11** | **20260225_add_extraction_template_engine** | ✅ | ❌ | ASL 提取引擎 4 张表 | +| **12** | **20260226_add_equery_critical_events_cron** | ❌ (db push) | ❌ | eQuery + 重大事件 + cron | + +> RDS 需要执行迁移 #7 ~ #12,共 **6 个迁移**。 + +### 2.2 无迁移文件的变更(db push 造成的漂移) + +以下 **6 张表 + 3 列 + 1 索引** 存在于开发数据库和 Prisma Schema 中,但没有对应的迁移文件: + +| Schema | 对象 | 类型 | 说明 | +|--------|------|------|------| +| iit_schema | `field_metadata` | 新表(16 列) | REDCap 字段元数据 | +| iit_schema | `qc_logs` | 新表(16 列) | 质控日志(附历史追溯) | +| iit_schema | `qc_project_stats` | 新表(10 列) | 项目级质控统计汇总 | +| iit_schema | `record_summary` | 新表(16 列) | 受试者记录汇总 | +| iit_schema | `projects.knowledge_base_id` | 新列 | 关联 EKB 知识库 | +| iit_schema | `idx_iit_project_kb` | 新索引 | knowledge_base_id 索引 | +| ssa_schema | `ssa_workflows` | 新表(11 列) | 统计分析工作流 | +| ssa_schema | `ssa_workflow_steps` | 新表(13 列) | 工作流步骤明细 | + +### 2.3 表数量对比 + +| Schema | 开发环境 | RDS | 差异 | +|--------|---------|-----|------| +| admin_schema | 2 | 2 | — | +| agent_schema | 6 | 6 | — | +| aia_schema | 3 | 3 | — | +| **asl_schema** | **12** | **7** | **+4 表 +6 列** | +| capability_schema | 4 | 4 | — | +| dc_schema | 6 | 6 | — | +| ekb_schema | 3 | 3 | — | +| **iit_schema** | **20** | **5** | **+15 表 +3 列** | +| pkb_schema | 5 | 5 | — | +| platform_schema | 19 | 19 | — | +| protocol_schema | 2 | 2 | — | +| public | 3 | 3 | — | +| rvw_schema | 1 | 1 | — | +| **ssa_schema** | **11** | **0** | **+11 表** | +| **合计** | **96** | **66** | **+30 表** | + +### 2.4 列级差异(已有表) + +| 表 | 开发环境 | RDS | 缺失列 | +|---|---------|-----|--------| +| `asl_schema.research_tasks` | 25 列 | 19 列 | `target_sources`, `confirmed_requirement`, `ai_intent_summary`, `execution_logs`, `synthesis_report`, `result_list` | +| `iit_schema.projects` | 18 列 | 15 列 | `knowledge_base_id`, `cron_enabled`, `cron_expression` | +| `iit_schema.skills` | 16 列 | — (新表) | 迁移 #8 中 ALTER ADD 4 列 | + +--- + +## 3. Seed 数据同步需求 + +### 3.1 Prompt 管理数据对比 + +| 表 | 开发环境 | RDS | 分析 | +|---|---------|-----|------| +| `prompt_templates` | 27 行 | 14 行 | RDS 缺 13 个 SSA 模板(ID 17-29) | +| `prompt_versions` | 42 行 | 23 行 | RDS 缺 19 个 SSA 版本(ID 26-44) | + +**重要**:RDS 的 AIA/ASL/DC/RVW 模板(ID 1-16)已经过**独立迭代**,部分版本比开发环境更丰富(如模板 7 在 RDS 有 v2/v3 内容各 1044 字符,开发环境是短内容测试版),**绝对不能覆盖**。 + +### 3.2 需要同步的 Seed 数据 + +| 表 | 行数 | 内容 | 操作 | +|---|------|------|------| +| `capability_schema.prompt_templates` | 13 行 | SSA 模块 Prompt(ID 17-29) | INSERT,已有则跳过 | +| `capability_schema.prompt_versions` | 19 行 | SSA Prompt 版本(ID 26-44) | INSERT,已有则跳过 | +| `asl_schema.extraction_templates` | 3 行 | 系统提取模板(RCT/Cohort/QC) | INSERT(新表,迁移后) | + +### 3.3 不需要同步的数据 + +| 表 | 原因 | +|---|------| +| `prompt_templates` ID 1-16 | RDS 版本更优,不覆盖 | +| `prompt_versions` ID 1-25 | RDS 版本更优,不覆盖 | +| `platform_schema.users/tenants/...` | RDS 有真实用户/租户数据 | +| `ekb_schema.*` | RDS 有真实知识库数据(5686 chunks) | +| `iit_schema.qc_logs` 等 | 开发测试数据,不推向生产 | + +--- + +## 4. 迁移方案 + +### 4.1 方案选择:补丁迁移 + `prisma migrate deploy` + +采用 **方案 B**:先为 db push 漏网的变更创建补丁迁移文件,然后用 `prisma migrate deploy` 一次性应用。 + +**风险评估**: + +| 风险项 | 评估 | 说明 | +|-------|------|------| +| 数据丢失 | ✅ 零风险 | 6 个迁移全部是 CREATE TABLE / ALTER TABLE ADD COLUMN,无任何 DROP / DELETE / TRUNCATE | +| 现有表结构破坏 | ✅ 零风险 | 仅新增,不修改已有列 | +| 现有数据变更 | ✅ 零风险 | 纯 DDL 操作,不涉及 DML | +| Prompt 数据丢失 | ✅ 零风险 | Prompt 在 capability_schema,不受任何迁移影响 | +| 迁移执行失败 | 🟡 低风险 | 可能因 RDS 权限问题失败,事务回滚不影响数据 | + +### 4.2 执行步骤总览 + +``` +步骤 1 → 备份 RDS 数据库 +步骤 2 → 创建补丁迁移文件(覆盖 db push 漏网变更) +步骤 3 → 本地标记补丁迁移为已应用(dev 已有这些表) +步骤 4 → 在 RDS 执行 prisma migrate deploy(7 个迁移) +步骤 5 → 同步 Seed 数据(SSA Prompt + 提取模板) +步骤 6 → 验证 +``` + +--- + +## 5. 详细执行步骤 + +### 步骤 1:备份 RDS 数据库 + +> ⚠️ **安全第一:任何操作前必须备份!** + +使用 Docker 容器中的 pg_dump(避免 PowerShell 编码问题): + +```bash +# 在 Docker 容器内执行备份(避免 PowerShell UTF-8 编码问题!) +docker exec ai-clinical-postgres pg_dump \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test" \ + -f /tmp/backup_rds_before_0227.sql + +# 将备份文件从容器复制到本地 +docker cp ai-clinical-postgres:/tmp/backup_rds_before_0227.sql ./backup_rds_before_0227.sql + +# 验证备份文件大小和中文内容 +docker exec ai-clinical-postgres head -20 /tmp/backup_rds_before_0227.sql +``` + +预期:备份文件应 > 1MB,且中文内容正常显示(非 `????`)。 + +### 步骤 2:创建补丁迁移文件 + +> 将 db push 漏网的 6 张表 + 3 列 + 索引 补入迁移体系 + +创建文件 `backend/prisma/migrations/20260227_patch_db_push_drift/migration.sql`: + +```sql +-- ================================================================ +-- 补丁迁移:覆盖 db push 创建的 6 张表 + 3 列 +-- 所有语句使用 IF NOT EXISTS 保证幂等(多次执行不报错) +-- ================================================================ + +-- ============ iit_schema: 4 张新表 + 1 列 + 1 索引 ============ + +-- 1. IIT 字段元数据表(REDCap 字段定义缓存) +CREATE TABLE IF NOT EXISTS "iit_schema"."field_metadata" ( + "id" TEXT NOT NULL, + "project_id" TEXT NOT NULL, + "field_name" TEXT NOT NULL, + "field_label" TEXT NOT NULL, + "field_type" TEXT NOT NULL, + "form_name" TEXT NOT NULL, + "section_header" TEXT, + "validation" TEXT, + "validation_min" TEXT, + "validation_max" TEXT, + "choices" TEXT, + "required" BOOLEAN NOT NULL DEFAULT false, + "branching" TEXT, + "alias" TEXT, + "rule_source" TEXT, + "synced_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "field_metadata_pkey" PRIMARY KEY ("id") +); + +CREATE UNIQUE INDEX IF NOT EXISTS "unique_iit_field_metadata" + ON "iit_schema"."field_metadata"("project_id", "field_name"); +CREATE INDEX IF NOT EXISTS "idx_iit_field_metadata_project" + ON "iit_schema"."field_metadata"("project_id"); +CREATE INDEX IF NOT EXISTS "idx_iit_field_metadata_form" + ON "iit_schema"."field_metadata"("project_id", "form_name"); + +-- 2. IIT 质控日志表 +CREATE TABLE IF NOT EXISTS "iit_schema"."qc_logs" ( + "id" TEXT NOT NULL, + "project_id" TEXT NOT NULL, + "record_id" TEXT NOT NULL, + "event_id" TEXT, + "qc_type" TEXT NOT NULL, + "form_name" TEXT, + "status" TEXT NOT NULL, + "issues" JSONB NOT NULL DEFAULT '[]', + "rules_evaluated" INTEGER NOT NULL DEFAULT 0, + "rules_skipped" INTEGER NOT NULL DEFAULT 0, + "rules_passed" INTEGER NOT NULL DEFAULT 0, + "rules_failed" INTEGER NOT NULL DEFAULT 0, + "rule_version" TEXT NOT NULL, + "inclusion_passed" BOOLEAN, + "exclusion_passed" BOOLEAN, + "triggered_by" TEXT NOT NULL, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + + CONSTRAINT "qc_logs_pkey" PRIMARY KEY ("id") +); + +CREATE INDEX IF NOT EXISTS "idx_iit_qc_log_record_time" + ON "iit_schema"."qc_logs"("project_id", "record_id", "created_at"); +CREATE INDEX IF NOT EXISTS "idx_iit_qc_log_status_time" + ON "iit_schema"."qc_logs"("project_id", "status", "created_at"); +CREATE INDEX IF NOT EXISTS "idx_iit_qc_log_type_time" + ON "iit_schema"."qc_logs"("project_id", "qc_type", "created_at"); + +-- 3. IIT 受试者记录汇总表 +CREATE TABLE IF NOT EXISTS "iit_schema"."record_summary" ( + "id" TEXT NOT NULL, + "project_id" TEXT NOT NULL, + "record_id" TEXT NOT NULL, + "enrolled_at" TIMESTAMP(3), + "enrolled_by" TEXT, + "last_updated_at" TIMESTAMP(3) NOT NULL, + "last_updated_by" TEXT, + "last_form_name" TEXT, + "form_status" JSONB NOT NULL DEFAULT '{}', + "total_forms" INTEGER NOT NULL DEFAULT 0, + "completed_forms" INTEGER NOT NULL DEFAULT 0, + "completion_rate" DOUBLE PRECISION NOT NULL DEFAULT 0, + "latest_qc_status" TEXT, + "latest_qc_at" TIMESTAMP(3), + "update_count" INTEGER NOT NULL DEFAULT 0, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "record_summary_pkey" PRIMARY KEY ("id") +); + +CREATE UNIQUE INDEX IF NOT EXISTS "unique_iit_record_summary" + ON "iit_schema"."record_summary"("project_id", "record_id"); +CREATE INDEX IF NOT EXISTS "idx_iit_record_summary_enrolled" + ON "iit_schema"."record_summary"("project_id", "enrolled_at"); +CREATE INDEX IF NOT EXISTS "idx_iit_record_summary_qc_status" + ON "iit_schema"."record_summary"("project_id", "latest_qc_status"); +CREATE INDEX IF NOT EXISTS "idx_iit_record_summary_completion" + ON "iit_schema"."record_summary"("project_id", "completion_rate"); + +-- 4. IIT 项目级质控统计汇总表 +CREATE TABLE IF NOT EXISTS "iit_schema"."qc_project_stats" ( + "id" TEXT NOT NULL, + "project_id" TEXT NOT NULL, + "total_records" INTEGER NOT NULL DEFAULT 0, + "passed_records" INTEGER NOT NULL DEFAULT 0, + "failed_records" INTEGER NOT NULL DEFAULT 0, + "warning_records" INTEGER NOT NULL DEFAULT 0, + "inclusion_met" INTEGER NOT NULL DEFAULT 0, + "exclusion_met" INTEGER NOT NULL DEFAULT 0, + "avg_completion_rate" DOUBLE PRECISION NOT NULL DEFAULT 0, + "updated_at" TIMESTAMP(3) NOT NULL, + + CONSTRAINT "qc_project_stats_pkey" PRIMARY KEY ("id") +); + +CREATE UNIQUE INDEX IF NOT EXISTS "qc_project_stats_project_id_key" + ON "iit_schema"."qc_project_stats"("project_id"); + +-- 5. IIT projects 表新增 knowledge_base_id 列 +ALTER TABLE "iit_schema"."projects" + ADD COLUMN IF NOT EXISTS "knowledge_base_id" TEXT; + +CREATE INDEX IF NOT EXISTS "idx_iit_project_kb" + ON "iit_schema"."projects"("knowledge_base_id"); + +-- ============ ssa_schema: 2 张新表 ============ + +-- 6. SSA 工作流表 +CREATE TABLE IF NOT EXISTS "ssa_schema"."ssa_workflows" ( + "id" TEXT NOT NULL DEFAULT gen_random_uuid()::text, + "session_id" TEXT NOT NULL, + "message_id" TEXT, + "status" VARCHAR NOT NULL DEFAULT 'pending', + "total_steps" INTEGER NOT NULL, + "completed_steps" INTEGER NOT NULL DEFAULT 0, + "workflow_plan" JSONB NOT NULL, + "reasoning" TEXT, + "created_at" TIMESTAMP(3) NOT NULL DEFAULT now(), + "started_at" TIMESTAMP(3), + "completed_at" TIMESTAMP(3), + + CONSTRAINT "ssa_workflows_pkey" PRIMARY KEY ("id") +); + +CREATE INDEX IF NOT EXISTS "idx_ssa_workflow_session" + ON "ssa_schema"."ssa_workflows"("session_id"); +CREATE INDEX IF NOT EXISTS "idx_ssa_workflow_status" + ON "ssa_schema"."ssa_workflows"("status"); + +-- 外键:ssa_workflows.session_id → ssa_sessions.id +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.table_constraints + WHERE constraint_name = 'ssa_workflows_session_id_fkey' + ) THEN + ALTER TABLE "ssa_schema"."ssa_workflows" + ADD CONSTRAINT "ssa_workflows_session_id_fkey" + FOREIGN KEY ("session_id") + REFERENCES "ssa_schema"."ssa_sessions"("id") + ON DELETE CASCADE ON UPDATE CASCADE; + END IF; +END $$; + +-- 7. SSA 工作流步骤表 +CREATE TABLE IF NOT EXISTS "ssa_schema"."ssa_workflow_steps" ( + "id" TEXT NOT NULL DEFAULT gen_random_uuid()::text, + "workflow_id" TEXT NOT NULL, + "step_order" INTEGER NOT NULL, + "tool_code" VARCHAR NOT NULL, + "tool_name" VARCHAR NOT NULL, + "status" VARCHAR NOT NULL DEFAULT 'pending', + "input_params" JSONB, + "guardrail_checks" JSONB, + "output_result" JSONB, + "error_info" JSONB, + "execution_ms" INTEGER, + "started_at" TIMESTAMP(3), + "completed_at" TIMESTAMP(3), + + CONSTRAINT "ssa_workflow_steps_pkey" PRIMARY KEY ("id") +); + +CREATE INDEX IF NOT EXISTS "idx_ssa_workflow_step_workflow" + ON "ssa_schema"."ssa_workflow_steps"("workflow_id"); +CREATE INDEX IF NOT EXISTS "idx_ssa_workflow_step_status" + ON "ssa_schema"."ssa_workflow_steps"("status"); + +-- 外键:ssa_workflow_steps.workflow_id → ssa_workflows.id +DO $$ +BEGIN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.table_constraints + WHERE constraint_name = 'ssa_workflow_steps_workflow_id_fkey' + ) THEN + ALTER TABLE "ssa_schema"."ssa_workflow_steps" + ADD CONSTRAINT "ssa_workflow_steps_workflow_id_fkey" + FOREIGN KEY ("workflow_id") + REFERENCES "ssa_schema"."ssa_workflows"("id") + ON DELETE CASCADE ON UPDATE CASCADE; + END IF; +END $$; +``` + +### 步骤 3:本地标记补丁迁移为已应用 + +> 开发环境已经有这些表(db push 创建的),只需告诉 Prisma "这个迁移已经执行过了"。 + +```bash +cd backend + +# 标记补丁迁移为已应用(不实际执行 SQL) +npx prisma migrate resolve --applied 20260227_patch_db_push_drift + +# 同时标记 20260226 迁移为已应用(dev 已有 equery/critical_events 表) +npx prisma migrate resolve --applied 20260226_add_equery_critical_events_cron +``` + +验证: + +```bash +# 本地应该显示 13 个迁移全部已应用 +npx prisma migrate status +``` + +### 步骤 4:在 RDS 执行迁移 + +> 核心操作:一次性应用 7 个迁移(#7 ~ #12 + 补丁) + +```bash +cd backend + +# 临时切换 DATABASE_URL 指向 RDS 外网 +# Windows PowerShell: +$env:DATABASE_URL="postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test" + +# 执行迁移(只应用未执行的迁移,不会重新执行已有的) +npx prisma migrate deploy +``` + +预期输出: + +``` +7 migrations found in prisma/migrations +6 migrations have been already applied +Applying migration `20260207112544_add_iit_manager_agent_tables` +Applying migration `20260208134925_add_cra_qc_engine_support` +Applying migration `20260219_add_ssa_module` +Applying migration `20260223_add_deep_research_v2_fields` +Applying migration `20260225_add_extraction_template_engine` +Applying migration `20260226_add_equery_critical_events_cron` +Applying migration `20260227_patch_db_push_drift` + +All migrations have been successfully applied. +``` + +> **注意**:迁移 #7 中包含 `CREATE EXTENSION IF NOT EXISTS vector;`,需要 RDS 已安装 pgvector 插件(已在 0126 部署中确认安装)。 + +### 步骤 5:同步 Seed 数据 + +> 仅同步 SSA Prompt 和提取模板,不动 RDS 已有数据 + +**方法:从开发环境导出 → 插入 RDS** + +```bash +# 5a. 导出 SSA Prompt 模板(ID >= 17,仅 SSA 新增) +docker exec ai-clinical-postgres psql -U postgres -d ai_clinical_research -c "\ + COPY (SELECT * FROM capability_schema.prompt_templates WHERE id >= 17) \ + TO '/tmp/seed_prompt_templates.csv' WITH CSV HEADER;" + +# 5b. 导出 SSA Prompt 版本(ID >= 26) +docker exec ai-clinical-postgres psql -U postgres -d ai_clinical_research -c "\ + COPY (SELECT * FROM capability_schema.prompt_versions WHERE id >= 26) \ + TO '/tmp/seed_prompt_versions.csv' WITH CSV HEADER;" + +# 5c. 导出提取模板(新表,全部 3 行) +docker exec ai-clinical-postgres psql -U postgres -d ai_clinical_research -c "\ + COPY (SELECT * FROM asl_schema.extraction_templates) \ + TO '/tmp/seed_extraction_templates.csv' WITH CSV HEADER;" + +# 5d. 导入到 RDS(在 Docker 容器内操作,避免 PowerShell 编码问题) +docker exec ai-clinical-postgres psql \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test" \ + -c "\COPY capability_schema.prompt_templates FROM '/tmp/seed_prompt_templates.csv' WITH CSV HEADER;" + +docker exec ai-clinical-postgres psql \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test" \ + -c "\COPY capability_schema.prompt_versions FROM '/tmp/seed_prompt_versions.csv' WITH CSV HEADER;" + +docker exec ai-clinical-postgres psql \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test" \ + -c "\COPY asl_schema.extraction_templates FROM '/tmp/seed_extraction_templates.csv' WITH CSV HEADER;" +``` + +> ⚠️ **关键**:所有操作通过 `docker exec` 在容器内执行,**避免 PowerShell 的 UTF-8 编码问题**(参考 0126 部署教训)。 + +### 步骤 6:验证 + +```bash +# 6a. 验证表数量(应从 66 → 96) +docker exec ai-clinical-postgres psql \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test" \ + -c "SELECT count(*) as total_tables FROM information_schema.tables WHERE table_type='BASE TABLE' AND table_schema NOT IN ('pg_catalog','information_schema');" + +# 6b. 验证迁移记录(应为 13 条) +docker exec ai-clinical-postgres psql \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test" \ + -c "SELECT count(*) FROM public._prisma_migrations;" + +# 6c. 验证 SSA Prompt 数据(应为 27 个模板) +docker exec ai-clinical-postgres psql \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test" \ + -c "SELECT count(*) FROM capability_schema.prompt_templates;" + +# 6d. 验证 SSA 表存在(应有 11 张表) +docker exec ai-clinical-postgres psql \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test" \ + -c "SELECT count(*) FROM information_schema.tables WHERE table_schema='ssa_schema';" + +# 6e. 验证关键列存在 +docker exec ai-clinical-postgres psql \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test" \ + -c "SELECT column_name FROM information_schema.columns WHERE table_schema='asl_schema' AND table_name='research_tasks' AND column_name IN ('target_sources','synthesis_report','result_list');" + +# 6f. 验证 RDS 原有数据未受影响(Prompt ID 1-16 + 用户数据) +docker exec ai-clinical-postgres psql \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test" \ + -c "SELECT id, code, name FROM capability_schema.prompt_templates WHERE id <= 16 ORDER BY id LIMIT 5;" + +docker exec ai-clinical-postgres psql \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test" \ + -c "SELECT count(*) as user_count FROM platform_schema.users;" +``` + +**验证通过标准**: + +| 检查项 | 预期值 | +|-------|-------| +| 总表数 | 96 | +| 迁移记录数 | 13 | +| prompt_templates 总数 | 27 | +| ssa_schema 表数 | 11 | +| research_tasks 新列 | 3 列存在 | +| 原有 Prompt(ID 1-16) | 数据完整、中文正常 | +| 用户数 | 22(不变) | + +--- + +## 6. 回滚方案 + +### 6.1 迁移执行失败 + +`prisma migrate deploy` 每个迁移在事务中执行,失败自动回滚,不影响已有数据。 + +处理方式:查看错误信息,修复 SQL 后重新执行。 + +### 6.2 需要完全回滚 + +使用步骤 1 的备份文件恢复: + +```bash +# 在 Docker 容器内操作(避免编码问题) +# 1. 删除测试数据库 +docker exec ai-clinical-postgres psql \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/postgres" \ + -c "DROP DATABASE ai_clinical_research_test WITH (FORCE);" + +# 2. 重新创建 +docker exec ai-clinical-postgres psql \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/postgres" \ + -c "CREATE DATABASE ai_clinical_research_test ENCODING='UTF8';" + +# 3. 安装插件 +docker exec ai-clinical-postgres psql \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test" \ + -c "CREATE EXTENSION IF NOT EXISTS pg_bigm; CREATE EXTENSION IF NOT EXISTS vector;" + +# 4. 恢复备份 +docker exec ai-clinical-postgres psql \ + "postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5so.pg.rds.aliyuncs.com:5432/ai_clinical_research_test" \ + -f /tmp/backup_rds_before_0227.sql +``` + +--- + +## 7. 注意事项 + +### 7.1 PowerShell 编码问题 + +> ⚠️ **0126 部署的惨痛教训:PowerShell 会破坏 UTF-8 编码** + +所有涉及中文数据的操作(备份、导入 Seed 数据)必须在 Docker 容器内直接执行(`docker exec`),**绝不能**通过 PowerShell 管道传输。 + +### 7.2 RDS 权限 + +- `CREATE EXTENSION` 需要 RDS 超级用户权限(已在 0126 部署中通过 RDS 控制台安装插件) +- `CREATE SCHEMA` 需要 OWNER 权限(airesearch 用户已具备) + +### 7.3 执行顺序 + +补丁迁移 `20260227` **必须排在** `20260219_add_ssa_module` 之后,因为 `ssa_workflows` 表的外键引用 `ssa_sessions` 表(由 #9 迁移创建)。当前文件名的字母序保证了正确顺序。 + +### 7.4 Prompt ID 序列 + +导入 Seed 数据后需要重置 `prompt_templates` 和 `prompt_versions` 表的 ID 序列: + +```sql +-- 重置序列到当前最大值 +SELECT setval(pg_get_serial_sequence('capability_schema.prompt_templates', 'id'), + (SELECT MAX(id) FROM capability_schema.prompt_templates)); +SELECT setval(pg_get_serial_sequence('capability_schema.prompt_versions', 'id'), + (SELECT MAX(id) FROM capability_schema.prompt_versions)); +``` + +--- + +## 8. 后续改进:防止 Schema 漂移 + +### 8.1 根因 + +当前 6 表 + 3 列无迁移文件的根因是开发中使用了 `prisma db push` 而非 `prisma migrate dev`。 + +### 8.2 四层防线 + +| 层级 | 时机 | 方法 | 实施成本 | +|------|------|------|---------| +| **开发规范** | 写代码时 | 禁止 `db push`,统一用 `migrate dev` | 零 | +| **pre-commit Hook** | git commit 前 | 检测 schema.prisma 变更但无新迁移文件 | 一次性 | +| **CI 漂移检测** | PR 合并前 | `prisma migrate diff --exit-code` | 一次性 | +| **部署前闸门** | 部署前 | 对比 schema vs 迁移历史 | 一次性 | + +详细实施方案见开发规范更新(后续单独文档)。 + +--- + +## 9. 时间估算 + +| 步骤 | 预计耗时 | 说明 | +|------|---------|------| +| 步骤 1:备份 | 5 分钟 | pg_dump 约 20MB | +| 步骤 2:创建补丁迁移 | 5 分钟 | 创建文件 | +| 步骤 3:本地标记 | 2 分钟 | prisma resolve | +| 步骤 4:RDS 迁移 | 3 分钟 | migrate deploy | +| 步骤 5:Seed 数据 | 5 分钟 | CSV 导出导入 | +| 步骤 6:验证 | 5 分钟 | 7 项检查 | +| **总计** | **~25 分钟** | 含缓冲时间 | + +--- + +## 更新日志 + +| 版本 | 日期 | 内容 | +|------|------|------| +| v1.0 | 2026-02-27 | 初始版本:完整迁移方案 | + +--- + +**文档结束** diff --git a/docs/05-部署文档/0227部署/02-部署完成总结.md b/docs/05-部署文档/0227部署/02-部署完成总结.md new file mode 100644 index 00000000..b9ba1e3b --- /dev/null +++ b/docs/05-部署文档/0227部署/02-部署完成总结.md @@ -0,0 +1,355 @@ +# 2026年2月27日部署完成总结 + +> **部署日期**:2026-02-27 +> **部署范围**:数据库迁移 + R统计引擎(新增) + Python微服务 + Node.js后端 + 前端Nginx 全量更新 +> **部署状态**:✅ 全部完成,所有功能测试通过 +> **文档日期**:2026-02-27 + +--- + +## 部署成果一览 + +### 服务版本对比 + +| 服务 | 部署前 | 部署后 | 变更类型 | +|------|--------|--------|---------| +| PostgreSQL(RDS) | 16 Schema / 63 表 | 16 Schema / 84 表 | Schema迁移 | +| R统计引擎 | 无 | **v1.0.1** | **全新部署** | +| Python微服务 | v1.1 | **v1.2** | 依赖+代码更新 | +| Node.js后端 | v1.7 | **v2.2** | 大版本更新(5万行新增) | +| 前端Nginx | v1.3 | **v1.8** | 大版本更新(3.2万行新增) | + +### 内网地址总览 + +| 服务 | 内网地址 | 端口 | 状态 | +|------|---------|------|------| +| R统计引擎(新) | `172.17.173.101` | 8080 | ✅ 新增 | +| Python微服务 | `172.17.173.102` | 8000 | ✅ 地址变更 | +| Node.js后端 | `172.17.197.28` | 3001 | ✅ 地址变更 | +| 前端Nginx | `172.17.197.29` | 80 | ✅ 地址变更 | + +--- + +## 一、数据库迁移 + +### 1.1 迁移背景 + +自 0126 部署以来,本地开发环境新增了大量功能模块(IIT Agent、SSA统计分析、ASL提取工作台等),导致本地数据库与RDS之间存在显著差异。部分变更通过 `prisma db push` 直接推送,未生成迁移文件,造成 Schema Drift。 + +### 1.2 迁移内容 + +**应用的 Prisma 迁移文件**(5个): + +| 迁移文件 | 内容 | 新增表数 | +|---------|------|---------| +| `20260207_add_iit_manager_agent_tables` | IIT Agent 8张表 | 8 | +| `20260208_add_cra_qc_engine_support` | CRA智能质控 | 1 | +| `20260219_add_ssa_module` | SSA统计分析模块 9张表 | 9 | +| `20260223_add_deep_research_v2_fields` | Deep Research V2.0 字段 | 0(列变更) | +| `20260225_add_extraction_template_engine` | 全文智能提取工作台 4张表 | 4 | + +**Drift 补丁迁移**(1个): + +| 迁移文件 | 内容 | +|---------|------| +| `20260227_patch_db_push_drift` | 修复 `prisma db push` 造成的 drift:`field_metadata`、`qc_logs`、`record_summary`、`qc_project_stats`、`ssa_workflows`、`ssa_workflow_steps` 等表 + `knowledge_base_id` 列 | + +**Seed 数据同步**: + +| 数据 | 条目数 | 目标表 | +|------|-------|-------| +| SSA 工具库 | 13条 | `ssa_schema.ssa_tools_library` | +| IIT 技能库 | 8条 | `iit_schema.iit_skills` | + +### 1.3 迁移结果 + +| 验证项 | 结果 | +|-------|------| +| Schema 数量 | 16 ✅ | +| 表总数 | 84 ✅ | +| Prisma 迁移记录 | 11条(含6条新增) ✅ | +| SSA 工具库数据 | 13条 ✅ | +| IIT 技能库数据 | 8条 ✅ | +| 已有数据完整性 | Prompt模板、用户数据零丢失 ✅ | + +> 详细方案见 `01-数据库迁移方案.md` + +--- + +## 二、R统计引擎部署(全新服务) + +### 2.1 服务概述 + +R统计引擎是 SSA(智能统计分析)模块的核心计算后端,采用 Brain-Hand 架构:Node.js 后端作为 Brain 负责调度,R Docker 作为 Hand 负责统计计算。 + +### 2.2 镜像信息 + +| 项目 | 值 | +|------|---| +| ACR 仓库 | `ssa-r-statistics` | +| 镜像版本 | `v1.0.1` | +| 镜像地址 | `crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/ssa-r-statistics:v1.0.1` | +| 镜像大小 | ~1.8GB | +| 基础镜像 | `rocker/r-ver:4.3` | +| R版本 | 4.3.3 | + +### 2.3 内置工具(13个) + +| 工具代码 | 功能 | +|---------|------| +| `descriptive` | 描述性统计 | +| `t_test_ind` | 独立样本T检验 | +| `t_test_paired` | 配对T检验 | +| `mann_whitney` | Mann-Whitney U检验 | +| `wilcoxon` | Wilcoxon符号秩检验 | +| `chi_square` | 卡方检验 | +| `fisher` | Fisher精确检验 | +| `anova_one` | 单因素方差分析 | +| `correlation` | 相关性分析 | +| `linear_reg` | 线性回归 | +| `logistic_binary` | 二元Logistic回归 | +| `baseline_table` | 基线特征表 | +| `meta_analysis` | Meta分析 | + +### 2.4 SAE 应用配置 + +| 配置项 | 值 | +|-------|---| +| 应用名称 | `r-statistics-test` | +| 实例规格 | 1核2GB | +| 实例数量 | 1 | +| 容器端口 | 8080 | +| 内网地址 | `http://172.17.173.101:8080` | +| 健康检查方式 | HTTP 检查 | +| 健康检查路径 | `/health` | + +### 2.5 部署过程中的问题与解决 + +**问题**:SAE HTTP 健康检查返回 404 + +- **现象**:Readiness probe 报 `HTTP status code: 404, body: {"error":"404 - Resource Not Found"}` +- **验证**:通过 SAE Webshell 执行 `curl http://localhost:8080/health` 返回 200 OK,确认服务本身正常 +- **解决**:最终 HTTP 健康检查配置调整后恢复正常 + +--- + +## 三、Python微服务更新 + +### 3.1 更新内容 + +**依赖变更**(requirements-prod.txt): + +| 变更 | 包名 | 用途 | +|------|-----|------| +| 新增 | `scipy>=1.11.0` | RVW V2.0 数据侦探:T检验、卡方检验逆向计算 | + +**代码变更**: + +| 模块 | 变更 | +|------|------| +| `forensics/` | 全新模块 - RVW V2.0 数据取证(5个文件) | +| `main.py` | 注册 forensics API 路由 | +| `operations/data_profile.py` | 新增 scipy 统计验证 | + +### 3.2 镜像信息 + +| 项目 | 值 | +|------|---| +| ACR 仓库 | `python-extraction` | +| 镜像版本 | v1.1 → **v1.2** | +| 镜像地址 | `crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/python-extraction:v1.2` | +| Digest | `sha256:be8612976255d706d652c5d16cb2e32c6e25b61a863d26c1ea7f63a9e0c95c86` | +| 基础镜像 | `python:3-slim` | + +### 3.3 SAE 应用配置 + +| 配置项 | 0126 部署 | 0227 部署 | +|-------|----------|----------| +| 应用名称 | `python-extraction-test` | `python-extraction-test` | +| 实例规格 | 1核2GB | **2核4GB** | +| 实例数量 | 1 | 1 | +| 容器端口 | 8000 | 8000 | +| 内网地址 | `172.17.173.84` | **`172.17.173.102`** | +| 镜像版本 | v1.1 | **v1.2** | + +> 规格从 1核2GB 升至 2核4GB,因为新增的 scipy、pandas、numpy 等科学计算库在 2 个 worker 下内存占用较高。 + +--- + +## 四、Node.js后端更新 + +### 4.1 更新内容 + +**271个文件变更,50972行新增代码**,主要包括: + +| 类别 | 变更 | +|------|------| +| 新增依赖 | `adm-zip`(ZIP处理)、`json-logic-js`(规则引擎) | +| 新增模块 | SSA 统计分析、ASL 图表/提取/Meta分析、RVW Skills、系统知识库 | +| 重大更新 | IIT CRA Agent V3.0(自主QC+Function Calling)、Deep Research V2.0 | + +### 4.2 镜像信息 + +| 项目 | 值 | +|------|---| +| ACR 仓库 | `backend-service` | +| 镜像版本 | v1.7 → **v2.2** | +| 镜像地址 | `crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v2.2` | +| Digest | `sha256:5f5ede30c5ff107018176622c674b53c640816f288d49912434303d8a5253211` | +| 构建方式 | `tsc --noCheck` + Docker 多阶段构建 | + +### 4.3 SAE 应用配置 + +| 配置项 | 0126 部署 | 0227 部署 | +|-------|----------|----------| +| 应用名称 | `nodejs-backend-test` | `nodejs-backend-test` | +| 实例规格 | 1核2GB | **2核4GB** | +| 实例数量 | 1 | 1 | +| 容器端口 | 3001 | 3001 | +| 内网地址 | `172.17.173.89` | **`172.17.197.28`** | +| 镜像版本 | v1.7 | **v2.2** | + +### 4.4 新增环境变量 + +| 环境变量 | 值 | 说明 | +|---------|---|------| +| `EXTRACTION_SERVICE_URL` | `http://172.17.173.102:8000` | Python 新地址 | +| `R_SERVICE_URL` | `http://172.17.173.101:8080` | R统计引擎(新增) | +| `UNIFUNCS_API_KEY` | `sk-2fNwqUH7...` | Deep Research(新增) | +| `MINERU_API_TOKEN` | (长token) | MinerU PDF提取(新增) | +| `MINERU_API_BASE` | `https://mineru.net/api/v4` | MinerU地址(新增) | +| `STORAGE_TYPE` | `oss` | 存储类型(新增) | + +--- + +## 五、前端Nginx更新 + +### 5.1 更新内容 + +**129个文件变更,32365行新增代码**,主要包括: + +| 类别 | 变更 | +|------|------| +| 新增依赖 | `react-markdown`、`remark-gfm`(Markdown渲染) | +| 新增模块 | SSA统计分析前端、ASL图表生成器/Meta分析引擎、IIT AI对话页 | +| nginx.conf | `client_max_body_size 50M`、新增 `/wechat/` 代理路由 | + +### 5.2 镜像信息 + +| 项目 | 值 | +|------|---| +| ACR 仓库 | `ai-clinical_frontend-nginx` | +| 镜像版本 | v1.3 → **v1.8** | +| Digest | `sha256:0a12b017ac6c85305fc5a716c5da245318c595fafd828c1222dd1a8ae79cfb26` | + +### 5.3 SAE 应用配置 + +| 配置项 | 0126 部署 | 0227 部署 | +|-------|----------|----------| +| 应用名称 | `frontend-nginx-service` | `frontend-nginx-service` | +| 实例规格 | 0.5核1GB | 0.5核1GB | +| 容器端口 | 80 | 80 | +| 内网地址 | `172.17.173.90` | **`172.17.197.29`** | +| 镜像版本 | v1.3 | **v1.8** | +| BACKEND_SERVICE_HOST | `172.17.173.89` | **`172.17.197.28`** | + +--- + +## 六、部署过程中的问题与解决 + +本次部署遇到 4 个问题,均已解决: + +### 6.1 前端登录报错:Unexpected token '<' is not valid JSON + +| 项目 | 内容 | +|------|------| +| **现象** | 登录页报 `Unexpected token '<', " 如不更新,公网域名 `https://iit.xunzhengyixue.com/` 将无法访问。 + +--- + +## 八、当前系统配置速查 + +### 数据库连接(测试环境) + +``` +postgresql://airesearch:Xibahe%40fengzhibo117@pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432/ai_clinical_research_test?connection_limit=18&pool_timeout=10 +``` + +### 服务内网地址 + +``` +R统计引擎: http://172.17.173.101:8080 (新增) +Python: http://172.17.173.102:8000 (更新) +后端: http://172.17.197.28:3001 (更新) +前端: http://172.17.197.29:80 (更新) +``` + +### ACR 镜像版本 + +| 仓库 | 版本 | +|------|-----| +| `ssa-r-statistics` | v1.0.1 | +| `python-extraction` | v1.2 | +| `backend-service` | v2.2 | +| `ai-clinical_frontend-nginx` | v1.8 | + +### 公网访问 + +``` +CLB: http://8.140.53.236/ +域名: https://iit.xunzhengyixue.com/ +``` + +--- + +> **文档版本**:v1.1 +> **最后更新**:2026-02-27(补充部署问题与解决记录) +> **维护人员**:开发团队 diff --git a/docs/05-部署文档/03-待部署变更清单.md b/docs/05-部署文档/03-待部署变更清单.md new file mode 100644 index 00000000..c1ab8870 --- /dev/null +++ b/docs/05-部署文档/03-待部署变更清单.md @@ -0,0 +1,99 @@ +# 待部署变更清单 + +> **用途**: 开发过程中实时记录所有待部署的变更,下次部署时按此清单逐项执行 +> **维护规则**: 每次修改 Schema / 新增依赖 / 改配置时,**立即**在此文档追加记录 +> **Cursor Rule**: `.cursor/rules/deployment-change-tracking.mdc` 会自动提醒 +> **最后清零**: 2026-02-27(0227 部署完成后清零) + +--- + +## 当前待部署变更 + +> ⚠️ 下次部署前,逐项检查此清单。部署完成后将已部署项移到「历史」区域并清零。 + +### 数据库变更 + +| # | 变更内容 | 迁移文件 | 优先级 | 备注 | +|---|---------|---------|--------|------| +| DB-1 | ssa_workflows 类型精度对齐 + 清理重复 FK | `20260227_align_schema_with_db_types` | 低 | 幂等 SQL,RDS 上执行无副作用 | + +### 后端变更 (Node.js) + +| # | 变更内容 | 涉及文件 | 需要操作 | 备注 | +|---|---------|---------|---------|------| +| — | *暂无* | | | | + +### 前端变更 + +| # | 变更内容 | 涉及文件 | 需要操作 | 备注 | +|---|---------|---------|---------|------| +| — | *暂无* | | | | + +### Python 微服务变更 + +| # | 变更内容 | 涉及文件 | 需要操作 | 备注 | +|---|---------|---------|---------|------| +| — | *暂无* | | | | + +### R 统计引擎变更 + +| # | 变更内容 | 涉及文件 | 需要操作 | 备注 | +|---|---------|---------|---------|------| +| — | *暂无* | | | | + +### 环境变量 / 配置变更 + +| # | 变更内容 | 服务 | 变量名 | 备注 | +|---|---------|------|--------|------| +| — | *暂无* | | | | + +### 基础设施变更 + +| # | 变更内容 | 范围 | 备注 | +|---|---------|------|------| +| — | *暂无* | | | + +--- + +## 记录模板 + +开发时发现需要部署的变更,复制下方模板追加到对应区域: + +```markdown + +| DB-N | 简述变更 | `迁移文件名` | 高/中/低 | 备注 | + + +| BE-N | 简述变更 | `file.ts` | 重新构建镜像 | 备注 | + + +| FE-N | 简述变更 | `Component.tsx` | 重新构建镜像 | 备注 | + + +| PY-N | 简述变更 | `requirements-prod.txt` | 重新构建镜像 | 备注 | + + +| R-N | 简述变更 | `tool.R` | 重新构建镜像 | 备注 | + + +| ENV-N | 简述变更 | nodejs-backend-test | `VAR_NAME=value` | 备注 | +``` + +--- + +## 历史(已部署,仅供追溯) + +### 0227 部署已清零项 + +| # | 变更内容 | 部署日期 | 结果 | +|---|---------|---------|------| +| DB | 5 个业务迁移 + 1 个 drift patch | 2026-02-27 | ✅ | +| DB | SSA data_profile 列补充 | 2026-02-27 | ✅ 线上热修 | +| DB | RVW review_tasks 8 列补充 | 2026-02-27 | ✅ 线上热修 | +| BE | Node.js v1.7 → v2.2(SSA/ASL/RVW/IIT 全模块更新) | 2026-02-27 | ✅ | +| BE | Dockerfile 增加 JSON 配置文件拷贝 | 2026-02-27 | ✅ | +| FE | 前端 v1.3 → v1.8(react-markdown, nginx 配置更新) | 2026-02-27 | ✅ | +| PY | Python v1.1 → v1.2(新增 scipy) | 2026-02-27 | ✅ | +| R | R 统计引擎 v1.0.1 全新部署 | 2026-02-27 | ✅ | +| ENV | nodejs-backend-test: R_STATISTICS_SERVICE_URL 等 | 2026-02-27 | ✅ | +| ENV | frontend-nginx-service: BACKEND_SERVICE_HOST 更新 | 2026-02-27 | ✅ | diff --git a/docs/05-部署文档/README.md b/docs/05-部署文档/README.md index 570dd41f..6136afb6 100644 --- a/docs/05-部署文档/README.md +++ b/docs/05-部署文档/README.md @@ -1,405 +1,70 @@ -# 🚀 AI临床研究平台 - 部署文档中心 +# 部署文档中心 -> **最后更新**:2025-12-25 -> **部署状态**:✅ 完全成功,所有服务运行正常 -> **公网访问**:http://8.140.53.236/ +> 版本: v2.0 +> 更新日期: 2026-02-27 +> 适用架构: 阿里云 SAE + RDS PostgreSQL + ACR + OSS + CLB --- -## 🎯 快速开始(3分钟找到你需要的文档) +## 快速导航 -### 我要做什么? - -| 你的目标 | 推荐文档 | 预计时间 | -|---------|---------|---------| -| 🔥 **日常更新代码(最常用)** | [19-日常更新快速操作手册](./19-日常更新快速操作手册.md) ⭐⭐⭐⭐⭐ | 20-25分钟 | -| 🚀 **完整部署系统** | [17-完整部署实战手册-2025版](./17-完整部署实战手册-2025版.md) | 3.5-6小时 | -| 🔍 **查询IP/密码等信息** | [00-部署进度总览](./00-部署进度总览.md) | 1分钟 | -| 📚 **学习部署原理** | [01-快速部署SOP-零基础版](./01-快速部署SOP-零基础版.md) | 4小时 | -| 🐍 **部署Python服务** | [09-Python微服务-SAE部署操作手册](./09-Python微服务-SAE部署操作手册.md) | 35分钟 | -| 🟢 **部署Node.js后端** | [12-Node.js后端-SAE部署操作手册](./12-Node.js后端-SAE部署操作手册.md) | 50分钟 | -| 🎨 **部署前端Nginx** | [07-前端Nginx-SAE部署操作手册](./07-前端Nginx-SAE部署操作手册.md) | 30分钟 | -| ❌ **遇到问题排查** | [15-Node.js后端-部署成功总结](./15-Node.js后端-部署成功总结.md) | 按需 | -| 📖 **不知道看哪个文档** | [18-部署文档使用指南](./18-部署文档使用指南.md) | 5分钟 | +| 你的目标 | 文档 | +|---------|------| +| 查看当前线上状态(IP/版本/密码) | [00-阿里云SAE最新真实状态记录](./00-阿里云SAE最新真实状态记录.md) | +| 查看下次需要部署什么 | [03-待部署变更清单](./03-待部署变更清单.md) | +| 执行日常更新(构建/推送/部署) | [01-日常更新操作手册](./01-日常更新操作手册.md) | +| 了解部署架构全貌 | [00-部署架构总览](./00-部署架构总览.md) | +| 查看某次具体部署记录 | `0126部署/` 或 `0227部署/` | +| 查看历史文档(2025首次部署) | `_archive-2025首次部署/` | --- -## 🔥 日常更新操作(高频使用)⭐⭐⭐⭐⭐ +## 目录结构 -### [19-日常更新快速操作手册.md](./19-日常更新快速操作手册.md) +``` +05-部署文档/ +├── 00-部署架构总览.md # 架构图、服务拓扑、部署顺序 +├── 00-阿里云SAE最新真实状态记录.md # ⭐ 核心:实时反映线上真实状态 +├── 01-日常更新操作手册.md # ⭐ 核心:统一的4服务部署SOP +├── 03-待部署变更清单.md # ⭐ 核心:开发中实时记录,部署时逐项检查 +│ +├── 0126部署/ # 2026-01-26 部署记录(归档) +├── 0227部署/ # 2026-02-27 部署记录(归档) +│ +└── _archive-2025首次部署/ # 2025-12 首次部署的原始文档(25个文件) +``` -**⚡ 最常用的文档!适合日常功能更新和快速迭代!** +### 核心文档职责 -**为什么推荐**: -- ✅ 短小精悍(670行),关键信息密集 -- ✅ 可直接复制执行的命令 -- ✅ 包含一键更新脚本 -- ✅ 适合团队协作和AI助手使用 +| 文档 | 职责 | 更新频率 | +|------|------|---------| +| **00-SAE最新真实状态记录** | "线上是什么样" — IP、版本、密码、环境变量 | 每次部署后 | +| **01-日常更新操作手册** | "怎么部署" — 4 个服务的构建/推送/部署 SOP | 流程变更时 | +| **03-待部署变更清单** | "要部署什么" — 开发中累积的待部署项 | 开发中实时记录 | -**包含内容**: -- **更新Node.js后端**(20-25分钟)- 最常用! - ```bash - 编译 → 构建镜像 → 推送ACR → SAE部署 → 验证 - ``` -- **更新前端Nginx**(15-20分钟) -- **更新Python服务**(30分钟) -- **修改环境变量**(5分钟)- 高频操作! -- **查看日志**(1分钟) -- **回滚操作**(7分钟) -- **一键更新脚本**(自动化) +### 每次部署的流程 -**适合人群**: -- 🎯 日常开发迭代的开发人员 -- 🎯 需要快速部署更新的运维人员 -- 🎯 团队新成员快速上手 -- 🎯 AI助手执行部署任务 +``` +部署前: + 1. 打开 03-待部署变更清单.md → 确认本次要部署哪些 + 2. 打开 00-SAE最新真实状态记录.md → 确认当前版本号 -**快速示例**: -```bash -# 更新Node.js后端到v1.5 -cd backend -npm run build -docker build -t backend-service:v1.5 . -docker push crpi-xxx.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.5 -# 然后在SAE控制台部署新版本 +执行中: + 3. 按 01-日常更新操作手册.md 逐服务执行 + +部署后: + 4. 更新 00-SAE最新真实状态记录.md(新IP/新版本) + 5. 清零 03-待部署变更清单.md(已部署项移到历史) + 6. 创建 MMDD部署/02-部署完成总结.md(记录过程和问题) ``` --- -## ⭐ 核心文档(新手必看) - -### 1️⃣ 完整部署实战手册(强烈推荐)⭐⭐⭐⭐⭐ - -**[17-完整部署实战手册-2025版.md](./17-完整部署实战手册-2025版.md)** - -**为什么推荐**: -- ✅ 基于2025-12-25实际部署经历编写 -- ✅ 包含所有遇到的问题及解决方案 -- ✅ 1800行详细步骤,可直接复制命令 -- ✅ 跟着做就能成功! - -**包含内容**: -- 完整部署流程(VPC→RDS→Python→Node.js→前端→CLB) -- 4个关键问题修复(环境变量、config、pino-pretty、ES Module) -- 关键经验总结(重启vs部署、环境变量命名等) -- 快速命令参考 -- 完整链路测试 - -**适合人群**: -- 🎯 要快速部署的人 -- 🎯 重新部署或迁移的人 -- 🎯 想了解实际坑点的人 - ---- - -### 2️⃣ 部署进度总览(日常必备)⭐⭐⭐⭐⭐ - -**[00-部署进度总览.md](./00-部署进度总览.md)** - -**为什么推荐**: -- ✅ 所有资源信息的索引中心 -- ✅ 快速查询IP、密码、环境变量 -- ✅ 文档导航指南 -- ✅ 部署状态追踪 - -**包含内容**: -- SAE应用内网IP地址 -- RDS数据库连接信息 -- OSS AccessKey -- ACR镜像仓库地址 -- 环境变量配置清单 -- 快速命令参考 - -**适合场景**: -- 🔍 忘记IP地址 -- 🔍 忘记数据库密码 -- 🔍 需要查询资源配置 -- 🔍 需要找相关文档 - ---- - -### 3️⃣ 部署文档使用指南⭐⭐⭐⭐ - -**[18-部署文档使用指南.md](./18-部署文档使用指南.md)** - -**为什么推荐**: -- ✅ 快速导航,找到需要的文档 -- ✅ 不同场景的阅读路径 -- ✅ 关键信息速查表 -- ✅ 最佳实践建议 - -**适合人群**: -- 📖 不知道从哪个文档开始看 -- 📖 想快速找到特定信息 -- 📖 想了解文档结构 - ---- - -## 📁 完整文档列表 - -### 🎯 核心指南(3个) -1. [README.md](./README.md) - 本文档,总入口 -2. [00-部署进度总览.md](./00-部署进度总览.md) - 资源速查、文档索引 -3. [18-部署文档使用指南.md](./18-部署文档使用指南.md) - 快速导航 - -### 🚀 完整部署(2个) -1. [17-完整部署实战手册-2025版.md](./17-完整部署实战手册-2025版.md) - ⭐ 实战版(推荐) -2. [01-快速部署SOP-零基础版.md](./01-快速部署SOP-零基础版.md) - 学习版 - -### 🔧 服务部署手册(4个) -1. [09-Python微服务-SAE部署操作手册.md](./09-Python微服务-SAE部署操作手册.md) -2. [12-Node.js后端-SAE部署操作手册.md](./12-Node.js后端-SAE部署操作手册.md) -3. [07-前端Nginx-SAE部署操作手册.md](./07-前端Nginx-SAE部署操作手册.md) -4. [08-PostgreSQL数据库部署操作手册.md](./08-PostgreSQL数据库部署操作手册.md) - -### 📖 技术详解(4个) -1. [04-Python微服务-SAE容器部署指南.md](./04-Python微服务-SAE容器部署指南.md) -2. [05-Node.js后端-SAE容器部署指南.md](./05-Node.js后端-SAE容器部署指南.md) -3. [06-前端Nginx-SAE容器部署指南.md](./06-前端Nginx-SAE容器部署指南.md) -4. [10-Node.js后端-Docker镜像构建手册.md](./10-Node.js后端-Docker镜像构建手册.md) - -### 📝 配置清单(1个) -1. [11-Node.js后端-SAE部署配置清单.md](./11-Node.js后端-SAE部署配置清单.md) - 21个环境变量详解 - -### 🐛 问题修复(4个) -1. [13-Node.js后端-镜像修复记录.md](./13-Node.js后端-镜像修复记录.md) - config目录问题 -2. [14-Node.js后端-pino-pretty问题修复.md](./14-Node.js后端-pino-pretty问题修复.md) - 日志配置问题 -3. [15-Node.js后端-部署成功总结.md](./15-Node.js后端-部署成功总结.md) - ⭐ 完整问题汇总 -4. [16-前端Nginx-部署成功总结.md](./16-前端Nginx-部署成功总结.md) - 前端部署总结 - ---- - -## 🎉 部署成功证明 - -### 当前部署状态(2025-12-25) - -| 服务 | 状态 | 内网地址 | 公网访问 | -|------|------|---------|---------| -| RDS PostgreSQL | ✅ 运行中 | `pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432` | ❌ | -| Python微服务 | ✅ 运行中 | `172.17.173.66:8000` | ❌ | -| Node.js后端 | ✅ 运行中 | `172.17.173.73:3001` | ❌ | -| 前端Nginx | ✅ 运行中 | `172.17.173.72:80` | ✅ | -| CLB负载均衡 | ✅ 运行中 | - | `http://8.140.53.236/` | - -### 功能验证 - -- ✅ 前端页面正常访问 -- ✅ 用户登录功能正常 -- ✅ 文献筛查模块正常 -- ✅ 数据清洗工具C的7大功能全部正常 -- ✅ 文件上传功能正常 -- ✅ AI对话功能正常 -- ✅ 数据库连接正常 -- ✅ Python服务调用正常 -- ✅ 响应时间 < 1秒 - ---- - -## ⚠️ 关键经验(必读) - -### 1. 环境变量名必须精确 - -**❌ 错误配置**: -```bash -PYTHON_SERVICE_URL=http://172.17.173.66:8000 -``` - -**✅ 正确配置**: -```bash -EXTRACTION_SERVICE_URL=http://172.17.173.66:8000 -``` - -**教训**:代码中使用的是 `EXTRACTION_SERVICE_URL`,环境变量名一个字母都不能错! - ---- - -### 2. 区分"重启应用"和"部署应用" - -| 操作 | 用途 | IP是否变 | 何时使用 | -|------|------|---------|---------| -| **重启应用** | 重启容器 | ❌ 不会变 | 修改环境变量、调整配置 | -| **部署应用** | 更新镜像 | ✅ 会变更 | 更新代码、更新镜像版本 | - -**教训**:只修改环境变量时,用"重启应用",避免IP变更导致其他服务配置失效! - ---- - -### 3. Dockerfile必须包含config目录 - -**问题**: -``` -ENOENT: no such file or directory, open '/app/config/agents.yaml' -``` - -**解决**: -```dockerfile -# ✅ 必须添加 -COPY config ./config -``` - ---- - -### 4. 使用VPC地址拉取镜像(省钱) - -**SAE拉取镜像时**: -```bash -# ✅ 正确(VPC地址,免流量费) -crpi-xxx-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.3 - -# ❌ 不推荐(公网地址,收流量费) -crpi-xxx.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.3 -``` - ---- - -## 💡 快速命令参考 - -### 登录ACR -```bash -docker login --username=gofeng117@163.com \ - --password=fengzhibo117 \ - crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com -``` - -### 构建并推送镜像 -```bash -# Node.js后端 -cd backend -npm run build -docker build -t backend-service:v1.3 . -docker tag backend-service:v1.3 \ - crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.3 -docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.3 -``` - -### 健康检查 -```bash -# Python服务 -curl http://172.17.173.66:8000/api/health - -# Node.js后端 -curl http://172.17.173.73:3001/health - -# 前端Nginx -curl http://172.17.173.72:80/health - -# 公网访问 -curl http://8.140.53.236/ -``` - ---- - -## 📊 部署架构图 - -``` -用户浏览器 - ↓ HTTP (公网) -CLB负载均衡器 (8.140.53.236) - ↓ HTTP (内网) -前端Nginx (172.17.173.72:80) - ↓ HTTP (内网, /api/v1/) -Node.js后端 (172.17.173.73:3001) - ↓ HTTP (内网, /api/dc/) -Python服务 (172.17.173.66:8000) - ↓ SQL (内网) -RDS PostgreSQL (pgm-2zex1m2y3r23hdn5.pg.rds.aliyuncs.com:5432) -``` - ---- - -## 🆘 需要帮助? - -### 常见问题 - -**Q:我是新手,从哪里开始?** -- A:直接看 [17-完整部署实战手册-2025版](./17-完整部署实战手册-2025版.md) - -**Q:只想更新代码,不想全部重新部署?** -- A:看对应服务的操作手册(如 [12-Node.js后端-SAE部署操作手册](./12-Node.js后端-SAE部署操作手册.md)) - -**Q:遇到报错了怎么办?** -- A:先看 [17-完整部署实战手册-2025版](./17-完整部署实战手册-2025版.md) 第9节 - -**Q:忘记密码或IP地址了?** -- A:查 [00-部署进度总览](./00-部署进度总览.md) - -**Q:不知道看哪个文档?** -- A:看 [18-部署文档使用指南](./18-部署文档使用指南.md) - ---- - -## 🎯 推荐阅读路径 - -### 路径1:首次完整部署(新手) - -``` -17-完整部署实战手册-2025版.md(主线) - ↓ -00-部署进度总览.md(查资源信息) - ↓ -15-Node.js后端-部署成功总结.md(遇到问题时) -``` - -**预计时间**:3.5 - 6小时 - ---- - -### 路径2:更新某个服务(熟练) - -``` -对应服务的操作手册(如12-Node.js后端-SAE部署操作手册.md) - ↓ -00-部署进度总览.md(查ACR地址) -``` - -**预计时间**:15 - 30分钟 - ---- - -### 路径3:修改环境变量 - -``` -11-Node.js后端-SAE部署配置清单.md(确认变量名) - ↓ -SAE控制台修改 - ↓ -重启应用(不是部署应用!) -``` - -**预计时间**:5分钟 - ---- - -## 📞 技术支持 - -- **开发团队**:内部文档体系 -- **阿里云工单**:https://workorder.console.aliyun.com/ -- **紧急问题**:先查文档,99%的问题都有解决方案 - ---- - -## 🎉 总结 - -**恭喜您找到了完整的部署文档!** - -### 3个核心文档记住它们 - -1. **本文档(README)** - 总入口,快速导航 -2. **[17-完整部署实战手册-2025版](./17-完整部署实战手册-2025版.md)** - 部署必看 -3. **[00-部署进度总览](./00-部署进度总览.md)** - 信息速查 - -### 部署成功的3个关键 - -1. ✅ 环境变量名必须精确匹配代码 -2. ✅ 区分"重启应用"和"部署应用" -3. ✅ 按顺序部署,每步都要验证 - ---- - -> **最后更新**:2025-12-25 -> **部署状态**:✅ 完全成功 -> **公网访问**:http://8.140.53.236/ -> **维护人员**:开发团队 - -🚀 **开始部署吧!祝您顺利!** - +## 相关文档索引 + +| 关注点 | 文档位置 | +|--------|---------| +| 数据库架构与迁移 | `docs/01-平台基础层/07-数据库/` | +| 数据库开发规范 | `docs/04-开发规范/09-数据库开发规范.md` | +| 运维监控 | `docs/07-运维文档/` | +| 云原生开发规范 | `docs/04-开发规范/08-云原生开发规范.md` | diff --git a/docs/05-部署文档/01-快速部署SOP-零基础版.md b/docs/05-部署文档/_archive-2025首次部署/01-快速部署SOP-零基础版.md similarity index 100% rename from docs/05-部署文档/01-快速部署SOP-零基础版.md rename to docs/05-部署文档/_archive-2025首次部署/01-快速部署SOP-零基础版.md diff --git a/docs/05-部署文档/02-SAE部署完全指南(产品经理版).md b/docs/05-部署文档/_archive-2025首次部署/02-SAE部署完全指南(产品经理版).md similarity index 100% rename from docs/05-部署文档/02-SAE部署完全指南(产品经理版).md rename to docs/05-部署文档/_archive-2025首次部署/02-SAE部署完全指南(产品经理版).md diff --git a/docs/05-部署文档/03-Dify-ECS部署完全指南.md b/docs/05-部署文档/_archive-2025首次部署/03-Dify-ECS部署完全指南.md similarity index 100% rename from docs/05-部署文档/03-Dify-ECS部署完全指南.md rename to docs/05-部署文档/_archive-2025首次部署/03-Dify-ECS部署完全指南.md diff --git a/docs/05-部署文档/04-Python微服务-SAE容器部署指南.md b/docs/05-部署文档/_archive-2025首次部署/04-Python微服务-SAE容器部署指南.md similarity index 100% rename from docs/05-部署文档/04-Python微服务-SAE容器部署指南.md rename to docs/05-部署文档/_archive-2025首次部署/04-Python微服务-SAE容器部署指南.md diff --git a/docs/05-部署文档/05-Node.js后端-SAE容器部署指南.md b/docs/05-部署文档/_archive-2025首次部署/05-Node.js后端-SAE容器部署指南.md similarity index 100% rename from docs/05-部署文档/05-Node.js后端-SAE容器部署指南.md rename to docs/05-部署文档/_archive-2025首次部署/05-Node.js后端-SAE容器部署指南.md diff --git a/docs/05-部署文档/06-前端Nginx-SAE容器部署指南.md b/docs/05-部署文档/_archive-2025首次部署/06-前端Nginx-SAE容器部署指南.md similarity index 100% rename from docs/05-部署文档/06-前端Nginx-SAE容器部署指南.md rename to docs/05-部署文档/_archive-2025首次部署/06-前端Nginx-SAE容器部署指南.md diff --git a/docs/05-部署文档/07-关键配置补充说明.md b/docs/05-部署文档/_archive-2025首次部署/07-关键配置补充说明.md similarity index 100% rename from docs/05-部署文档/07-关键配置补充说明.md rename to docs/05-部署文档/_archive-2025首次部署/07-关键配置补充说明.md diff --git a/docs/05-部署文档/07-前端Nginx-SAE部署操作手册.md b/docs/05-部署文档/_archive-2025首次部署/07-前端Nginx-SAE部署操作手册.md similarity index 100% rename from docs/05-部署文档/07-前端Nginx-SAE部署操作手册.md rename to docs/05-部署文档/_archive-2025首次部署/07-前端Nginx-SAE部署操作手册.md diff --git a/docs/05-部署文档/08-PostgreSQL数据库部署操作手册.md b/docs/05-部署文档/_archive-2025首次部署/08-PostgreSQL数据库部署操作手册.md similarity index 100% rename from docs/05-部署文档/08-PostgreSQL数据库部署操作手册.md rename to docs/05-部署文档/_archive-2025首次部署/08-PostgreSQL数据库部署操作手册.md diff --git a/docs/05-部署文档/08-部署检查清单.md b/docs/05-部署文档/_archive-2025首次部署/08-部署检查清单.md similarity index 100% rename from docs/05-部署文档/08-部署检查清单.md rename to docs/05-部署文档/_archive-2025首次部署/08-部署检查清单.md diff --git a/docs/05-部署文档/09-Python微服务-SAE部署操作手册.md b/docs/05-部署文档/_archive-2025首次部署/09-Python微服务-SAE部署操作手册.md similarity index 100% rename from docs/05-部署文档/09-Python微服务-SAE部署操作手册.md rename to docs/05-部署文档/_archive-2025首次部署/09-Python微服务-SAE部署操作手册.md diff --git a/docs/05-部署文档/10-Node.js后端-Docker镜像构建手册.md b/docs/05-部署文档/_archive-2025首次部署/10-Node.js后端-Docker镜像构建手册.md similarity index 100% rename from docs/05-部署文档/10-Node.js后端-Docker镜像构建手册.md rename to docs/05-部署文档/_archive-2025首次部署/10-Node.js后端-Docker镜像构建手册.md diff --git a/docs/05-部署文档/11-Node.js后端-SAE部署配置清单.md b/docs/05-部署文档/_archive-2025首次部署/11-Node.js后端-SAE部署配置清单.md similarity index 100% rename from docs/05-部署文档/11-Node.js后端-SAE部署配置清单.md rename to docs/05-部署文档/_archive-2025首次部署/11-Node.js后端-SAE部署配置清单.md diff --git a/docs/05-部署文档/12-Node.js后端-SAE部署操作手册.md b/docs/05-部署文档/_archive-2025首次部署/12-Node.js后端-SAE部署操作手册.md similarity index 100% rename from docs/05-部署文档/12-Node.js后端-SAE部署操作手册.md rename to docs/05-部署文档/_archive-2025首次部署/12-Node.js后端-SAE部署操作手册.md diff --git a/docs/05-部署文档/13-Node.js后端-镜像修复记录.md b/docs/05-部署文档/_archive-2025首次部署/13-Node.js后端-镜像修复记录.md similarity index 100% rename from docs/05-部署文档/13-Node.js后端-镜像修复记录.md rename to docs/05-部署文档/_archive-2025首次部署/13-Node.js后端-镜像修复记录.md diff --git a/docs/05-部署文档/14-Node.js后端-pino-pretty问题修复.md b/docs/05-部署文档/_archive-2025首次部署/14-Node.js后端-pino-pretty问题修复.md similarity index 100% rename from docs/05-部署文档/14-Node.js后端-pino-pretty问题修复.md rename to docs/05-部署文档/_archive-2025首次部署/14-Node.js后端-pino-pretty问题修复.md diff --git a/docs/05-部署文档/15-Node.js后端-部署成功总结.md b/docs/05-部署文档/_archive-2025首次部署/15-Node.js后端-部署成功总结.md similarity index 100% rename from docs/05-部署文档/15-Node.js后端-部署成功总结.md rename to docs/05-部署文档/_archive-2025首次部署/15-Node.js后端-部署成功总结.md diff --git a/docs/05-部署文档/16-前端Nginx-部署成功总结.md b/docs/05-部署文档/_archive-2025首次部署/16-前端Nginx-部署成功总结.md similarity index 100% rename from docs/05-部署文档/16-前端Nginx-部署成功总结.md rename to docs/05-部署文档/_archive-2025首次部署/16-前端Nginx-部署成功总结.md diff --git a/docs/05-部署文档/17-完整部署实战手册-2025版.md b/docs/05-部署文档/_archive-2025首次部署/17-完整部署实战手册-2025版.md similarity index 100% rename from docs/05-部署文档/17-完整部署实战手册-2025版.md rename to docs/05-部署文档/_archive-2025首次部署/17-完整部署实战手册-2025版.md diff --git a/docs/05-部署文档/18-部署文档使用指南.md b/docs/05-部署文档/_archive-2025首次部署/18-部署文档使用指南.md similarity index 100% rename from docs/05-部署文档/18-部署文档使用指南.md rename to docs/05-部署文档/_archive-2025首次部署/18-部署文档使用指南.md diff --git a/docs/05-部署文档/19-日常更新快速操作手册.md b/docs/05-部署文档/_archive-2025首次部署/19-日常更新快速操作手册.md similarity index 100% rename from docs/05-部署文档/19-日常更新快速操作手册.md rename to docs/05-部署文档/_archive-2025首次部署/19-日常更新快速操作手册.md diff --git a/docs/05-部署文档/CTO 代码审查报告:AI临床研究平台部署架构.md b/docs/05-部署文档/_archive-2025首次部署/CTO 代码审查报告:AI临床研究平台部署架构.md similarity index 100% rename from docs/05-部署文档/CTO 代码审查报告:AI临床研究平台部署架构.md rename to docs/05-部署文档/_archive-2025首次部署/CTO 代码审查报告:AI临床研究平台部署架构.md diff --git a/docs/05-部署文档/PostgreSQL部署策略-摸底报告.md b/docs/05-部署文档/_archive-2025首次部署/PostgreSQL部署策略-摸底报告.md similarity index 100% rename from docs/05-部署文档/PostgreSQL部署策略-摸底报告.md rename to docs/05-部署文档/_archive-2025首次部署/PostgreSQL部署策略-摸底报告.md diff --git a/docs/05-部署文档/SSL 证书域名SAE配置指南.md b/docs/05-部署文档/_archive-2025首次部署/SSL 证书域名SAE配置指南.md similarity index 100% rename from docs/05-部署文档/SSL 证书域名SAE配置指南.md rename to docs/05-部署文档/_archive-2025首次部署/SSL 证书域名SAE配置指南.md diff --git a/docs/05-部署文档/文档修正报告-20251214.md b/docs/05-部署文档/_archive-2025首次部署/文档修正报告-20251214.md similarity index 100% rename from docs/05-部署文档/文档修正报告-20251214.md rename to docs/05-部署文档/_archive-2025首次部署/文档修正报告-20251214.md diff --git a/docs/05-部署文档/集成部署补充指南:填补最后的缝隙.md b/docs/05-部署文档/_archive-2025首次部署/集成部署补充指南:填补最后的缝隙.md similarity index 100% rename from docs/05-部署文档/集成部署补充指南:填补最后的缝隙.md rename to docs/05-部署文档/_archive-2025首次部署/集成部署补充指南:填补最后的缝隙.md diff --git a/docs/09-架构实施/J技术架构咨询/数据库同步规范与 Prisma 操作指南.md b/docs/09-架构实施/J技术架构咨询/数据库同步规范与 Prisma 操作指南.md new file mode 100644 index 00000000..e718c86b --- /dev/null +++ b/docs/09-架构实施/J技术架构咨询/数据库同步规范与 Prisma 操作指南.md @@ -0,0 +1,96 @@ +# **Prisma 数据库同步与生产部署规范 (SOP)** + +针对本地 schema.prisma 与真实数据库不同步(Schema Drift)的问题,结合我们平台的“Postgres-Only”架构特性(存在大量非 Prisma 管理的底层函数,如 pg-boss),特制定本规范。 + +## **一、 当前差距有多大?如何安全评估?** + +由于我无法直接连接您的本地数据库,当前的“具体差距”需要您通过命令行来测量。基于系统近期的 V2.1 迭代(引入了 SSA QPER 架构、RVW 模块 Schema 隔离、IIT 模块表等),大概率存在未提交的 Migration 或手动修改的字段。 + +### **安全测量差距的指令(只读,绝对安全)** + +请在 backend 目录下运行以下命令来查看差距,**不要直接跑 push**: + +\# 查看本地 Schema 与当前数据库的差异 (Diff) +npx prisma migrate diff \--from-schema-datamodel prisma/schema.prisma \--to-schema-datamodel prisma/schema.prisma + +\# 或者更直观地查看哪些迁移尚未应用 +npx prisma migrate status + +**差距通常分为三类:** + +1. **Prisma 超前**:你在 schema.prisma 里加了新模型(如 IitProject),但还没在数据库建表。 +2. **数据库超前**:你或队友手动在数据库里跑了 SQL 加了字段,但没更新到 schema.prisma。 +3. **平台边界对象(预期内差距)**:数据库中存在 platform\_schema.job\_common 表和 create\_queue() 函数。由于我们是 Postgres-Only 架构使用了 pg-boss,这些对象**不由 Prisma 管理**,在对比时 Prisma 可能会认为这些是“多余的”,这是正常的,**绝对不能让 Prisma 删掉它们**。 + +## **二、 如何彻底解决并确立规范操作?** + +要彻底解决不同步问题,必须明确\*\*“唯一事实来源 (Single Source of Truth)”**。在现代 ORM 开发流程中,**schema.prisma 必须是数据库结构的唯一事实来源\*\*。 + +### **🔴 绝对红线(重申 2026-01-11 事故教训)** + +任何情况下,**严禁**使用以下命令(除非是全新的空数据库): + +* ❌ npx prisma db push \--force-reset (会清空所有数据并删除 pg-boss 队列!) +* ❌ npx prisma migrate reset (会重置整个数据库) +* ❌ npx prisma db push (在生产环境**绝对禁用**,在本地也尽量少用,因为它不生成迁移历史,容易导致状态撕裂) + +### **✅ 规范 1:本地开发环境同步 SOP(解决当前不同步)** + +当你在本地发现 schema.prisma 和数据库不一致时,请严格按照以下 4 步操作: + +**Step 1: 强制备份(生命线)** + +docker exec ai-clinical-postgres pg\_dump \-U postgres \-d ai\_clinical\_research \> backup\_$(date \+%Y%m%d).sql + +**Step 2: 确定谁才是对的?** + +* **情况 A(正常开发):schema.prisma 是最新的,数据库旧了。** + 执行生成迁移文件的命令: + npx prisma migrate dev \--name describe\_your\_changes + + *说明:这会根据 Prisma Schema 生成一段完整的 SQL (.sql 文件),并安全地应用到本地数据库。如果报错说有冲突,通常是因为存在手动修改的数据。* +* **情况 B(特殊情况):数据库是最新的(比如 DBA 直接改了库),schema.prisma 旧了。** + 执行反向拉取: + npx prisma db pull + + *说明:这会将数据库当前的真实结构覆盖写入你的 schema.prisma 中。完成后别忘了执行 npx prisma generate 更新 Node.js 客户端。* + +**Step 3: 重新生成 Client** + +无论采用哪种情况,同步完成后必须刷新客户端: + +npx prisma generate + +### **✅ 规范 2:生产环境部署 SOP(未来如何部署)** + +在云端(阿里云 SAE \+ RDS)部署时,数据库的操作极其敏感。生产环境**只允许通过标准的 SQL 迁移文件进行变更**。 + +**Step 1: 确保本地已生成 Migration** + +在本地开发完成后,所有的变更都应该已经通过 npx prisma migrate dev 生成在了 prisma/migrations/ 目录下,并随代码提交到了 Git 仓库。 + +**Step 2: 生产环境应用迁移** + +在后端服务部署时(可以通过 CI/CD 管道,或在单独的部署容器中),执行以下命令: + +\# 设置生产环境变量 +export DATABASE\_URL="postgresql://user:password@rds-host:5432/ai\_clinical\_research" + +\# 执行生产部署专属命令 +npx prisma migrate deploy + +*原理:migrate deploy **不会**去对比 schema.prisma,它只会傻瓜式地检查 \_prisma\_migrations 表,把还没跑过的 .sql 脚本按顺序执行一遍。这是业界最安全、最规范的做法。* + +### **✅ 规范 3:Postgres-Only 架构特殊边界守护** + +因为我们平台利用了 PostgreSQL 作为队列(pg-boss)和缓存,Prisma 在执行某些深度同步时,可能会误删这些非 Prisma 表。 + +**防范策略:** + +1. 始终保留恢复脚本(目前我们已有 restore\_job\_common.sql 和 restore\_pgboss\_functions.sql)。 +2. 在执行 migrate dev 之后,如果发现 pg-boss 服务崩溃,立即通过 psql 执行上述恢复脚本,将函数重新注入到 platform\_schema 中。 +3. 团队成员之间必须达成共识:所有针对业务表的修改必须走 schema.prisma;所有针对平台底层调度机制(如缓存、队列函数)的修改,直接走原生 SQL,并将其文档化。 + +## **结语** + +遵循 **“以 schema.prisma 为核心 \-\> 生成 Migration \-\> 本地 migrate dev \-\> 生产 migrate deploy”** 这条标准流水线,就能彻底告别环境撕裂,且为百人并发、多实例部署提供最坚实的数据底座。 \ No newline at end of file diff --git a/docs/09-架构实施/J技术架构咨询/阿里云 SAE 全栈部署与高并发弹性策略指南.md b/docs/09-架构实施/J技术架构咨询/阿里云 SAE 全栈部署与高并发弹性策略指南.md new file mode 100644 index 00000000..ae280bbe --- /dev/null +++ b/docs/09-架构实施/J技术架构咨询/阿里云 SAE 全栈部署与高并发弹性策略指南.md @@ -0,0 +1,112 @@ +# **阿里云 SAE 全栈部署与高并发弹性策略指南** + +基于 AIclinicalresearch 平台当前的四层架构(前端、Node.js 后端、Python 微服务、R 统计引擎),本指南旨在统筹规划阿里云 Serverless App Engine (SAE) 的使用策略。不仅涵盖了 R 引擎的单线程阻断解法,更扩展至全栈模块的弹性配置、潮汐流量应对 SOP,以及 SAE 高阶功能的深度利用。 + +## **一、 全系统 SAE 规格与弹性扩容指标配置** + +针对不同模块的技术特性,SAE 的**弹性扩容指标**(触发 Scale-out 的阈值)必须差异化配置,切忌一刀切。 + +### **1\. R 统计引擎 (ssa-r-statistics)** + +* **特性**:R 语言和 Plumber 框架默认单线程阻塞。复杂矩阵运算消耗大量 CPU 和内存。镜像极大(1.81GB)。 +* **基础规格**:2 vCPU, 4 GB (绝对下限)。 +* **实例数策略**:最小实例 \= 1,最大实例 \= 5。 +* **🔥 弹性扩容指标**:**基于并发请求数 (QPS / 并发连接数)**。 + * **策略**:当单实例并发请求数 \> 1 或 \> 2 时,立即触发扩容。因为 CPU 还没跑满时,请求已经在排队了,必须用并发数来敏锐感知阻塞。 + +### **2\. Node.js 后端 (backend-service)** + +* **特性**:异步非阻塞,擅长高并发 I/O。持有大量 SSE 长链接(AI 流式对话)。包含 pg-boss 队列。 +* **基础规格**:2 vCPU, 4 GB。 +* **实例数策略**:最小实例 \= 1,最大实例 \= 5。 +* **🔥 弹性扩容指标**:**基于 CPU 和内存使用率**。 + * **策略**:当 CPU 使用率 \> 70% 或 内存使用率 \> 80% 时触发扩容。Fastify 框架抗并发极强,通常是 JSON 序列化或 Prisma 并发查询导致 CPU 飙升。 + +### **3\. Python 微服务 (python-extraction)** + +* **特性**:PDF 解析(PyMuPDF)和数据清洗(Pandas)是内存消耗大户。 +* **基础规格**:1 vCPU, 2 GB 或 2 vCPU, 4 GB(取决于平均 PDF 大小)。 +* **实例数策略**:最小实例 \= 1,最大实例 \= 3。 +* **🔥 弹性扩容指标**:**基于内存使用率**。 + * **策略**:当内存使用率 \> 85% 时扩容。Python 数据处理极易引发 OOM,需通过扩容分散大文件处理压力。 + +### **4\. 前端 Nginx (frontend-nginx)** + +* **特性**:静态资源分发,极度轻量。 +* **基础规格**:1 vCPU, 2 GB(甚至更低)。 +* **实例数策略**:最小实例 \= 1,最大实例 \= 3。 +* **🔥 弹性扩容指标**:**基于 CPU 或出网流量**。 + * **策略**:CPU \> 60% 或 出网带宽达到瓶颈时扩容。 + +## **二、 高并发场景操作 SOP(以“培训班”潮汐流量为例)** + +面对培训班(如 50-100 人同时操作统计模块)产生的突发流量,**千万不能依赖临时的自动扩容**(拉取 1.8GB 镜像需要时间,会导致大规模 504 超时)。必须采用\*\*定时弹性伸缩(Cron HPA)\*\*进行预热。 + +### **🎯 操作时间线与策略** + +#### **1\. 培训班开始前 1 天(配置策略)** + +* **动作**:登录阿里云 SAE 控制台,进入 R 统计引擎和 Node.js 后端的【弹性伸缩】配置页面。 +* **配置**:添加“定时弹性策略”(Cron HPA)。 + * 设定执行时间:例如 2026-03-01 08:30(提前半小时)。 + * 设定目标实例数:强制将实例数扩展至 3 或 5 个。 + +#### **2\. 培训班开始前 30 分钟(系统预热)** + +* **动作**:SAE 会根据设定的 Cron 规则自动启动新实例。 +* **效果**:系统完成 1.8GB 镜像拉取、环境初始化、加载 R/Python 依赖包。所有实例状态变为 Healthy,提前排兵布阵完毕。 + +#### **3\. 培训班进行中(9:00 \- 17:00)** + +* **动作**:无需人工干预。 +* **效果**:50 名学员同时点击“运行 T 检验”,SAE 网关将请求均匀分发给 5 个预热好的 R 引擎实例。单线程阻塞被完美的物理隔离化解。 + +#### **4\. 培训班结束后(17:30 以后)** + +* **动作**:依靠 SAE 的定时策略或自动缩容策略自动执行。 +* **效果**:实例数恢复至最小 1 个,立刻停止多余计费。整体成本开销仅为 5 个实例运行 8 小时的费用(极具性价比)。 + +## **三、 全栈架构如何深度利用 SAE 高阶功能** + +除了弹性扩容,结合你们的系统状态,强烈建议启用 SAE 的以下功能来提升系统的企业级稳定性: + +### **1\. 开启“镜像加速”(针对大镜像冷启动)** + +* **适用模块**:Python 微服务 (1.1GB)、R 统计引擎 (1.81GB)。 +* **配置与价值**:在 SAE 应用配置中勾选【镜像加速】。SAE 底层会通过按需加载数据块的技术(如 DADI),将几分钟的冷启动时间压缩到秒级。这是应对偶发流量突增的核心兜底技术。 + +### **2\. 优雅上下线与无损发布 (Graceful Shutdown)** + +* **适用模块**:Node.js 后端(特别是 pg-boss 队列)。 +* **配置与价值**: + * 目前你们的 ASL 和 DC 模块深度依赖 pg-boss 处理异步任务。 + * 如果 SAE 突然缩容杀掉 Node 实例,运行中的文献抓取任务会中断。 + * **操作**:在 SAE 中配置优雅下线时间(如 30 秒)。在 Node.js 代码中监听 SIGTERM 信号,收到信号后,停止接收新 HTTP 请求,但**等待 pg-boss 正在处理的 job 执行完毕**后再退出容器。 + +### **3\. Liveness 与 Readiness 探针 (健康检查)** + +* **适用模块**:全模块。 +* **配置与价值**: + * **Liveness (存活探针)**:配置在 GET /health。如果 R 引擎死锁,探针连续 3 次失败,SAE 会自动重启该容器(自愈能力)。 + * **Readiness (就绪探针)**:在应用刚启动、正在建立 PostgreSQL 数据库连接池或加载 R 语言模型时,Readiness 返回 false,SAE 不会把用户流量打过来,避免报错。 + +### **4\. 长链接防断开配置 (针对 SSE 架构)** + +* **适用模块**:Node.js 后端、R 统计引擎、前端 Nginx。 +* **配置与价值**:系统中有大量的打字机效果(AI 流式对话)和进度条流式推送(SSE)。必须在 SAE 的网关层(如 ALB/CLB)调整 **闲置超时时间 (Idle Timeout)**,建议设置为 120秒 或更长,防止长时间推理时网络连接被强制切断。 + +### **5\. 一体化可观测性 (SLS 日志与 APM 链路监控)** + +* **适用模块**:全模块。 +* **配置与价值**: + * **日志采集**:将各容器的 stdout 日志一键收集到阿里云 SLS,所有报错无需 SSH 登录服务器,直接在网页端关键词检索(如 \[ERROR\] R引擎)。 + * **链路追踪**:SAE 支持无侵入式 APM。你能清晰看到一条请求:从 前端 \-\> Node.js (消耗 50ms) \-\> R 引擎 (消耗 2000ms) 的全链路耗时,精准定位系统性能瓶颈。 + +## **四、 总结:运维与管理策略时间线** + +1. **日常平峰期**:所有微服务维持 最小实例 1,最大实例 3/5。通过“并发数”和“CPU”的双重自动弹性指标应对日常零星的并发波动。 +2. **大版本更新日**:利用 SAE 的“分批发布”或“灰度发布”功能。先替换 1 个实例为 v2.0,测试无误后再全量更新,实现业务零停机。 +3. **大中型活动(培训班)**:提前在日历上标记,通过 SAE 【定时弹性策略】提前 30 分钟扩容预热大容器,活动后自动缩容。 +4. **故障排查时**:不再去看单机日志,直接利用 SAE 挂载的 ARMS(应用实时监控服务)查看错误率飙升的模块,或者进入 SLS 搜索 TraceID。 + +这套体系将彻底把你们的研发团队从繁琐的运维、服务器抗压焦虑中解放出来,让 "Serverless (无服务器)" 的红利在你们的临床 AI 系统中最大化展现。 \ No newline at end of file diff --git a/frontend-v2/src/modules/aia/styles/chat-workspace.css b/frontend-v2/src/modules/aia/styles/chat-workspace.css index dab08fd5..339d1760 100644 --- a/frontend-v2/src/modules/aia/styles/chat-workspace.css +++ b/frontend-v2/src/modules/aia/styles/chat-workspace.css @@ -953,13 +953,9 @@ white-space: normal; }.message-bubble .markdown-content p { margin: 0 0 8px 0; -} - -.message-bubble .markdown-content p:last-child { +}.message-bubble .markdown-content p:last-child { margin-bottom: 0; -} - -.message-bubble .markdown-content .md-divider { +}.message-bubble .markdown-content .md-divider { border: none; border-top: 1px solid #E5E7EB; margin: 12px 0;