feat(dc/tool-c): Day 2 - Session管理与数据处理完成

核心功能:
- 数据库: 创建dc_tool_c_sessions表 (12字段, 3索引)
- 服务层: SessionService (383行), DataProcessService (303行)
- 控制器: SessionController (300行, 6个API端点)
- 路由: 新增6个Session管理路由
- 测试: 7个API测试全部通过 (100%)

技术亮点:
- 零落盘架构: Excel内存解析, OSS存储
- Session管理: 10分钟过期, 心跳延长机制
- 云原生规范: storage/logger/prisma全平台复用
- 完整测试: 上传/预览/完整数据/删除/心跳

文件清单:
- backend/prisma/schema.prisma (新增DcToolCSession模型)
- backend/prisma/migrations/create_tool_c_session.sql
- backend/scripts/create-tool-c-table.mjs
- backend/src/modules/dc/tool-c/services/ (SessionService, DataProcessService)
- backend/src/modules/dc/tool-c/controllers/SessionController.ts
- backend/src/modules/dc/tool-c/routes/index.ts
- backend/test-tool-c-day2.mjs
- docs/03-业务模块/DC-数据清洗整理/00-工具C当前状态与开发指南.md
- docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-06_工具C_Day2开发完成总结.md

代码统计: ~1900行
测试结果: 7/7 通过 (100%)
云原生规范: 完全符合
This commit is contained in:
2025-12-06 22:12:47 +08:00
parent 8be741cd52
commit 2348234013
13 changed files with 3466 additions and 0 deletions

View File

@@ -0,0 +1,765 @@
# 工具CTool C- 科研数据编辑器 - 当前状态与开发指南
> **最后更新**: 2025-12-06
> **当前版本**: Day 2 MVP开发完成
> **开发进度**: Python微服务 ✅ | Session管理 ✅ | AI代码生成 ⏸️ | 前端开发 ⏸️
---
## 📊 模块整体进度
| 组件 | 进度 | 代码行数 | 状态 |
|------|------|---------|------|
| **Python微服务** | 100% | ~450行 | ✅ Day 1完成 |
| **Node.js后端** | 40% | ~1700行 | 🟡 Day 2完成 |
| **前端界面** | 0% | 0行 | ⏸️ 未开始 |
| **数据库Schema** | 100% | 1表 | ✅ Day 2完成 |
| **总体进度** | **25%** | **~2150行** | 🟡 **MVP阶段** |
---
## ✅ 已完成功能Day 1-2
### Day 1: Python微服务扩展 ✅
---
### 1. Python微服务扩展
#### 文件结构
```
extraction_service/
├── services/
│ └── dc_executor.py # 427行 ✅ 新增
├── main.py # 617行新增2个端点
├── test_module.py # 27行测试脚本
├── quick_test.py # 64行快速测试
└── test_execute_simple.py # 51行简单测试
```
#### 核心功能
**1.1 AST静态代码检查**
- **模块**: `dc_executor.py::validate_code()`
- **功能**:
- 解析Python代码的抽象语法树AST
- 检测危险模块导入os, sys, subprocess等
- 检测危险函数调用eval, exec, open等
- 检测是否操作df变量
- **安全黑名单**:
```python
DANGEROUS_MODULES = {
'os', 'sys', 'subprocess', 'shutil', 'glob',
'socket', 'urllib', 'requests', 'http',
'pickle', 'shelve', 'dbm',
'importlib', '__import__',
'eval', 'exec', 'compile',
'open', 'input', 'file',
}
DANGEROUS_BUILTINS = {
'eval', 'exec', 'compile', '__import__',
'open', 'input', 'file',
'getattr', 'setattr', 'delattr',
'globals', 'locals', 'vars',
}
```
**1.2 Pandas代码沙箱执行** ✅
- **模块**: `dc_executor.py::execute_pandas_code()`
- **功能**:
- 创建安全的执行环境(限制可用函数)
- 执行Pandas数据处理代码
- 捕获print输出
- 30秒超时保护
- 返回执行结果和元数据
- **安全措施**:
- 限制可用内置函数仅允许安全函数如len, range等
- 禁止文件操作
- 禁止网络访问
- 禁止系统调用
- 超时自动终止Unix系统
**1.3 FastAPI端点** ✅
- **端点1**: `POST /api/dc/validate`
- 功能:代码安全验证
- 请求:`{"code": "..."}`
- 响应:`{"valid": bool, "errors": [], "warnings": []}`
- **端点2**: `POST /api/dc/execute`
- 功能Pandas代码执行
- 请求:`{"data": [...], "code": "..."}`
- 响应:`{"success": bool, "result_data": [...], "output": "", ...}`
#### 测试验证结果
✅ **测试1正常代码执行**
```python
# 输入
data = [{"age": 25}, {"age": 65}, {"age": 45}]
code = "df['old'] = df['age'] > 60"
# 输出
{
"success": true,
"result_data": [
{"age": 25, "old": false},
{"age": 65, "old": true},
{"age": 45, "old": false}
],
"execution_time": 0.004,
"result_shape": [3, 2]
}
```
✅ **测试2危险代码拦截**
```python
# 输入
code = "import os"
# 输出
{
"valid": false,
"errors": ["🚫 禁止导入危险模块: os (行 1)"],
"warnings": ["⚠️ 代码中未使用 df 变量,可能无法操作数据"]
}
```
✅ **测试3医疗数据清洗**
```python
# 输入
data = [
{"patient_id": "P001", "age": 25, "sbp": 120, "dbp": 80},
{"patient_id": "P002", "age": 65, "sbp": 150, "dbp": 95},
{"patient_id": "P003", "age": None, "sbp": 160, "dbp": 100}
]
code = """
import numpy as np
df['age'] = df['age'].apply(lambda x: np.nan if x is None or x > 120 else x)
df['hypertension'] = df.apply(
lambda row: '高血压' if row['sbp'] >= 140 or row['dbp'] >= 90 else '正常',
axis=1
)
"""
# 输出
{
"success": true,
"result_data": [
{"patient_id": "P001", "age": 25, "sbp": 120, "dbp": 80, "hypertension": "正常"},
{"patient_id": "P002", "age": 65, "sbp": 150, "dbp": 95, "hypertension": "高血压"},
{"patient_id": "P003", "age": null, "sbp": 160, "dbp": 100, "hypertension": "高血压"}
],
"execution_time": 0.008
}
```
---
### Day 2: Session管理 + 数据处理 ✅
#### 文件结构(新增)
```
backend/src/modules/dc/tool-c/
├── services/
│ ├── PythonExecutorService.ts # 177行 ✅ Day 1
│ ├── SessionService.ts # 383行 ✅ Day 2 新增
│ └── DataProcessService.ts # 303行 ✅ Day 2 新增
├── controllers/
│ ├── TestController.ts # 131行 ✅ Day 1
│ └── SessionController.ts # 300行 ✅ Day 2 新增
└── routes/
└── index.ts # 62行 ✅ Day 2 更新
```
#### 核心功能
**2.1 SessionService** ✅
- **功能**: Session生命周期管理
- **方法**:
```typescript
class SessionService {
createSession(userId, fileName, buffer): Promise<SessionData>
getSession(sessionId): Promise<SessionData>
getPreviewData(sessionId): Promise<PreviewDataResponse>
getFullData(sessionId): Promise<any[]>
deleteSession(sessionId): Promise<void>
updateHeartbeat(sessionId): Promise<Date>
cleanExpiredSessions(): Promise<number>
}
```
- **特性**:
- ✅ 零落盘Excel内存解析直接上传OSS
- ✅ 10分钟过期机制
- ✅ 心跳延长功能
- ✅ 自动清理过期Session
- ✅ 完整的错误处理
**2.2 DataProcessService** ✅
- **功能**: Excel文件解析和验证
- **方法**:
```typescript
class DataProcessService {
parseExcel(buffer): ParsedExcelData
validateFile(buffer, fileName): ValidationResult
inferColumnTypes(data): ColumnType[]
formatFileSize(bytes): string
}
```
- **特性**:
- ✅ 内存解析(零落盘)
- ✅ 10MB文件大小限制
- ✅ 支持.xlsx, .xls, .csv
- ✅ 列类型推断(可选)
**2.3 SessionController** ✅
- **功能**: Session管理API端点
- **端点**:
- `POST /sessions/upload` - 上传Excel创建Session ✅
- `GET /sessions/:id` - 获取Session信息 ✅
- `GET /sessions/:id/preview` - 获取预览数据前100行
- `GET /sessions/:id/full` - 获取完整数据 ✅
- `DELETE /sessions/:id` - 删除Session ✅
- `POST /sessions/:id/heartbeat` - 更新心跳 ✅
**2.4 数据库表** ✅
- **表名**: `dc_schema.dc_tool_c_sessions`
- **字段**: 12个id, user_id, file_name, file_key, total_rows, total_cols, columns, encoding, file_size, created_at, updated_at, expires_at
- **索引**: 3个主键 + user_id + expires_at
- **迁移脚本**: `backend/scripts/create-tool-c-table.mjs`
#### API测试结果Day 2
✅ **测试数据**:
```
文件名: test-medical-data.xlsx
数据: 8行 x 7列医疗数据
列名: patient_id, name, age, gender, diagnosis, sbp, dbp
文件大小: 17.42 KB
```
✅ **测试结果**:
| 测试项 | 状态 | 说明 |
|--------|------|------|
| 上传文件创建Session | ✅ | 返回201Session创建成功 |
| 获取Session信息 | ✅ | 元数据正确返回 |
| 获取预览数据前100行| ✅ | 8行数据全部返回 |
| 获取完整数据 | ✅ | 从OSS读取成功 |
| 更新心跳 | ✅ | 过期时间延长10分钟 |
| 删除Session | ✅ | OSS+DB清理成功 |
| 验证删除 | ✅ | 返回404确认删除 |
| **总计** | **7/7 (100%)** | **所有测试通过** |
✅ **云原生规范检查**:
- ✅ 使用 `storage` 服务(零落盘)
- ✅ 使用 `logger` 服务(结构化日志)
- ✅ 使用 `prisma` 全局实例
- ✅ Excel内存解析无本地文件存储
- ✅ 无硬编码配置
---
### 2. Node.js后端集成Day 1
#### 文件结构
```
backend/src/modules/dc/tool-c/
├── services/
│ └── PythonExecutorService.ts # 177行 ✅ 新增
├── controllers/
│ └── TestController.ts # 131行 ✅ 新增
├── routes/
│ └── index.ts # 29行 ✅ 新增
└── README.md # 172行技术文档
```
#### 核心服务
**2.1 PythonExecutorService** ✅
- **功能**: 封装Python微服务HTTP调用
- **方法**:
```typescript
class PythonExecutorService {
validateCode(code: string): Promise<ValidateCodeResponse>
executeCode(data: any[], code: string): Promise<ExecuteCodeResponse>
healthCheck(): Promise<boolean>
}
```
- **特性**:
- 完整的错误处理和重试机制
- 30秒超时控制
- 连接状态检测
- 详细的日志记录
**2.2 TestController** ✅
- **功能**: Day 1测试端点控制器
- **端点**:
- `GET /test/health` - 测试Python服务健康
- `POST /test/validate` - 测试代码验证
- `POST /test/execute` - 测试代码执行
**2.3 路由注册** ✅
- **前缀**: `/api/v1/dc/tool-c`
- **状态**: 已在 `dc/index.ts` 中注册
- **可访问**: ✅ 服务启动后即可调用
---
## ⏸️ 待开发功能Day 2-15
### Week 1: 基础架构Day 2-5
#### Day 2: 数据库 + Session管理 ✅
**数据库Schema**(已创建):
```prisma
// dc_tool_c_sessions 表 ✅
model DcToolCSession {
id String @id @default(uuid())
userId String
fileName String
fileKey String // OSS存储key
totalRows Int
totalCols Int
columns Json // 列名数组
encoding String? // 编码格式
fileSize Int
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
expiresAt DateTime // 过期时间
@@index([userId])
@@index([expiresAt])
@@map("dc_tool_c_sessions")
@@schema("dc_schema")
}
```
**已完成服务**:
- [x] `SessionService.ts` - Session管理383行
- [x] `createSession()` - 创建会话上传Excel到OSS
- [x] `getSession()` - 获取会话元数据
- [x] `getPreviewData()` - 获取预览数据前100行
- [x] `getFullData()` - 获取完整数据从OSS
- [x] `deleteSession()` - 删除会话OSS+DB
- [x] `updateHeartbeat()` - 更新心跳延长10分钟
- [x] `cleanExpiredSessions()` - 清理过期Session
- [x] `DataProcessService.ts` - 数据处理303行
- [x] Excel文件解析xlsx库内存解析
- [x] 文件验证(大小、格式、内容)
- [x] 列类型推断(可选)
- [x] 文件大小限制10MB
- [x] `SessionController.ts` - Session控制器300行
- [x] 6个API端点全部实现
#### Day 3: AI代码生成服务 ⏸️
**待开发服务**:
- [ ] `AICodeService.ts` - AI代码生成
- [ ] 集成LLMFactory
- [ ] System Prompt设计含10个Few-shot示例
- [ ] 代码生成和自我修正
- [ ] 上下文管理Session元数据
**System Prompt要点**:
```typescript
const systemPrompt = `
你是一个医疗科研数据清洗专家负责生成Pandas代码。
数据集信息:
- 文件名:${fileName}
- 行数:${totalRows}
- 列数:${totalCols}
- 列名:${columns.join(', ')}
安全规则:
1. 只能操作df变量
2. 禁止导入os、sys等危险模块
3. 禁止使用eval、exec等危险函数
4. 必须进行异常处理
Few-shot示例
[示例1] 标记老年组
用户: 把年龄大于60的标记为老年组
代码: df['age_group'] = df['age'].apply(lambda x: '老年' if x > 60 else '非老年')
...
`;
```
#### Day 3-5: AI代码生成和控制器 ⏸️
**待开发控制器**:
- [ ] `AIController.ts`
- [ ] POST `/ai/chat` - AI对话生成代码
- [ ] POST `/ai/execute` - 执行AI生成的代码
- [ ] GET `/ai/history/:sessionId` - 获取对话历史
**待开发服务**:
- [ ] `AICodeService.ts` - AI代码生成
- [ ] 集成LLMFactory
- [ ] System Prompt设计10个Few-shot
- [ ] 上下文管理
- [ ] 自我修正机制
### Week 2: 前端开发Day 6-10
**待开发组件**:
- [ ] `ToolCEditor.tsx` - 主编辑器页面
- [ ] `DataGrid.tsx` - AG Grid数据表格
- [ ] `AICopilot.tsx` - AI助手侧边栏
- [ ] `FileUpload.tsx` - 文件上传组件
- [ ] `CodeBlock.tsx` - 代码显示组件
- [ ] `ActionCard.tsx` - AI操作卡片
### Week 3: 测试优化Day 11-15
**测试任务**:
- [ ] 15个医疗数据清洗场景测试
- [ ] 性能测试10MB文件
- [ ] 并发测试(多用户)
- [ ] 安全测试(代码沙箱)
- [ ] UI/UX测试
---
## 🗄️ 数据库状态
### 当前表结构
**dc_schema 中的表**:
```sql
-- Tool B相关表已存在
dc_schema.dc_templates -- 预设模板 ✅
dc_schema.dc_extraction_tasks -- 提取任务 ✅
dc_schema.dc_extraction_items -- 提取记录 ✅
dc_schema.dc_health_checks -- 健康检查 ✅
-- Tool C相关表
dc_schema.dc_tool_c_sessions -- ✅ 已创建Day 2
dc_schema.dc_tool_c_ai_history -- ⏸️ 待创建Day 3
```
**创建方式**(已完成):
```bash
# Day 2 已执行
cd backend
node scripts/create-tool-c-table.mjs # ✅ 成功
npx prisma generate # ✅ 成功
```
**表结构详情**:
```sql
-- dc_tool_c_sessions 表12字段3索引
CREATE TABLE dc_schema.dc_tool_c_sessions (
id UUID PRIMARY KEY,
user_id VARCHAR(255),
file_name VARCHAR(500),
file_key VARCHAR(500), -- OSS路径
total_rows INTEGER,
total_cols INTEGER,
columns JSONB, -- ["age", "gender", ...]
encoding VARCHAR(50),
file_size INTEGER,
created_at TIMESTAMP,
updated_at TIMESTAMP,
expires_at TIMESTAMP -- 10分钟过期
);
```
---
## 🔌 API端点清单
### Python微服务 (http://localhost:8000)
| 方法 | 端点 | 功能 | 状态 | 说明 |
|------|------|------|------|------|
| GET | `/api/health` | 健康检查 | ✅ | 检查服务状态 |
| POST | `/api/dc/validate` | 代码验证 | ✅ | AST安全检查 |
| POST | `/api/dc/execute` | 代码执行 | ✅ | Pandas代码执行 |
### Node.js后端 (http://localhost:3000)
#### 测试端点Day 1
| 方法 | 端点 | 功能 | 状态 | 说明 |
|------|------|------|------|------|
| GET | `/api/v1/dc/tool-c/test/health` | 测试Python服务 | ✅ | Day 1测试用 |
| POST | `/api/v1/dc/tool-c/test/validate` | 测试代码验证 | ✅ | Day 1测试用 |
| POST | `/api/v1/dc/tool-c/test/execute` | 测试代码执行 | ✅ | Day 1测试用 |
#### Session管理端点Day 2 已完成)✅
| 方法 | 端点 | 功能 | 状态 | 测试 |
|------|------|------|------|------|
| POST | `/api/v1/dc/tool-c/sessions/upload` | 上传Excel | ✅ | 201 成功 |
| GET | `/api/v1/dc/tool-c/sessions/:id` | 获取Session | ✅ | 200 成功 |
| GET | `/api/v1/dc/tool-c/sessions/:id/preview` | 获取预览数据 | ✅ | 200 成功 |
| GET | `/api/v1/dc/tool-c/sessions/:id/full` | 获取完整数据 | ✅ | 200 成功 |
| DELETE | `/api/v1/dc/tool-c/sessions/:id` | 删除Session | ✅ | 200 成功 |
| POST | `/api/v1/dc/tool-c/sessions/:id/heartbeat` | 心跳更新 | ✅ | 200 成功 |
#### AI功能端点待开发
| 方法 | 端点 | 功能 | 状态 | 计划 |
|------|------|------|------|------|
| POST | `/api/v1/dc/tool-c/ai/chat` | AI对话生成代码 | ⏸️ | Day 3 |
| POST | `/api/v1/dc/tool-c/ai/execute` | 执行AI代码 | ⏸️ | Day 3 |
| GET | `/api/v1/dc/tool-c/ai/history/:sessionId` | 获取历史 | ⏸️ | Day 3 |
---
## ⚙️ 环境配置
### 必需环境变量
在 `backend/.env` 中配置:
```bash
# Python微服务地址必需
EXTRACTION_SERVICE_URL=http://localhost:8000
# OSS存储Day 2使用
OSS_REGION=your-region
OSS_BUCKET=your-bucket
OSS_ACCESS_KEY_ID=your-key-id
OSS_ACCESS_KEY_SECRET=your-secret
# LLM配置Day 3使用
LLM_PROVIDER=openai
LLM_API_KEY=your-api-key
LLM_MODEL=gpt-4
```
### 服务启动顺序
1. **启动Python微服务** (必需)
```bash
cd extraction_service
.\venv\Scripts\activate
python main.py
# 服务运行在 http://localhost:8000
```
2. **启动Node.js后端** (必需)
```bash
cd backend
npm run dev
# 服务运行在 http://localhost:3000
```
3. **启动前端** (Day 6后)
```bash
cd frontend-v2
npm run dev
# 服务运行在 http://localhost:5173
```
---
## 📂 代码结构
### Python微服务
```
extraction_service/
├── services/
│ ├── dc_executor.py # DC代码执行模块 ✅
│ ├── pdf_extractor.py # PDF提取
│ ├── docx_extractor.py # Docx提取
│ └── txt_extractor.py # Txt提取
├── main.py # FastAPI主文件 ✅
├── requirements.txt # Python依赖
└── venv/ # 虚拟环境
```
### Node.js后端
```
backend/src/modules/dc/tool-c/
├── services/
│ ├── PythonExecutorService.ts # Python调用服务 ✅
│ ├── SessionService.ts # Session管理 ⏸️
│ ├── AICodeService.ts # AI代码生成 ⏸️
│ └── DataProcessService.ts # 数据处理 ⏸️
├── controllers/
│ ├── TestController.ts # 测试控制器 ✅
│ ├── SessionController.ts # Session控制器 ⏸️
│ └── AIController.ts # AI控制器 ⏸️
├── routes/
│ └── index.ts # 路由定义 ✅
└── utils/
└── (待添加)
```
### 前端
```
frontend-v2/src/modules/dc/tool-c/
├── pages/
│ └── ToolCEditor.tsx # 主编辑器页面 ⏸️
├── components/
│ ├── DataGrid.tsx # AG Grid表格 ⏸️
│ ├── AICopilot.tsx # AI助手 ⏸️
│ ├── FileUpload.tsx # 文件上传 ⏸️
│ └── CodeBlock.tsx # 代码块 ⏸️
├── hooks/
│ ├── useSession.ts # Session Hook ⏸️
│ └── useAI.ts # AI Hook ⏸️
└── types/
└── index.ts # 类型定义 ⏸️
```
---
## 🧪 测试清单
### Day 1 测试(已完成)✅
- [x] Python服务健康检查
- [x] AST代码验证正常代码
- [x] AST代码验证危险代码拦截
- [x] Pandas代码执行简单场景
- [x] Pandas代码执行医疗数据清洗
- [x] Node.js服务集成
- [x] HTTP通信正常
### Day 2-15 测试(待执行)⏸️
#### 基础功能测试
- [ ] Excel文件上传<10MB
- [ ] 文件编码检测
- [ ] Session创建和删除
- [ ] OSS存储读写
- [ ] 心跳机制
#### AI功能测试
- [ ] LLM代码生成
- [ ] 代码自我修正
- [ ] Few-shot效果验证
- [ ] 上下文理解准确性
#### 15个医疗数据清洗场景
**基础场景(成功率>90%**:
- [ ] 场景1标记老年组age > 60
- [ ] 场景2删除缺失患者ID的行
- [ ] 场景3性别编码男1女0
- [ ] 场景4计算BMI
- [ ] 场景5删除缺失率>50%的列
**中等场景(成功率>80%**:
- [ ] 场景6血压分类正常/高血压)
- [ ] 场景7计算住院天数
- [ ] 场景8删除重复患者ID
- [ ] 场景9清理异常年龄值>120
- [ ] 场景10按性别分组统计
**高级场景(成功率>60%**:
- [ ] 场景11复杂分组聚合
- [ ] 场景12时间序列分析
- [ ] 场景13医学规则验证
- [ ] 场景14多列联合清洗
- [ ] 场景15缺失值智能填充
---
## 🚀 快速开始
### 开发者快速上手
1. **启动Python微服务**
```bash
cd extraction_service
.\venv\Scripts\activate
python main.py
```
2. **测试Python服务**
```bash
# PowerShell测试
Invoke-WebRequest -Uri "http://localhost:8000/api/health"
```
3. **启动Node.js后端**
```bash
cd backend
npm install # 首次运行
npm run dev
```
4. **测试Node.js集成**
```bash
curl http://localhost:3000/api/v1/dc/tool-c/test/health
```
### API调用示例
**代码验证**:
```bash
curl -X POST http://localhost:3000/api/v1/dc/tool-c/test/validate \
-H "Content-Type: application/json" \
-d '{"code":"df[\"age_group\"] = df[\"age\"] > 60"}'
```
**代码执行**:
```bash
curl -X POST http://localhost:3000/api/v1/dc/tool-c/test/execute \
-H "Content-Type: application/json" \
-d '{
"data": [{"age": 25}, {"age": 65}],
"code": "df[\"old\"] = df[\"age\"] > 60"
}'
```
---
## 📝 开发记录
| 日期 | 里程碑 | 详细记录 |
|------|--------|---------|
| 2025-12-06 | Day 1完成 | [2025-12-06_工具C_Day1开发完成总结.md](./06-开发记录/2025-12-06_工具C_Day1开发完成总结.md) |
| 2025-12-06 | Day 2完成 | [2025-12-06_工具C_Day2开发完成总结.md](./06-开发记录/2025-12-06_工具C_Day2开发完成总结.md) |
---
## 🎯 下一步行动
### 立即执行Day 2
1. [ ] 创建 `dc_tool_c_sessions` 数据库表
2. [ ] 实现 `SessionService.ts`
3. [ ] 实现 `DataProcessService.ts`
4. [ ] 集成OSS存储服务
5. [ ] 创建 `SessionController.ts`
### 本周目标Week 1
- [ ] 完成Session管理和数据处理
- [ ] 完成AI代码生成服务
- [ ] 完成后端所有API端点
- [ ] 通过Postman测试所有API
---
## 📚 相关文档
- **需求文档**: [PRDTool C - 科研数据编辑器 (MVP V1.1).md](./01-需求分析/PRDTool%20C%20-%20科研数据编辑器%20(MVP%20V1.1).md)
- **技术设计**: [技术设计文档:工具 C - 科研数据编辑器 (V7 云端沙箱抗风险版).md](./02-技术设计/技术设计文档:工具%20C%20-%20科研数据编辑器%20(V7%20云端沙箱抗风险版).md)
- **开发计划**: [工具C_MVP开发计划_V1.0.md](./04-开发计划/工具C_MVP开发计划_V1.0.md)
- **TODO清单**: [工具C_MVP开发_TODO清单.md](./04-开发计划/工具C_MVP开发_TODO清单.md)
- **UI原型**: [工具C_原型设计V6.html](./03-UI设计/工具C_原型设计V6%20.html)
---
## 🔐 安全说明
### 代码执行安全
- ✅ AST静态检查拦截危险操作
- ✅ 沙箱环境限制可用函数
- ✅ 30秒超时保护
- ✅ 禁止文件和网络操作
- ⏸️ 资源使用限制(待实现)
### 数据安全
- ✅ 10MB文件大小限制
- ⏸️ OSS加密存储待实现
- ⏸️ 10分钟Session过期待实现
- ⏸️ 用户隔离(待实现)
---
**维护者**: AI Assistant
**联系方式**: 请查看项目README
**最后更新**: 2025-12-06

View File

@@ -0,0 +1,600 @@
# 工具C Day 2 开发完成总结
> **日期**: 2025-12-06
> **开发目标**: Session管理 + 数据处理
> **开发状态**: ✅ 全部完成
---
## 📊 完成情况概览
| 任务类别 | 完成任务数 | 总任务数 | 完成率 |
|---------|-----------|---------|--------|
| **数据库Schema** | 1 | 1 | 100% |
| **服务层开发** | 2 | 2 | 100% |
| **控制器开发** | 1 | 1 | 100% |
| **路由配置** | 1 | 1 | 100% |
| **API测试** | 7 | 7 | 100% |
| **总计** | **12** | **12** | **100%** ✅ |
---
## ✅ 已完成任务清单
### 1. 数据库Schema设计与创建
#### 任务1.1: 设计Prisma模型 ✅
- **文件**: `backend/prisma/schema.prisma`
- **新增模型**: `DcToolCSession`
- **字段数**: 12个
- id, userId, fileName, fileKey
- totalRows, totalCols, columns, encoding, fileSize
- createdAt, updatedAt, expiresAt
**关键设计决策**:
- ✅ 符合云原生规范DB只存元数据不存大数据
- ✅ 删除了previewData字段从OSS实时读取
- ✅ 添加expiresAt支持10分钟过期
- ✅ 使用JSONB存储columns数组
#### 任务1.2: 创建数据库表 ✅
- **方式**: Node.js脚本直接执行SQL避免prisma db push冲突
- **脚本**: `backend/scripts/create-tool-c-table.mjs` (139行)
- **结果**:
- ✅ 表创建成功
- ✅ 3个索引创建成功
- ✅ 表注释添加成功
- ✅ Prisma Client重新生成
**创建的索引**:
1. `dc_tool_c_sessions_pkey` - 主键索引
2. `idx_dc_tool_c_sessions_user_id` - 用户查询索引
3. `idx_dc_tool_c_sessions_expires_at` - 过期清理索引
---
### 2. 服务层开发
#### 任务2.1: SessionService实现 ✅
- **文件**: `backend/src/modules/dc/tool-c/services/SessionService.ts` (383行)
- **功能**:
-`createSession()` - 创建会话
- 文件大小验证(<10MB
- Excel内存解析零落盘
- 上传到OSSplatform storage服务
- 保存元数据到DB
- 返回Session信息
-`getSession()` - 获取会话
- 从DB查询Session
- 检查是否过期
- 返回元数据
-`getPreviewData()` - 获取预览数据
- 从OSS下载文件到内存
- 内存解析Excel
- 返回前100行
-`getFullData()` - 获取完整数据
- 从OSS下载完整文件
- 内存解析
- 返回所有数据
-`deleteSession()` - 删除会话
- 删除OSS文件
- 删除DB记录
- 错误容错OSS删除失败不影响DB
-`updateHeartbeat()` - 更新心跳
- 延长expiresAt 10分钟
- 更新updatedAt时间戳
-`cleanExpiredSessions()` - 清理过期会话
- 查询过期Session
- 批量删除
- 返回清理数量
**代码示例**:
```typescript
async createSession(userId: string, fileName: string, fileBuffer: Buffer) {
// 1. 验证文件大小
if (fileBuffer.length > 10 * 1024 * 1024) {
throw new Error('文件大小超过10MB');
}
// 2. 内存解析Excel零落盘
const workbook = xlsx.read(fileBuffer, { type: 'buffer' });
const data = xlsx.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]);
// 3. 上传到OSS
const fileKey = `dc/tool-c/sessions/${userId}/${Date.now()}-${fileName}`;
await storage.upload(fileKey, fileBuffer);
// 4. 保存到DB只存元数据
const session = await prisma.dcToolCSession.create({
data: { userId, fileName, fileKey, totalRows, totalCols, columns, ... }
});
return session;
}
```
#### 任务2.2: DataProcessService实现 ✅
- **文件**: `backend/src/modules/dc/tool-c/services/DataProcessService.ts` (303行)
- **功能**:
-`parseExcel()` - 解析Excel文件
- 内存读取(零落盘)
- 转换为JSON格式
- 提取行数、列数、列名
-`validateFile()` - 验证文件
- 文件大小检查(<10MB
- 文件格式检查(.xlsx, .xls, .csv
- 内容完整性检查
- 返回友好错误信息
-`inferColumnTypes()` - 推断列类型(可选)
- 取前10行样本
- 推断类型number, string, date, boolean, mixed
- 返回类型信息
-`formatFileSize()` - 格式化文件大小
- 自动转换单位B, KB, MB
-`generateFileSummary()` - 生成文件摘要
- 包含所有元信息
- 前5行样本数据
**代码示例**:
```typescript
parseExcel(buffer: Buffer): ParsedExcelData {
// 内存解析(零落盘)
const workbook = xlsx.read(buffer, { type: 'buffer' });
const sheet = workbook.Sheets[workbook.SheetNames[0]];
const data = xlsx.utils.sheet_to_json(sheet);
return {
data,
columns: Object.keys(data[0] || {}),
totalRows: data.length,
totalCols: Object.keys(data[0] || {}).length,
};
}
validateFile(buffer: Buffer, fileName: string): ValidationResult {
// 1. 文件大小
if (buffer.length > 10 * 1024 * 1024) {
return { valid: false, error: '文件超过10MB' };
}
// 2. 文件格式
const ext = fileName.substring(fileName.lastIndexOf('.'));
if (!['.xlsx', '.xls', '.csv'].includes(ext)) {
return { valid: false, error: '不支持的格式' };
}
// 3. 内容完整性
try {
this.parseExcel(buffer);
} catch (error) {
return { valid: false, error: '文件无法解析' };
}
return { valid: true };
}
```
---
### 3. 控制器层开发
#### 任务3.1: SessionController实现 ✅
- **文件**: `backend/src/modules/dc/tool-c/controllers/SessionController.ts` (300行)
- **功能**: 6个API端点
-`upload()` - POST /sessions/upload
- 接收multipart/form-data文件上传
- 调用SessionService.createSession()
- 返回201 + Session信息
-`getSession()` - GET /sessions/:id
- 获取Session元数据
- 检查过期
- 返回200 + Session信息
-`getPreviewData()` - GET /sessions/:id/preview
- 获取前100行数据
- 从OSS实时读取
- 返回200 + 预览数据
-`getFullData()` - GET /sessions/:id/full
- 获取完整数据
- 从OSS下载
- 返回200 + 完整数据
-`deleteSession()` - DELETE /sessions/:id
- 删除OSS文件
- 删除DB记录
- 返回200 + 成功信息
-`updateHeartbeat()` - POST /sessions/:id/heartbeat
- 延长过期时间
- 返回200 + 新过期时间
**错误处理**:
- Session不存在 → 404
- Session过期 → 404
- 服务器错误 → 500
- 参数错误 → 400
#### 任务3.2: 路由配置更新 ✅
- **文件**: `backend/src/modules/dc/tool-c/routes/index.ts` (62行)
- **新增路由**: 6个Session管理路由
- **路由前缀**: `/api/v1/dc/tool-c`
---
### 4. API测试验收
#### 测试数据
```javascript
// 8行 x 7列医疗数据
[
{ patient_id: 'P001', name: '张三', age: 25, gender: '男', diagnosis: '感冒', sbp: 120, dbp: 80 },
{ patient_id: 'P002', name: '李四', age: 65, gender: '女', diagnosis: '高血压', sbp: 150, dbp: 95 },
// ... 共8条记录
]
```
#### 测试结果7/7 通过)✅
**测试1: 上传文件创建Session**
- 请求POST /sessions/uploadmultipart
- 响应201 Created
- Session ID: `e7abe493-009d-4f97-8342-7a00c09c39fc`
- 数据验证:✅ 8行 x 7列 完全匹配
- 列名识别:✅ 7个列名全部正确
**测试2: 获取Session信息**
- 请求GET /sessions/:id
- 响应200 OK
- 返回数据:元数据完整(文件名、行数、列数、列名、过期时间)
**测试3: 获取预览数据**
- 请求GET /sessions/:id/preview
- 响应200 OK
- 返回数据前100行实际8行全部返回
- 数据完整性:✅ 中文字段正确解析
**测试4: 获取完整数据**
- 请求GET /sessions/:id/full
- 响应200 OK
- 从OSS读取✅ 正常
- 数据一致性:✅ 与上传数据完全一致
**测试5: 更新心跳**
- 请求POST /sessions/:id/heartbeat
- 响应200 OK
- 过期时间:✅ 延长10分钟
**测试6: 删除Session**
- 请求DELETE /sessions/:id
- 响应200 OK
- OSS文件✅ 删除成功
- DB记录✅ 删除成功
**测试7: 验证删除**
- 请求GET /sessions/:id已删除
- 响应404 Not Found
- 验证结果:✅ Session已正确删除
---
## 📂 新增文件清单
### 数据库
1. `backend/prisma/schema.prisma` - 新增DcToolCSession模型
2. `backend/prisma/migrations/create_tool_c_session.sql` - SQL迁移文件
3. `backend/scripts/create-tool-c-table.mjs` - 表创建脚本139行
### 服务层
4. `backend/src/modules/dc/tool-c/services/SessionService.ts` - 383行 ✅
5. `backend/src/modules/dc/tool-c/services/DataProcessService.ts` - 303行 ✅
### 控制器层
6. `backend/src/modules/dc/tool-c/controllers/SessionController.ts` - 300行 ✅
### 路由层
7. `backend/src/modules/dc/tool-c/routes/index.ts` - 更新62行 ✅
### 测试脚本
8. `backend/test-tool-c-day2.mjs` - 383行 ✅
### 文档
9. `docs/03-业务模块/DC-数据清洗整理/06-开发记录/2025-12-06_工具C_Day2开发完成总结.md` - 本文件
**新增代码总计**: ~1,900+ 行
---
## 🎯 核心功能实现
### 功能1: Excel文件上传 ✅
**流程**:
```
用户上传Excel → 文件验证 → 内存解析 → 上传OSS → 保存元数据到DB → 返回Session
```
**技术亮点**:
- ✅ 零落盘Excel全程内存处理
- ✅ OSS存储文件上传到云存储
- ✅ 元数据分离DB只存最小必要信息
**代码片段**:
```typescript
// 内存解析(不落盘)
const workbook = xlsx.read(fileBuffer, { type: 'buffer' });
const data = xlsx.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]);
// 上传到OSS
await storage.upload(fileKey, fileBuffer);
// 保存元数据到DB不存大数据
await prisma.dcToolCSession.create({ data: { userId, fileName, fileKey, ... } });
```
---
### 功能2: Session管理 ✅
**流程**:
```
创建Session → 10分钟过期 → 心跳延长 → 自动清理
```
**技术亮点**:
- ✅ 10分钟过期机制
- ✅ 心跳延长(前端定时发送)
- ✅ 自动清理过期Session
- ✅ 过期检查索引优化
**代码片段**:
```typescript
// 创建时设置过期时间
const expiresAt = new Date(Date.now() + 10 * 60 * 1000);
// 心跳延长
const newExpiresAt = new Date(Date.now() + 10 * 60 * 1000);
await prisma.dcToolCSession.update({
where: { id: sessionId },
data: { expiresAt: newExpiresAt }
});
// 清理过期Session
const expiredSessions = await prisma.dcToolCSession.findMany({
where: { expiresAt: { lt: new Date() } }
});
```
---
### 功能3: 数据获取(预览/完整)✅
**流程**:
```
前端请求 → 检查Session → 从OSS下载 → 内存解析 → 返回数据
```
**技术亮点**:
- ✅ 按需读取预览100行完整读取全部
- ✅ 内存解析:不落盘
- ✅ 缓存优化:前端可缓存预览数据
**代码片段**:
```typescript
async getPreviewData(sessionId: string) {
const session = await this.getSession(sessionId);
// 从OSS下载到内存
const buffer = await storage.download(session.fileKey);
// 内存解析
const workbook = xlsx.read(buffer, { type: 'buffer' });
const data = xlsx.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[0]]);
// 返回前100行
return { ...session, previewData: data.slice(0, 100) };
}
```
---
## 🔐 云原生规范遵守情况
### ✅ 必须遵守的规范100%符合)
| 规范 | 要求 | 实现 | 状态 |
|------|------|------|------|
| **文件存储** | 使用storage服务 | ✅ 所有文件上传到OSS | ✅ |
| **零落盘** | Excel内存解析 | ✅ xlsx.read(buffer) | ✅ |
| **日志系统** | 使用logger | ✅ 所有日志使用platform logger | ✅ |
| **数据库** | 使用全局prisma | ✅ import from config/database | ✅ |
| **禁止本地存储** | 无fs.writeFile | ✅ 无本地文件操作 | ✅ |
| **禁止硬编码** | 使用环境变量 | ✅ 所有配置可配置 | ✅ |
### 代码审查清单(通过)
- [x] 是否使用 `storage.upload()` 而非 `fs.writeFile()`
- [x] Excel 是否从内存解析,而非保存到本地? ✅
- [x] 是否使用全局 `prisma` 实例? ✅
- [x] 是否所有配置都从 `process.env` 读取? ✅
- [x] 是否使用 `logger` 而非 `console.log`
- [x] 所有 async 函数是否有 try-catch
- [x] 是否记录了详细错误日志? ✅
- [x] 是否返回了友好的错误信息? ✅
---
## 📈 代码质量指标
| 指标 | Day 1 | Day 2 | 增长 |
|------|-------|-------|------|
| **新增代码行数** | ~1,300 | ~1,900 | +46% |
| **API端点数** | 3个测试 | +6个正式 | +200% |
| **服务类数** | 1个 | +2个 | +200% |
| **控制器数** | 1个 | +1个 | +100% |
| **数据库表** | 0个 | +1个 | 新增 |
| **测试通过率** | 100% | 100% | 保持 |
---
## 🚀 API端点汇总Day 2更新
### Python微服务 (http://localhost:8000)
| 方法 | 端点 | 功能 | 状态 |
|------|------|------|------|
| GET | `/api/health` | 健康检查 | ✅ Day 1 |
| POST | `/api/dc/validate` | 代码验证 | ✅ Day 1 |
| POST | `/api/dc/execute` | 代码执行 | ✅ Day 1 |
### Node.js后端 (http://localhost:3000)
#### 测试端点Day 1
| 方法 | 端点 | 功能 | 状态 |
|------|------|------|------|
| GET | `/api/v1/dc/tool-c/test/health` | 测试Python服务 | ✅ |
| POST | `/api/v1/dc/tool-c/test/validate` | 测试代码验证 | ✅ |
| POST | `/api/v1/dc/tool-c/test/execute` | 测试代码执行 | ✅ |
#### Session管理端点Day 2
| 方法 | 端点 | 功能 | 状态 | 测试 |
|------|------|------|------|------|
| POST | `/api/v1/dc/tool-c/sessions/upload` | 上传Excel | ✅ | 201 |
| GET | `/api/v1/dc/tool-c/sessions/:id` | 获取Session | ✅ | 200 |
| GET | `/api/v1/dc/tool-c/sessions/:id/preview` | 获取预览 | ✅ | 200 |
| GET | `/api/v1/dc/tool-c/sessions/:id/full` | 获取完整 | ✅ | 200 |
| DELETE | `/api/v1/dc/tool-c/sessions/:id` | 删除Session | ✅ | 200 |
| POST | `/api/v1/dc/tool-c/sessions/:id/heartbeat` | 心跳更新 | ✅ | 200 |
---
## 🔍 技术难点解决
### 难点1: Prisma db push 冲突
**问题**: 执行`npx prisma db push`时提示要删除现有表
**原因**: Prisma Schema与数据库实际结构不同步
**解决方案**:
- 创建独立的Node.js脚本create-tool-c-table.mjs
- 使用`prisma.$executeRawUnsafe()`直接执行SQL
- 只创建Tool C的表不影响其他表
**代码**:
```javascript
await prisma.$executeRawUnsafe(`
CREATE TABLE dc_schema.dc_tool_c_sessions (...)
`);
```
**结果**: ✅ 表创建成功,无数据丢失
---
### 难点2: 路径别名导入失败
**问题**: `import { logger } from '@/common/logging'` 报错 `ERR_MODULE_NOT_FOUND`
**原因**: TSX在运行时不识别路径别名
**解决方案**: 使用相对路径导入
```typescript
// ❌ 错误
import { logger } from '@/common/logging';
// ✅ 正确
import { logger } from '../../../../common/logging/index.js';
```
**修复文件**:
- TestController.ts ✅
- PythonExecutorService.ts ✅
- SessionService.ts ✅
- DataProcessService.ts ✅
- SessionController.ts ✅
---
### 难点3: 零落盘架构设计
**问题**: 是否在DB存储previewData以提升性能
**分析**:
- 方案ADB存previewData → 性能好,但违反"零落盘"规范
- 方案B实时从OSS读取 → 性能稍差,但符合规范
**决策**: 方案B规范优先
- ✅ 遵守云原生规范
- ✅ DB存储量小
- ✅ 数据一致性强
- ⚠️ 每次预览需读OSS前端可缓存影响可控
---
## 📝 待办事项Day 3
### AI代码生成服务
- [ ] 创建 `AICodeService.ts`
- [ ] 集成LLMFactory
- [ ] 设计System Prompt10个Few-shot示例
- [ ] 实现AI与Python执行服务集成
- [ ] 添加自我修正机制
### AI控制器
- [ ] 创建 `AIController.ts`
- [ ] POST `/ai/chat` - AI对话
- [ ] POST `/ai/execute` - 执行AI代码
- [ ] GET `/ai/history/:sessionId` - 对话历史
### 测试场景
- [ ] 测试AI生成简单代码
- [ ] 测试AI生成医疗清洗代码
- [ ] 测试自我修正机制
- [ ] 端到端测试(上传 → AI处理 → 结果导出)
---
## 🎉 Day 2 总结
### 成果
-**Session管理完整实现**: 6个API端点7/7测试通过
-**零落盘架构**: 完全符合云原生规范
-**数据库集成**: 表创建成功,索引优化
-**OSS集成**: 文件上传/下载/删除正常
-**错误处理完善**: 所有异常场景都有处理
### 技术亮点
1. **零落盘架构**: Excel全程内存处理无临时文件
2. **按需加载**: 预览100行完整数据按需获取
3. **Session过期**: 10分钟自动过期心跳延长
4. **错误容错**: OSS删除失败不影响DB清理
5. **完整日志**: 所有操作都有结构化日志
### 开发效率
- **计划工时**: 5.5小时
- **实际工时**: ~5小时
- **任务完成率**: 100% (6/6)
- **代码质量**: 高(完整注释+测试)
- **测试通过率**: 100% (7/7)
### 下一步重点
1. 实现AI代码生成服务LLMFactory
2. 设计System Prompt10个Few-shot
3. 集成AI与Python执行
4. 端到端功能测试
---
**开发者**: AI Assistant
**审核状态**: ✅ 待用户验收
**下一步**: Day 3 - AI代码生成服务