核心功能: - 新增AICodeService(550行):AI代码生成核心服务 - 新增AIController(257行):4个API端点 - 新增dc_tool_c_ai_history表:存储对话历史 - 实现自我修正机制:最多3次智能重试 - 集成LLMFactory:复用通用能力层 - 10个Few-shot示例:覆盖Level 1-4场景 技术优化: - 修复NaN序列化问题(Python端转None) - 修复数据传递问题(从Session获取真实数据) - 优化System Prompt(明确环境信息) - 调整Few-shot示例(移除import语句) 测试结果: - 通过率:9/11(81.8%) 达到MVP标准 - 成功场景:缺失值处理、编码、分箱、BMI、筛选、填补、统计、分类 - 待优化:数值清洗、智能去重(已记录技术债务TD-C-006) API端点: - POST /api/v1/dc/tool-c/ai/generate(生成代码) - POST /api/v1/dc/tool-c/ai/execute(执行代码) - POST /api/v1/dc/tool-c/ai/process(生成并执行,一步到位) - GET /api/v1/dc/tool-c/ai/history/:sessionId(对话历史) 文档更新: - 新增Day 3开发完成总结(770行) - 新增复杂场景优化技术债务(TD-C-006) - 更新工具C当前状态文档 - 更新技术债务清单 影响范围: - backend/src/modules/dc/tool-c/*(新增2个文件,更新1个文件) - backend/scripts/create-tool-c-ai-history-table.mjs(新增) - backend/prisma/schema.prisma(新增DcToolCAiHistory模型) - extraction_service/services/dc_executor.py(NaN序列化修复) - docs/03-业务模块/DC-数据清洗整理/*(5份文档更新) Breaking Changes: 无 总代码行数:+950行 Refs: #Tool-C-Day3
24 KiB
DC数据清洗整理模块 - 当前状态与开发指南
文档版本: v2.1
创建日期: 2025-11-28
维护者: DC模块开发团队
最后更新: 2025-12-06 (Tool C Day 1完成)
文档目的: 反映模块真实状态,记录代码丢失与重建经历
⚠️ 重要事件记录
代码丢失事件(2025-11-28)
事件描述:
- 在2025-11-27开发的DC模块Tool B代码完全丢失
- 原因:Cursor临时缓存丢失,代码未及时提交到Git
- 影响范围:
- ❌ 所有Service层代码(4个服务)
- ❌ Controller层代码
- ❌ Routes配置
- ❌ 数据库迁移SQL文件(
20251127_add_dc_tool_b_tables/migration.sql为空) - ✅ 设计文档保留(PRD、技术设计、API设计、数据库设计、UI原型)
- ✅ 开发记录保留(Day2、Day3完成总结)
- ✅ Prisma Schema定义保留(4个表模型)
重建工作:
- ✅ 2025-11-28:完整重建后端代码(100%功能恢复)
- ✅ Git提交:防止再次丢失
- ⚠️ 数据库表状态:未确认(无法连接验证,但可随时通过
npx prisma db push创建)
教训与改进:
- ✅ 更新了Git提交规范:强制每日提交
- ✅ 清理了所有数据库检查脚本(终端输出问题无法解决)
- ⚠️ 关键问题:Cursor的PowerShell终端无法正常显示输出,导致多次尝试失败
📋 文档说明
本文档是DC数据清洗整理模块的真实状态快照,如实记录代码丢失、重建过程和当前真实状况。
与其他文档的关系:
- 本文档(00-模块当前状态):What is(真实状态,包括问题)
- 开发计划文档:What to do(原计划)
- 开发记录文档:What done(包括丢失前的Day2-3记录)
- 技术设计文档:How to do(设计方案)
🎯 模块概述
核心功能
DC数据清洗整理模块提供4个智能工具,帮助研究人员清洗、整理、提取医疗数据。
当前状态
- 开发阶段:🎉 Tool B MVP完成 + 🚀 Tool C Day 1完成
- 已完成功能:
- ✅ Portal:智能数据清洗工作台(2025-12-02)
- ✅ Tool B 后端:病历结构化机器人(2025-11-28重建完成)
- ✅ Tool B 前端:5步工作流完整实现(2025-12-03)
- ✅ Tool B API对接:6个端点全部集成(2025-12-03)
- ✅ Tool C Python微服务:代码执行引擎(2025-12-06,Day 1)
- ✅ Tool C Node.js后端:Python服务集成(2025-12-06,Day 1)
- 开发中功能:
- 🟡 Tool C:科研数据编辑器(15%完成,MVP Day 1/15)
- ✅ Python微服务扩展(AST检查 + Pandas执行)
- ✅ Node.js后端集成(PythonExecutorService)
- ⏸️ Session管理(Day 2)
- ⏸️ AI代码生成(Day 3-5)
- ⏸️ 前端开发(Day 6-10)
- 🟡 Tool C:科研数据编辑器(15%完成,MVP Day 1/15)
- 未开发功能:
- ❌ Tool A:医疗数据超级合并器
- 模型支持:DeepSeek-V3 + Qwen-Max 双模型交叉验证(已验证可用)
- 部署状态:✅ 前后端完整可用,数据库表已确认存在并正常工作
- 已知问题:4个技术债务(见
07-技术债务/Tool-B技术债务清单.md)
关键里程碑
Tool B - 病历结构化机器人:
- ✅ 2025-11-22:Day 2完成(首次开发)
- 数据库Schema设计(4个表)
- 4个服务骨架创建
- LLMFactory测试通过
- ✅ 2025-11-23:Day 3完成(首次开发)
- HealthCheckService完整实现
- TemplateService完整实现(3个预设模板)
- API测试通过
- ❌ 2025-11-27:代码完全丢失
- ✅ 2025-11-28:代码重建完成
- 4个Service重建(HealthCheck、Template、DualModel、Conflict)
- 1个Controller重建(6个API端点)
- Routes集成到主应用
- Git提交保护
- ✅ 2025-12-02:Portal页面完成
- 工作台界面开发完成
- UI优化,匹配原型设计
- 与系统顶部导航集成
- ✅ 2025-12-03:Tool B MVP版本完成 🎉
- 前端5步工作流(~1400行代码)
- API完整对接(Phase 1-5)
- 真实LLM调用验证通过
- 双模型提取成功测试
- Excel导出功能可用
Tool C - 科研数据编辑器:
- ✅ 2025-12-06:Day 1完成 🚀
- Python微服务扩展(dc_executor.py,427行)
- AST静态代码检查(危险模块拦截)
- Pandas沙箱执行(30秒超时保护)
- FastAPI新增2个端点(/api/dc/validate, /api/dc/execute)
- Node.js后端集成(PythonExecutorService,177行)
- 测试控制器和路由(3个测试端点)
- 功能验证100%通过
🏗️ 技术架构
技术栈
前端
框架: React 19 + TypeScript 5
路由: React Router DOM v6
状态管理: @tanstack/react-query (React Query v5)
UI组件: Ant Design v5
样式: TailwindCSS v3
构建工具: Vite v5
⚠️ 状态:仅有Placeholder,无真实代码
后端
框架: Fastify v4 (Node.js 22)
数据库: PostgreSQL 16 + Prisma 6
LLM SDK: 自研 LLMFactory (统一适配层)
模型: DeepSeek-V3, Qwen-Max
日志: Winston
Excel处理: xlsx 库(内存模式)
并发控制: p-limit(限制LLM并发数)
✅ 状态:代码已重建,100%功能恢复
基础设施(云原生)
数据库: PostgreSQL 16 with Schema isolation
Schema: dc_schema (独立隔离)
存储: storage服务(OSS ↔ LocalFS)
缓存: cache服务(Redis ↔ Memory)
日志: logger服务(Winston结构化)
任务队列: jobQueue服务(异步处理)
✅ 状态:100%复用平台基础设施
📂 真实代码结构
前端代码结构
frontend-v2/src/modules/dc/
├── index.tsx # ❌ 仅Placeholder,无真实功能
├── components/ # 📁 空文件夹
├── pages/ # 📁 空文件夹结构
│ ├── tool-a/ # 📁 空
│ ├── tool-b/ # 📁 空(应实现V4原型)
│ └── tool-c/ # 📁 空
└── types/ # 📁 空文件夹
⚠️ 真实状态:前端完全未开发,只有占位符
前端待实现功能(基于V4原型设计):
- Step 1:文件上传与列选择
- Step 2:Schema映射(疾病类型、报告类型、目标字段)
- Step 3:处理进度监控(实时进度、并发任务显示)
- Step 4:冲突验证工作台(双模型对比、上下文显示)
- Step 5:结果导出(Excel下载)
后端代码结构
backend/src/modules/dc/
├── index.ts # ✅ 模块入口(117行)
│ ├── registerDCRoutes() # 路由注册函数
│ └── initDCModule() # 初始化函数(含数据库检查)
├── tool-b/ # ✅ 工具B:病历结构化机器人
│ ├── services/ # ✅ 服务层(4个核心服务)
│ │ ├── HealthCheckService.ts # ✅ 190行 - Excel健康检查
│ │ ├── TemplateService.ts # ✅ 243行 - 预设模板管理
│ │ ├── DualModelExtractionService.ts # ✅ 390行 - 双模型提取
│ │ └── ConflictDetectionService.ts # ✅ 215行 - 冲突检测算法
│ ├── controllers/ # ✅ 控制器层
│ │ └── ExtractionController.ts # ✅ 388行 - 6个API端点
│ ├── routes/ # ✅ 路由层
│ │ └── index.ts # ✅ 115行 - 路由配置
│ ├── utils/ # 📁 空(预留)
│ └── workers/ # 📁 空(预留异步任务)
├── tool-a/ # 📁 空(未开发)
├── tool-c/ # 📁 空(未开发)
├── portal/ # 📁 空(未开发)
└── shared/ # 📁 空(预留共享代码)
✅ 真实状态:Tool B后端代码完整,共计 1,658 行
后端代码统计(重建完成):
- 总文件数:7个TypeScript文件
- 总代码量:约1,658行(不含注释和空行)
- 服务层:4个服务,1,038行
- 控制器层:1个控制器,388行
- 路由层:1个路由文件,115行
- 模块入口:1个index.ts,117行
🗄️ 数据库设计
Schema隔离
-- DC模块独立Schema
dc_schema (独立隔离,包含4个表)
数据表设计
1. dc_health_checks(健康检查记录)
model DcHealthCheck {
id String @id @default(uuid())
userId String
fileName String
columnName String
emptyRate Float // 空值率
avgLength Float // 平均长度
totalRows Int // 总行数
estimatedTokens Int // 估算Token消耗
status String // pass | warning | rejected
message String // 拦截原因
createdAt DateTime @default(now())
@@schema("dc_schema")
@@map("dc_health_checks")
}
2. dc_templates(预设模板)
model DcTemplate {
id String @id @default(uuid())
diseaseType String // 疾病类型(lung_cancer, diabetes, hypertension)
reportType String // 报告类型(pathology, admission, outpatient)
displayName String // 显示名称
fields Json // 目标字段定义
promptTemplate String // Prompt模板
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([diseaseType, reportType])
@@schema("dc_schema")
@@map("dc_templates")
}
3. dc_extraction_tasks(提取任务)
model DcExtractionTask {
id String @id @default(uuid())
userId String
projectName String
sourceFileKey String // OSS存储路径
textColumn String // 待提取列名
diseaseType String
reportType String
targetFields Json // 目标字段
modelA String @default("deepseek-v3")
modelB String @default("qwen3-72b")
status String @default("pending")
totalCount Int @default(0)
processedCount Int @default(0)
cleanCount Int @default(0) // 无冲突
conflictCount Int @default(0) // 有冲突
failedCount Int @default(0)
totalTokens Int @default(0)
totalCost Float @default(0)
error String?
createdAt DateTime @default(now())
startedAt DateTime?
completedAt DateTime?
items DcExtractionItem[]
@@schema("dc_schema")
@@map("dc_extraction_tasks")
}
4. dc_extraction_items(提取明细)
model DcExtractionItem {
id String @id @default(uuid())
taskId String
rowIndex Int // Excel行号
originalText String @db.Text
resultA Json? // DeepSeek结果
resultB Json? // Qwen结果
status String @default("pending")
conflictFields String[] @default([]) // 冲突字段列表
finalResult Json? // 最终结果
tokensA Int @default(0)
tokensB Int @default(0)
error String?
createdAt DateTime @default(now())
resolvedAt DateTime?
task DcExtractionTask @relation(fields: [taskId], references: [id], onDelete: Cascade)
@@schema("dc_schema")
@@map("dc_extraction_items")
}
数据库状态
✅ 已验证完成(2025-12-02)
验证结果:
- ✅ dc_schema: 已存在
- ✅ dc_health_checks: 已创建(2条记录)
- ✅ dc_templates: 已创建(3条预设模板)
- ✅ dc_extraction_tasks: 已创建(1条记录)
- ✅ dc_extraction_items: 已创建(4条记录)
预设模板列表:
- 肺癌病理报告 (lung_cancer/pathology)
- 糖尿病入院记录 (diabetes/admission)
- 高血压门诊病历 (hypertension/outpatient)
验证脚本:
# 检查数据库表状态
cd backend
node scripts/check-dc-tables.mjs
结论:✅ 数据库完全准备就绪,后端API应该可以直接使用!
🔌 API接口
路由前缀
/api/v1/dc/tool-b
已实现API(6个端点)
1. 健康检查
POST /health-check
Content-Type: multipart/form-data
Body:
- file: Excel文件
- columnName: 待检查列名
Response: {
status: 'pass' | 'warning' | 'rejected',
emptyRate: number,
avgLength: number,
totalRows: number,
estimatedTokens: number,
message: string
}
2. 获取所有模板
GET /templates
Response: {
templates: Array<{
id: string,
diseaseType: string,
reportType: string,
displayName: string,
fields: object
}>
}
3. 创建提取任务
POST /tasks
Content-Type: multipart/form-data
Body:
- file: Excel文件
- projectName: 项目名称
- textColumn: 文本列名
- diseaseType: 疾病类型
- reportType: 报告类型
- targetFields: JSON字符串
Response: {
taskId: string,
status: 'pending',
message: '任务创建成功'
}
4. 查询任务进度
GET /tasks/:taskId/progress
Response: {
taskId: string,
status: 'pending' | 'processing' | 'completed' | 'failed',
totalCount: number,
processedCount: number,
cleanCount: number,
conflictCount: number,
failedCount: number,
totalTokens: number,
totalCost: number,
progress: number, // 百分比
error?: string
}
5. 获取任务明细
GET /tasks/:taskId/items?status=conflict
Query:
- status: 'conflict' | 'clean' | 'failed' | 'all'
- page: number (default: 1)
- pageSize: number (default: 20)
Response: {
items: Array<{
id: string,
rowIndex: number,
originalText: string,
resultA: object,
resultB: object,
conflictFields: string[],
finalResult?: object,
status: string
}>,
pagination: {
total: number,
page: number,
pageSize: number,
totalPages: number
}
}
6. 解决冲突
POST /items/:itemId/resolve
Body: {
resolvedData: object // 用户确认的最终结果
}
Response: {
success: true,
itemId: string,
finalResult: object
}
🎨 前端UI设计
V4原型设计
文件位置:
docs/03-业务模块/DC-数据清洗整理/03-UI设计/工具B_病历结构化机器人_原型设计_V4.tsx
5个Step流程:
Step 1:上传与Schema
- Excel文件上传(拖拽或选择)
- 自动检测列名
- 选择文本列(待提取)
Step 2:配置映射
- 选择疾病类型(肺癌、糖尿病、高血压)
- 选择报告类型(病理、入院、门诊)
- 自动加载预设模板
- 显示目标字段(可调整)
Step 3:处理进度
- 实时进度条
- 当前处理行号
- Token消耗统计
- 成本预估
- 并发任务显示(DeepSeek + Qwen同时运行)
Step 4:冲突验证
- 冲突列表(表格显示)
- 双模型结果对比(左右分栏)
- 原文上下文显示
- 冲突字段高亮
- 快速确认按钮
Step 5:结果导出
- 统计概览(总数、无冲突、已解决、失败)
- Excel导出按钮
- 4个Sheet:
1. 完整结果
2. 无冲突项
3. 冲突项(已解决)
4. 失败项
⚠️ 状态:设计完成,代码未实现
🔧 技术实现细节
1. 健康检查机制
实现位置:HealthCheckService.ts(190行)
核心功能:
- Excel内存解析(xlsx库,无需落盘)
- 空值率计算(拦截 >50%)
- 平均文本长度计算
- Token消耗估算(基于平均长度 × 4 × 行数)
- 拦截策略:
- 空值率 >50%:❌ rejected
- 空值率 30-50%:⚠️ warning
- 空值率 <30%:✅ pass
云原生特性:
- ✅ 复用
storage.getFileBuffer()(OSS存储) - ✅ 复用
cache.set()(结果缓存1小时) - ✅ 内存处理(零落盘)
2. 双模型提取
实现位置:DualModelExtractionService.ts(390行)
核心功能:
- 并发调用DeepSeek-V3和Qwen-Max
- PII脱敏(姓名、身份证号)
- 3层JSON解析(容错机制):
- 标准JSON解析
- 去除Markdown代码块后解析
- 正则提取JSON对象
- 重试机制(最多3次)
- Token统计与成本计算
云原生特性:
- ✅ 复用
LLMFactory.getLLM() - ✅ 复用
jobQueue.add()(异步任务) - ✅ 复用
logger.info()(结构化日志)
3. 冲突检测算法
实现位置:ConflictDetectionService.ts(215行)
核心功能:
- 字段级对比(逐字段比较DeepSeek和Qwen结果)
- 值归一化(去除空格、统一大小写)
- 数值容差(相对误差 <5%视为一致)
- 语义相似度(预留接口,可接入embedding)
- 冲突字段列表生成
状态判断:
if (conflictFields.length === 0) {
status = 'clean' // 无冲突,自动通过
} else {
status = 'conflict' // 有冲突,需人工确认
}
4. 模板管理
实现位置:TemplateService.ts(243行)
预设模板(3个):
- 肺癌病理报告(lung_cancer/pathology)
- 14个字段:肿瘤类型、分期、基因突变等
- 糖尿病入院记录(diabetes/admission)
- 12个字段:血糖、糖化血红蛋白、并发症等
- 高血压门诊记录(hypertension/outpatient)
- 10个字段:血压、心率、用药等
Prompt模板:
你是一个专业的医学信息提取助手。请从以下病历文本中提取关键信息...
疾病类型:{diseaseType}
报告类型:{reportType}
目标字段:{fields}
病历原文:
{originalText}
请严格按照JSON格式输出...
✅ 已解决的问题
1. 数据库表状态验证 ✅ 已完成(2025-12-02)
问题描述:
- 代码丢失后无法确认数据库表是否存在
- 迁移文件丢失(
migration.sql为空)
解决方案:
- ✅ 创建了数据库检查脚本
backend/scripts/check-dc-tables.mjs - ✅ 验证确认所有表已创建
- ✅ 验证确认预设模板已初始化
验证结果:
- ✅ dc_schema存在
- ✅ 4个表全部存在
- ✅ 3个预设模板已初始化
- ✅ 有测试数据可用
结论:数据库完全准备就绪,可以直接使用!
⚠️ 当前存在的问题
2. 前端完全未开发 🔴 高优先级
问题描述:
- 只有Placeholder占位符
- V4原型设计已完成,但无任何实现代码
影响:
- ❌ 无法进行完整的端到端测试
- ❌ 无法演示给用户
工作量估算:
- Step 1(上传与Schema):4小时
- Step 2(配置映射):3小时
- Step 3(处理进度):3小时
- Step 4(冲突验证):6小时(最复杂)
- Step 5(结果导出):2小时
- 总计:18小时(约2-3天)
优先级:🔴 高(阻塞完整功能)
3. 后端未经真实测试 🟡 中优先级
问题描述:
- 代码是基于设计文档重建的
- 没有运行过真实的API测试
- 没有验证过LLM调用是否正常
风险:
- ⚠️ 可能存在未发现的bug
- ⚠️ 实际LLM提取效果未验证
解决方案:
- 先执行
npx prisma db push创建表 - 启动后端:
npm run dev - 使用REST Client测试6个API端点
- 上传真实Excel文件测试提取效果
优先级:🟡 中(前端开发前应完成)
4. Cursor终端输出问题 🟢 低优先级
问题描述:
- PowerShell终端无法正常显示命令输出
- 导致无法运行数据库检查脚本
- 浪费了大量时间尝试不同方法
影响:
- ⚠️ 开发调试不便
- ⚠️ 无法实时查看日志
临时解决方案:
- 使用外部PowerShell或CMD窗口
- 使用Prisma Studio可视化工具
- 直接启动后端查看启动日志
优先级:🟢 低(有替代方案)
📝 下一步开发计划
立即需要做的(紧急)
-
验证数据库表 🔴
cd backend npx prisma db push npx prisma studio # 可视化确认 -
后端API测试 🔴
- 启动后端服务
- 测试6个API端点
- 验证LLM调用
- 确认双模型提取逻辑
-
Git再次提交 🔴
- 确保所有代码已提交
- 推送到远程仓库(如果有)
短期开发任务(本周)
-
前端UI开发 🔴(预计2-3天)
- 基于V4原型实现5个Step
- 参考ASL模块的前端代码结构
- 使用React Query管理API调用
- 使用Ant Design组件
-
端到端测试 🟡
- 真实Excel文件测试
- 冲突解决流程测试
- 导出功能测试
中期优化任务(下周)
-
性能优化 🟡
- 添加并发控制(p-limit)
- 优化Excel大文件处理
- 添加进度实时推送(WebSocket)
-
错误处理优化 🟡
- 完善错误提示
- 添加重试机制
- 失败任务恢复
📚 相关文档
设计文档
开发记录
- Day2完成总结(丢失前)
- Day3完成总结(丢失前)
- DC模块重建完成总结(重建后)
规范文档
🎓 给新开发者的提示
快速上手
-
了解代码丢失事件
- 阅读本文档的"重要事件记录"部分
- 理解为什么要每日Git提交
-
熟悉后端代码
- 先看
backend/src/modules/dc/index.ts了解模块结构 - 阅读4个Service的代码注释
- 运行Prisma Studio查看数据库表
- 先看
-
理解云原生架构
- 阅读
云原生开发规范 - 了解如何复用平台基础设施
- 禁止:本地文件存储、内存缓存、硬编码配置
- 阅读
-
参考ASL模块
- DC模块前端应类似ASL模块的前端结构
- 复用ASL的Hooks、组件和工具函数
- 保持一致的代码风格
常见陷阱
❌ 不要这样做:
- 本地开发时直接写
fs.writeFileSync()(违反云原生规范) - 使用全局变量缓存数据(Serverless环境不可靠)
- 忘记每日Git提交(代码可能丢失)
- 在Cursor终端运行复杂脚本(输出问题)
✅ 应该这样做:
- 使用
storage.uploadBuffer()存储文件 - 使用
cache.set()缓存数据 - 每天下班前必须Git提交
- 复杂脚本在外部PowerShell运行
📊 模块统计
代码量统计(当前)
后端代码(已完成):
- TypeScript文件:7个
- 总行数:约1,658行
- 服务层:4个服务,1,038行
- 控制器层:388行
- 路由层:115行
前端代码(未开发):
- TypeScript/TSX文件:1个(Placeholder)
- 总行数:14行
- 真实功能:0%
数据库:
- 表数量:4个(Prisma Schema已定义)
- 实际创建:⚠️ 未确认
开发进度
整体进度:约35%
- Tool B后端:100% ✅
- Tool B前端:0% ❌
- Tool A:0% ❌
- Tool C:0% ❌
- Portal:0% ❌
🤝 致谢
感谢所有参与DC模块开发的同事,特别是在代码丢失后快速重建的努力。
本文档力求真实反映模块状态,包括问题和不足,以便更好地规划后续工作。
最后更新: 2025-11-28
文档维护: DC模块开发团队
联系方式: 项目Issues