# RVW稿件审查模块迁移计划(v2.1 - 稳定迁移版) > **文档版本:** v2.1 > **创建日期:** 2026-01-07 > **最后更新:** 2026-01-07 > **维护者:** 开发团队 > **文档目的:** 将稿件审查功能从旧架构安全迁移到新架构,同时整合MVP核心需求 --- ## 📋 项目概述 ### 1. 背景 稿件审查功能是2025-10-30(Day 30)独立开发的功能模块,目前位于 `backend/src/legacy/` 和 `frontend/` 目录中。现需要: 1. **架构迁移**:迁移到标准的模块目录结构(`modules/rvw`) 2. **功能升级**:整合《智能期刊审稿系统MVP产品需求文档》的核心功能 ### 2. 迁移原则 | 原则 | 说明 | |------|------| | **稳定优先** | 每个Phase完成后必须通过测试验证 | | **安全可靠** | 数据库迁移前必须备份,支持回滚 | | **阶段验证** | 每个Phase有明确的验收标准 | | **向后兼容** | 保留旧API过渡期,不影响现有功能 | | **渐进式** | 先核心后扩展,先后端后前端 | ### 3. 功能范围 | 功能 | 本次开发 | 数据库支撑 | 说明 | |------|:--------:|:----------:|------| | **核心AI评估** | ✅ | ✅ | 稿约规范性+方法学 | | **批量上传** | ✅ | ✅ | 多文件上传 | | **审稿工作台** | ✅ | ✅ | 宽表布局+筛选 | | **智能体选择** | ✅ | ✅ | 可选1个或2个 | | **批量操作** | ✅ | ✅ | 批量运行审查 | | **状态筛选** | ✅ | ✅ | 全部/待处理/已完成 | | PDF报告导出 | ✅ | ✅ | 优化现有功能 | | PICO卡片 | ⏸️ | ✅ | **暂不开发,数据库预留** | | 系统设置 | ⏸️ | ✅ | **暂不开发,数据库预留** | | 历史归档 | ⏸️ | ✅ | **暂不开发,数据库预留** | | 登录页面 | ⏸️ | - | 暂不开发 | ### 4. 智能体选择说明 用户可以灵活选择运行的智能体: ``` 选项 A: 只选择「稿约规范性智能体」 → 只运行规范性评估 选项 B: 只选择「方法学统计智能体」 → 只运行方法学评估 选项 C: 同时选择两个智能体 → 同时运行两项评估(默认) ``` --- ## 📊 数据库设计(完整版,支撑未来扩展) ### 1. 期刊配置表(预留,暂不使用) ```prisma // review_schema model JournalConfig { id String @id @default(uuid()) name String // 期刊名称 logoUrl String? @map("logo_url") // Logo URL(预留) defaultModel String @default("deepseek-v3") @map("default_model") settings Json? // 其他配置(预留) createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") reviewTasks ReviewTask[] @@map("journal_configs") @@schema("review_schema") } ``` ### 2. 审稿任务表(扩展版) ```prisma model ReviewTask { id String @id @default(uuid()) userId String @map("user_id") journalId String? @map("journal_id") // 预留:期刊关联 // 文件信息 fileName String @map("file_name") fileSize Int @map("file_size") filePath String? @map("file_path") extractedText String @map("extracted_text") wordCount Int? @map("word_count") authorName String? @map("author_name") // 预留:作者提取 // 状态管理 status String @default("pending") // ✅ 智能体选择:可选1个或2个 selectedAgents String[] @default(["editorial", "methodology"]) @map("selected_agents") // 评估结果 editorialReview Json? @map("editorial_review") methodologyReview Json? @map("methodology_review") overallScore Float? @map("overall_score") // 结果摘要(用于列表展示) editorialScore Float? @map("editorial_score") methodologyStatus String? @map("methodology_status") // pass/warn/fail // 预留:PICO提取(暂不使用) picoExtract Json? @map("pico_extract") // 元数据 modelUsed String? @map("model_used") startedAt DateTime? @map("started_at") completedAt DateTime? @map("completed_at") durationSeconds Int? @map("duration_seconds") errorMessage String? @map("error_message") // 预留:归档功能(暂不使用) isArchived Boolean @default(false) @map("is_archived") archivedAt DateTime? @map("archived_at") createdAt DateTime @default(now()) @map("created_at") updatedAt DateTime @updatedAt @map("updated_at") // 关联 user users @relation(fields: [userId], references: [id], onDelete: Cascade) journal JournalConfig? @relation(fields: [journalId], references: [id]) @@index([userId]) @@index([journalId]) @@index([status]) @@index([createdAt]) @@index([isArchived]) @@map("review_tasks") @@schema("review_schema") } ``` ### 3. 字段说明 | 字段 | 本次使用 | 预留用途 | |------|:--------:|---------| | `journalId` | ❌ | 系统设置:期刊关联 | | `authorName` | ❌ | 自动提取作者名 | | `selectedAgents` | ✅ | 用户选择的智能体 | | `editorialScore` | ✅ | 列表显示规范性分数 | | `methodologyStatus` | ✅ | 列表显示方法学状态 | | `picoExtract` | ❌ | PICO卡片数据 | | `isArchived` | ❌ | 历史归档功能 | | `archivedAt` | ❌ | 归档时间 | --- ## 📋 安全迁移策略 ### 1. 迁移前准备 ```bash # 1. 备份数据库 pg_dump -h localhost -U postgres -d airesearch -F c -f backup_before_rvw_migration.dump # 2. 记录当前数据量 SELECT COUNT(*) FROM public.review_tasks; # 3. 导出关键数据(可选) COPY public.review_tasks TO '/tmp/review_tasks_backup.csv' WITH CSV HEADER; ``` ### 2. 回滚方案 ```bash # 如果迁移失败,回滚数据库 pg_restore -h localhost -U postgres -d airesearch -c backup_before_rvw_migration.dump # 如果只需要回滚Schema迁移 ALTER TABLE review_schema.review_tasks SET SCHEMA public; DROP SCHEMA review_schema; ``` ### 3. 阶段性验证 每个Phase完成后必须通过以下验证: | Phase | 验证内容 | 验收标准 | |-------|---------|---------| | Phase 1 | 后端API测试 | 所有API返回正确,日志无ERROR | | Phase 2 | 数据库迁移 | 数据完整,查询正常,索引有效 | | Phase 3 | 前端功能测试 | 核心流程通顺,无白屏/报错 | | Phase 4 | 集成测试 | 端到端流程正常 | | Phase 5 | 验收测试 | 符合MVP验收标准 | --- ## 📋 开发任务清单 ### Phase 1:后端模块迁移(2天) #### Day 1 上午:创建模块结构 + 复用核心代码 **1.1 创建目录结构** ``` backend/src/modules/rvw/ ├── routes/ │ └── index.ts # 路由定义 ├── controllers/ │ └── reviewController.ts # 控制器 ├── services/ │ ├── reviewService.ts # 主服务(复用+扩展) │ ├── editorialService.ts # 稿约评估(复用) │ └── methodologyService.ts # 方法学评估(复用) ├── types/ │ └── index.ts # 类型定义 ├── prompts/ │ ├── editorial_system.txt # 稿约Prompt │ └── methodology_system.txt # 方法学Prompt └── index.ts # 模块入口 ``` - [ ] **1.1.1** 创建目录结构 - [ ] **1.1.2** 复制 `reviewEditorialStandards()` → `editorialService.ts` - [ ] **1.1.3** 复制 `reviewMethodology()` → `methodologyService.ts` - [ ] **1.1.4** 复制 `parseJSONFromLLMResponse()` → `utils.ts` - [ ] **1.1.5** 复制 Prompt 文件到模块内 **1.2 云原生改造** - [ ] **1.2.1** 替换 `console.log` → `logger` - [ ] **1.2.2** 移除 Mock用户ID,集成JWT认证 - [ ] **1.2.3** 使用 `process.env` 配置 #### Day 1 下午:智能体选择逻辑 **1.3 智能体选择实现** ```typescript // types/index.ts export type AgentType = 'editorial' | 'methodology'; export interface RunReviewParams { taskId: string; agents: AgentType[]; // 可选1个或2个 } // services/reviewService.ts async function runReview(params: RunReviewParams) { const { taskId, agents } = params; // 验证:至少选择1个智能体 if (agents.length === 0) { throw new Error('请至少选择一个智能体'); } // 更新任务状态 await prisma.reviewTask.update({ where: { id: taskId }, data: { status: 'reviewing', selectedAgents: agents, startedAt: new Date() } }); // 只运行选中的智能体 let editorialResult = null; let methodologyResult = null; if (agents.includes('editorial')) { editorialResult = await editorialService.review(taskId); } if (agents.includes('methodology')) { methodologyResult = await methodologyService.review(taskId); } // 计算综合分数 const overallScore = calculateOverallScore(editorialResult, methodologyResult, agents); // 更新结果 await prisma.reviewTask.update({ where: { id: taskId }, data: { status: 'completed', editorialReview: editorialResult, methodologyReview: methodologyResult, editorialScore: editorialResult?.overall_score, methodologyStatus: getMethodologyStatus(methodologyResult), overallScore, completedAt: new Date(), durationSeconds: calculateDuration(taskId) } }); } // 根据选择的智能体计算综合分数 function calculateOverallScore(editorial: any, methodology: any, agents: AgentType[]) { if (agents.length === 2 && editorial && methodology) { // 两个都选:40% + 60% return editorial.overall_score * 0.4 + methodology.overall_score * 0.6; } else if (agents.includes('editorial') && editorial) { // 只选规范性 return editorial.overall_score; } else if (agents.includes('methodology') && methodology) { // 只选方法学 return methodology.overall_score; } return null; } ``` - [ ] **1.3.1** 实现智能体选择类型定义 - [ ] **1.3.2** 实现 `runReview()` 函数 - [ ] **1.3.3** 实现综合分数计算逻辑 - [ ] **1.3.4** 实现方法学状态判断(pass/warn/fail) #### Day 2 上午:批量操作 + API扩展 **1.4 批量运行实现** ```typescript // services/reviewService.ts async function batchRunReview(params: BatchRunParams) { const { taskIds, agents } = params; // 限制并发数 const MAX_CONCURRENT = 5; const results = []; for (let i = 0; i < taskIds.length; i += MAX_CONCURRENT) { const batch = taskIds.slice(i, i + MAX_CONCURRENT); const batchResults = await Promise.allSettled( batch.map(taskId => runReview({ taskId, agents })) ); results.push(...batchResults); } return results; } ``` - [ ] **1.4.1** 实现批量运行接口 - [ ] **1.4.2** 实现并发控制(最多5个) - [ ] **1.4.3** 实现错误处理(单个失败不影响其他) **1.5 API路由定义** ```typescript // routes/index.ts export default async function rvwRoutes(fastify: FastifyInstance) { // 任务管理 fastify.post('/tasks', reviewController.createTask); // 创建/上传 fastify.get('/tasks', reviewController.getTaskList); // 列表(筛选) fastify.get('/tasks/:taskId', reviewController.getTaskDetail); // 详情 fastify.get('/tasks/:taskId/report', reviewController.getTaskReport); // 报告 fastify.delete('/tasks/:taskId', reviewController.deleteTask); // 删除 // 运行审查(核心功能) fastify.post('/tasks/:taskId/run', reviewController.runReview); // 单个运行 fastify.post('/tasks/batch/run', reviewController.batchRunReview); // 批量运行 } ``` - [ ] **1.5.1** 实现路由定义 - [ ] **1.5.2** 实现控制器方法 - [ ] **1.5.3** 添加请求验证 #### Day 2 下午:注册路由 + Phase 1 验证 **1.6 注册新路由** ```typescript // backend/src/index.ts import rvwRoutes from './modules/rvw/routes/index.js'; // 注册新路由(v2) await fastify.register(rvwRoutes, { prefix: '/api/v2/rvw' }); logger.info('✅ RVW稿件审查路由已注册: /api/v2/rvw'); // 保留旧路由(兼容) await fastify.register(reviewRoutes, { prefix: '/api/v1' }); logger.info('✅ Legacy审稿路由保留: /api/v1/review'); ``` - [ ] **1.6.1** 注册新路由 - [ ] **1.6.2** 保留旧路由兼容 **1.7 Phase 1 验证测试** ```http ### 1. 创建任务 POST {{baseUrl}}/api/v2/rvw/tasks Content-Type: multipart/form-data # file: test.docx ### 2. 运行审查(只选规范性) POST {{baseUrl}}/api/v2/rvw/tasks/{{taskId}}/run Content-Type: application/json { "agents": ["editorial"] } ### 3. 运行审查(只选方法学) POST {{baseUrl}}/api/v2/rvw/tasks/{{taskId}}/run Content-Type: application/json { "agents": ["methodology"] } ### 4. 运行审查(两个都选) POST {{baseUrl}}/api/v2/rvw/tasks/{{taskId}}/run Content-Type: application/json { "agents": ["editorial", "methodology"] } ### 5. 批量运行 POST {{baseUrl}}/api/v2/rvw/tasks/batch/run Content-Type: application/json { "taskIds": ["id1", "id2", "id3"], "agents": ["editorial", "methodology"] } ### 6. 获取任务列表 GET {{baseUrl}}/api/v2/rvw/tasks?status=pending&limit=10 ### 7. 获取报告 GET {{baseUrl}}/api/v2/rvw/tasks/{{taskId}}/report ``` **Phase 1 验收标准:** | 测试项 | 预期结果 | 通过 | |--------|---------|:----:| | 创建任务 | 返回taskId,状态pending | ⬜ | | 只选规范性 | 只有editorialReview有值 | ⬜ | | 只选方法学 | 只有methodologyReview有值 | ⬜ | | 两个都选 | 两个Review都有值 | ⬜ | | 批量运行 | 多个任务都完成 | ⬜ | | 旧API兼容 | `/api/v1/review/*` 正常 | ⬜ | - [ ] **1.7.1** 编写测试用例 - [ ] **1.7.2** 执行测试 - [ ] **1.7.3** 修复问题 - [ ] **1.7.4** 确认Phase 1通过 --- ### Phase 2:数据库Schema迁移(0.5天) #### 迁移前:备份 - [ ] **2.1** 备份数据库 ```bash pg_dump -h localhost -U postgres -d airesearch -F c -f backup_phase2.dump ``` - [ ] **2.2** 记录当前数据 ```sql SELECT COUNT(*) FROM public.review_tasks; ``` #### 迁移执行 - [ ] **2.3** 创建迁移SQL ```sql -- 1. 创建新Schema CREATE SCHEMA IF NOT EXISTS review_schema; -- 2. 创建期刊配置表(预留) CREATE TABLE review_schema.journal_configs ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, logo_url TEXT, default_model VARCHAR(50) DEFAULT 'deepseek-v3', settings JSONB, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- 3. 迁移review_tasks表到新Schema ALTER TABLE public.review_tasks SET SCHEMA review_schema; -- 4. 添加新字段(支持未来扩展) ALTER TABLE review_schema.review_tasks ADD COLUMN IF NOT EXISTS journal_id UUID REFERENCES review_schema.journal_configs(id), ADD COLUMN IF NOT EXISTS author_name VARCHAR(255), ADD COLUMN IF NOT EXISTS selected_agents TEXT[] DEFAULT ARRAY['editorial', 'methodology'], ADD COLUMN IF NOT EXISTS editorial_score FLOAT, ADD COLUMN IF NOT EXISTS methodology_status VARCHAR(20), ADD COLUMN IF NOT EXISTS pico_extract JSONB, ADD COLUMN IF NOT EXISTS is_archived BOOLEAN DEFAULT FALSE, ADD COLUMN IF NOT EXISTS archived_at TIMESTAMPTZ; -- 5. 创建索引 CREATE INDEX IF NOT EXISTS idx_review_tasks_journal ON review_schema.review_tasks(journal_id); CREATE INDEX IF NOT EXISTS idx_review_tasks_archived ON review_schema.review_tasks(is_archived); -- 6. 创建默认期刊配置 INSERT INTO review_schema.journal_configs (name, default_model) VALUES ('默认期刊', 'deepseek-v3'); ``` - [ ] **2.4** 更新Prisma Schema - 修改 `@@schema("review_schema")` - 添加新字段 - [ ] **2.5** 执行迁移 ```bash npx prisma migrate dev --name rvw_schema_migration ``` #### Phase 2 验证 - [ ] **2.6** 验证数据完整性 ```sql -- 确认数据量一致 SELECT COUNT(*) FROM review_schema.review_tasks; -- 确认字段可用 SELECT id, selected_agents, editorial_score FROM review_schema.review_tasks LIMIT 5; -- 确认外键关系 SELECT rt.id, rt.user_id, u.email FROM review_schema.review_tasks rt JOIN public.users u ON rt.user_id = u.id LIMIT 5; ``` **Phase 2 验收标准:** | 测试项 | 预期结果 | 通过 | |--------|---------|:----:| | 数据迁移 | 数据量一致 | ⬜ | | 新字段 | 字段存在且可用 | ⬜ | | 外键关系 | 关联正常 | ⬜ | | 索引有效 | 查询性能正常 | ⬜ | | API正常 | 后端API仍可用 | ⬜ | - [ ] **2.7** 确认Phase 2通过 --- ### Phase 3:前端重构(3天) #### Day 3:模块结构 + API层 **3.1 创建模块结构** ``` frontend-v2/src/modules/rvw/ ├── api/ │ └── reviewApi.ts # API封装 ├── components/ │ ├── ScoreCard.tsx # 复用 │ ├── EditorialReview.tsx # 复用 │ ├── MethodologyReview.tsx # 复用 │ ├── AgentSelector.tsx # 🆕 智能体选择弹窗 │ ├── BatchToolbar.tsx # 🆕 批量操作栏 │ ├── TaskTable.tsx # 🆕 任务列表表格 │ └── StatusFilter.tsx # 🆕 状态筛选 ├── pages/ │ ├── ReviewDashboard.tsx # 🆕 审稿工作台 │ └── ReviewDetail.tsx # 报告详情(优化) ├── hooks/ │ ├── useReviewTask.ts │ └── useBatchOperation.ts ├── stores/ │ └── useReviewStore.ts ├── types/ │ └── index.ts └── index.tsx ``` - [ ] **3.1.1** 创建目录结构 - [ ] **3.1.2** 复用现有组件(ScoreCard、EditorialReview、MethodologyReview) **3.2 API封装** ```typescript // api/reviewApi.ts export type AgentType = 'editorial' | 'methodology'; // 运行审查(支持选择智能体) export async function runReview(taskId: string, agents: AgentType[]): Promise { return axios.post(`/api/v2/rvw/tasks/${taskId}/run`, { agents }); } // 批量运行 export async function batchRunReview(taskIds: string[], agents: AgentType[]): Promise { return axios.post('/api/v2/rvw/tasks/batch/run', { taskIds, agents }); } // 获取任务列表(带筛选) export interface TaskListParams { status?: 'all' | 'pending' | 'completed'; limit?: number; offset?: number; } export async function getTaskList(params: TaskListParams): Promise { return axios.get('/api/v2/rvw/tasks', { params }); } ``` - [ ] **3.2.1** 实现API封装 - [ ] **3.2.2** 实现类型定义 #### Day 4:核心页面开发 **3.3 智能体选择弹窗** ```tsx // components/AgentSelector.tsx interface AgentSelectorProps { visible: boolean; taskIds: string[]; // 支持单个或多个 onConfirm: (agents: AgentType[]) => void; onCancel: () => void; } // 弹窗内容: // ✅ 稿约规范性智能体(默认选中) // 格式、参考文献、图片检查 // ☐ 方法学统计智能体 // DeepSeek 深度逻辑推理 // // 提示:可选择1个或同时选择2个智能体 // // [取消] [立即运行] ``` - [ ] **3.3.1** 实现智能体选择弹窗 - [ ] **3.3.2** 支持单选和多选 - [ ] **3.3.3** 默认选中规范性智能体 **3.4 审稿工作台** ``` ┌─────────────────────────────────────────────────────────────────┐ │ Header: [Logo] 智能审稿系统 [上传新稿件] │ ├─────────────────────────────────────────────────────────────────┤ │ Filter: [全部|待处理|已完成] │ ├─────────────────────────────────────────────────────────────────┤ │ ┌───────────────────────────────────────────────────────────┐ │ │ │ ☐ 文件名称/信息 上传时间 审稿维度 结果摘要 操作 │ │ │ │ ☐ 替雷利珠单抗...pdf 10:30 [规范][方法] 92分 [查看] │ │ │ ☐ 高血压药物...docx 刚刚 [未运行] 等待... [开始] │ │ └───────────────────────────────────────────────────────────┘ │ ├─────────────────────────────────────────────────────────────────┤ │ [Batch Toolbar: 3个文件已选中 | 运行智能审稿 | ✕] │ └─────────────────────────────────────────────────────────────────┘ ``` - [ ] **3.4.1** 实现页面布局 - [ ] **3.4.2** 实现任务列表表格 - [ ] **3.4.3** 实现状态筛选 - [ ] **3.4.4** 实现批量操作栏 #### Day 5:报告详情 + Phase 3 验证 **3.5 报告详情页** - [ ] **3.5.1** 实现Tab切换(规范性/方法学) - [ ] **3.5.2** 复用评估详情组件 - [ ] **3.5.3** 根据选择的智能体显示对应Tab - [ ] **3.5.4** 实现导出报告按钮 **3.6 路由配置** ```typescript // router/index.tsx { path: '/rvw', children: [ { path: '', element: }, { path: ':taskId', element: } ] } ``` - [ ] **3.6.1** 配置路由 - [ ] **3.6.2** 添加导航菜单 **Phase 3 验证测试** | 测试项 | 预期结果 | 通过 | |--------|---------|:----:| | 页面加载 | 工作台正常显示 | ⬜ | | 文件上传 | 支持多文件 | ⬜ | | 智能体选择 | 可选1个或2个 | ⬜ | | 批量操作 | 批量运行成功 | ⬜ | | 状态筛选 | 筛选结果正确 | ⬜ | | 报告查看 | 显示对应评估结果 | ⬜ | - [ ] **3.7** 确认Phase 3通过 --- ### Phase 4:集成测试(1天) **4.1 端到端测试** | 测试场景 | 步骤 | 预期结果 | |---------|------|---------| | 单文件+单智能体 | 上传→选规范性→查看 | 只显示规范性报告 | | 单文件+双智能体 | 上传→选两个→查看 | 显示两个报告Tab | | 批量+双智能体 | 上传3个→批量运行 | 3个都完成 | | 状态筛选 | 上传→筛选待处理 | 正确过滤 | - [ ] **4.1.1** 执行端到端测试 - [ ] **4.1.2** 修复发现的问题 **4.2 性能测试** | 指标 | 目标 | 实际 | |------|------|------| | 列表加载 | < 1秒 | ⬜ | | 单文件审查 | < 2分钟 | ⬜ | | 5文件并发 | < 5分钟 | ⬜ | - [ ] **4.2.1** 执行性能测试 **4.3 兼容性测试** - [ ] **4.3.1** Chrome浏览器测试 - [ ] **4.3.2** Edge浏览器测试 - [ ] **4.3.3** 旧API兼容性确认 --- ### Phase 5:验收与上线(0.5天) **5.1 MVP验收标准** | 验收项 | 预期结果 | 通过 | |--------|---------|:----:| | 流程通 | 5个PDF,3分钟内全部完成 | ⬜ | | 规范性准确 | 删掉摘要结论必须报错 | ⬜ | | 方法学准确 | 混淆统计方法必须报存疑 | ⬜ | | 无崩溃 | 连续上传20个不卡死 | ⬜ | - [ ] **5.1.1** 执行验收测试 - [ ] **5.1.2** 编写验收报告 **5.2 上线准备** - [ ] **5.2.1** 更新文档 - [ ] **5.2.2** 通知相关人员 - [ ] **5.2.3** 监控上线后状态 --- ## 📅 时间估算 | Phase | 任务 | 预估工时 | 验证点 | |-------|------|---------|--------| | **Phase 1** | 后端模块迁移 | 2天 | ✓ API测试通过 | | **Phase 2** | 数据库迁移 | 0.5天 | ✓ 数据完整性验证 | | **Phase 3** | 前端重构 | 3天 | ✓ 功能测试通过 | | **Phase 4** | 集成测试 | 1天 | ✓ 端到端测试通过 | | **Phase 5** | 验收上线 | 0.5天 | ✓ MVP验收通过 | | **总计** | - | **7天** | - | --- ## ⏸️ 暂不开发的功能(数据库已预留) | 功能 | 预留字段 | 后续计划 | |------|---------|---------| | **PICO卡片** | `pico_extract` | 方法学评估扩展 | | **系统设置** | `JournalConfig`表 | 期刊Logo/模型配置 | | **历史归档** | `is_archived`, `archived_at` | 自动归档7天前数据 | | **登录页面** | - | 独立产品时开发 | --- ## ⚠️ 风险控制 ### 1. 数据库迁移风险 | 风险 | 概率 | 影响 | 控制措施 | |------|------|------|---------| | 数据丢失 | 低 | 高 | 迁移前备份 | | 迁移失败 | 中 | 中 | 准备回滚SQL | | 性能下降 | 低 | 中 | 验证索引有效性 | ### 2. 功能回归风险 | 风险 | 概率 | 影响 | 控制措施 | |------|------|------|---------| | 旧API中断 | 低 | 高 | 保留v1路由 | | 评估结果异常 | 低 | 高 | 对比测试结果 | | 前端白屏 | 中 | 中 | 阶段性测试 | ### 3. 回滚计划 ```bash # 如果需要回滚到迁移前状态 # 1. 停止服务 pm2 stop all # 2. 回滚数据库 pg_restore -h localhost -U postgres -d airesearch -c backup_phase2.dump # 3. 切换到旧代码分支 git checkout main # 4. 重启服务 pm2 start all ``` --- ## 📚 参考文档 - [智能期刊审稿系统MVP PRD](../01-需求分析/智能期刊审稿系统%20MVP%20产品需求文档.md) - [智能审稿V7原型](../01-需求分析/智能审稿V7.html) - [云原生开发规范](../../04-开发规范/08-云原生开发规范.md) - [现有系统技术摸底报告](../../00-项目概述/现有系统技术摸底报告.md) --- **文档版本:** v2.1 **最后更新:** 2026-01-07 **下一步:** 确认后开始Phase 1