Features - User Management (Phase 4.1): - Database: Add user_modules table for fine-grained module permissions - Database: Add 4 user permissions (view/create/edit/delete) to role_permissions - Backend: UserService (780 lines) - CRUD with tenant isolation - Backend: UserController + UserRoutes (648 lines) - 13 API endpoints - Backend: Batch import users from Excel - Frontend: UserListPage (412 lines) - list/filter/search/pagination - Frontend: UserFormPage (341 lines) - create/edit with module config - Frontend: UserDetailPage (393 lines) - details/tenant/module management - Frontend: 3 modal components (592 lines) - import/assign/configure - API: GET/POST/PUT/DELETE /api/admin/users/* endpoints Architecture Upgrade - Module Permission System: - Backend: Add getUserModules() method in auth.service - Backend: Login API returns modules array in user object - Frontend: AuthContext adds hasModule() method - Frontend: Navigation filters modules based on user.modules - Frontend: RouteGuard checks requiredModule instead of requiredVersion - Frontend: Remove deprecated version-based permission system - UX: Only show accessible modules in navigation (clean UI) - UX: Smart redirect after login (avoid 403 for regular users) Fixes: - Fix UTF-8 encoding corruption in ~100 docs files - Fix pageSize type conversion in userService (String to Number) - Fix authUser undefined error in TopNavigation - Fix login redirect logic with role-based access check - Update Git commit guidelines v1.2 with UTF-8 safety rules Database Changes: - CREATE TABLE user_modules (user_id, tenant_id, module_code, is_enabled) - ADD UNIQUE CONSTRAINT (user_id, tenant_id, module_code) - INSERT 4 permissions + role assignments - UPDATE PUBLIC tenant with 8 module subscriptions Technical: - Backend: 5 new files (~2400 lines) - Frontend: 10 new files (~2500 lines) - Docs: 1 development record + 2 status updates + 1 guideline update - Total: ~4900 lines of code Status: User management 100% complete, module permission system operational
24 KiB
24 KiB
Tool C 技术债务清单
创建日期: 2025-12-06
最后更新: 2025-12-06
当前版本: Day 3 MVP完成
优先级分级: P0-紧急 | P1-重要 | P2-中期优化 | P3-长期规划
📋 技术债务概览
| 编号 | 债务项 | 优先级 | 预计工时 | 影响范围 | 计划时间 |
|---|---|---|---|---|---|
| TD-C-001 | Python Session状态持久化 | P1 | 1天 | 稳定性 | Day 5-6 |
| TD-C-002 | 数据版本管理与回滚 | P2 | 2天 | 功能 | Week 3 |
| TD-C-003 | 大文件性能优化 | P2 | 1.5天 | 性能 | Week 3 |
| TD-C-004 | AI Prompt持续优化 | P1 | 持续 | 质量 | 持续 |
| TD-C-005 | 前端对话UI开发 | P0 | 3天 | 功能 | Day 4-5 |
| TD-C-006 | 复杂场景Prompt优化 | P2 | 0.5天 | 质量 | Day 4 |
🔴 P1: 重要(近期必做)
TD-C-001: Python Session状态持久化
当前问题:
# 当前实现:内存维护Session状态
session_data = {} # 存在内存中
# 问题:
# 1. Python服务重启 → Session数据丢失
# 2. 多实例部署 → 负载均衡会导致状态不一致
# 3. 无法回滚到历史版本
影响:
- 用户体验差:重启服务后需重新上传文件
- 无法云原生部署:不支持多实例
- 数据安全性:内存断电即丢失
优化方案:
方案A: Redis持久化(推荐)
# 使用Redis存储Session状态
import redis
import pickle
class SessionManager:
def __init__(self):
self.redis_client = redis.Redis(host='localhost', port=6379)
def save_session(self, session_id, dataframe):
# 序列化DataFrame
serialized = pickle.dumps(dataframe)
# 存储到Redis,10分钟过期
self.redis_client.setex(
f"session:{session_id}",
600, # 10分钟
serialized
)
def get_session(self, session_id):
data = self.redis_client.get(f"session:{session_id}")
if data:
return pickle.loads(data)
return None
方案B: OSS持久化
# 每次操作后保存到OSS
def save_to_oss(session_id, dataframe):
# 序列化为Parquet格式(高效)
buffer = io.BytesIO()
dataframe.to_parquet(buffer)
# 上传到OSS
oss_key = f"dc/tool-c/sessions/{session_id}/current.parquet"
oss_client.put_object(oss_key, buffer.getvalue())
实施计划:
- Day 5: 实现Redis集成
- Day 6: 测试与部署
TD-C-004: AI Prompt持续优化
当前问题:
- 10个Few-shot示例可能不够覆盖所有场景
- 某些复杂医疗场景AI理解不准确
- 代码生成质量依赖DeepSeek-V3性能
优化方向:
1. 扩展Few-shot库
# 当前:10个示例
# 目标:20-30个示例,分类存储
few_shot_library = {
"basic": [...], # 基础清洗(10个)
"medical": [...], # 医疗专业(10个)
"advanced": [...] # 高级分析(10个)
}
# 根据用户需求动态选择相关示例
def select_relevant_examples(user_message):
# 语义匹配最相关的5个示例
...
2. 用户反馈收集
# 记录AI生成失败的场景
failed_cases = []
# 定期分析,添加新示例
def analyze_failures():
# 找出高频失败场景
# 人工编写Few-shot
# 更新System Prompt
3. 多模型备选
# 主:DeepSeek-V3(性价比高)
# 备:GPT-4(质量高,成本高)
# 备:Claude-3.5(代码能力强)
if deepseek_fails:
retry_with_gpt4()
实施计划:
- 持续收集失败案例
- 每月优化1次Prompt
- 测试其他LLM模型
🟡 P2: 中期优化(1-2个月)
TD-C-002: 数据版本管理与回滚
当前问题:
- AI每次操作都直接修改当前数据
- 无法撤销/回滚到之前状态
- 无法对比不同版本
优化方案:
版本管理架构:
# 每次操作后保存快照
class DataVersionManager:
def save_version(self, session_id, dataframe, operation_desc):
version_id = str(uuid.uuid4())
# 保存到OSS(Parquet格式,压缩高效)
oss_key = f"dc/tool-c/sessions/{session_id}/versions/{version_id}.parquet"
dataframe.to_parquet(oss_key)
# 元数据存数据库
db.save({
"session_id": session_id,
"version_id": version_id,
"operation": operation_desc,
"timestamp": now(),
"row_count": len(dataframe),
"file_size": ...
})
def rollback(self, session_id, version_id):
# 从OSS恢复
dataframe = pd.read_parquet(oss_key)
return dataframe
前端展示:
// 版本历史列表
<Timeline>
<TimelineItem>
版本1: 上传原始文件 (100行)
</TimelineItem>
<TimelineItem>
版本2: 删除缺失值 (95行) [回滚]
</TimelineItem>
<TimelineItem>
版本3: 计算BMI (95行) [当前]
</TimelineItem>
</Timeline>
成本估算:
- 每个版本~1-5MB(Parquet压缩后)
- 10个版本 = 10-50MB
- OSS成本:¥0.01-0.05/Session
实施计划:
- Week 3: 后端版本管理
- Week 4: 前端UI + 测试
TD-C-003: 大文件性能优化
当前限制:
- 文件大小:10MB
- 行数限制:~50,000行
- 前端预览:100行
优化目标:
- 文件大小:50MB
- 行数限制:500,000行
- 前端预览:虚拟滚动
技术方案:
1. 流式处理
# 分块读取大文件
def process_large_file(file_path):
chunk_size = 10000 # 每次处理1万行
for chunk in pd.read_csv(file_path, chunksize=chunk_size):
# 分块处理
process_chunk(chunk)
2. Apache Arrow集成
# 使用Arrow高性能列式存储
import pyarrow as pa
import pyarrow.parquet as pq
# Node.js ↔ Python 数据传输
# 使用Arrow IPC格式(比JSON快10-100倍)
3. 前端虚拟滚动
// 使用AG Grid的虚拟滚动
<AgGridReact
rowModelType="infinite"
cacheBlockSize={100}
maxBlocksInCache={10}
/>
实施计划:
- Week 3: 流式处理 + Arrow
- Week 4: 前端虚拟滚动
🟡 P2: 中期优化(1-2个月)
TD-C-006: 复杂场景Prompt优化(Day 3测试遗留)
当前问题: Day 3测试中,2个复杂场景持续超时失败(3次重试都失败):
- 示例2:数值列清洗(creatinine列处理,包含
<0.1等特殊符号) - 示例7:智能去重(日期解析 + 排序 + 去重)
失败原因分析:
❌ 示例2失败: timeout of 60000ms exceeded
用户需求: 把creatinine列里的非数字符号去掉,<0.1按0.05处理,转为数值类型
问题:
- 需求描述复杂(3个子任务:去符号 + 特殊值处理 + 类型转换)
- AI理解不准确,生成的代码有逻辑错误
- 3次重试仍无法修正
❌ 示例7失败: timeout of 60000ms exceeded
用户需求: 按patient_id去重,保留check_date最新的记录
问题:
- 日期列可能包含多种格式
- 排序 + 去重的组合逻辑复杂
- AI生成的代码执行出错后难以自我修正
优化方案:
方案A: 增强Few-shot示例
# 为这两个场景添加更详细的Few-shot示例
### 示例: 复杂数值清洗(含特殊符号)
用户: 把肌酐列里的非数字符号(>、<)去掉,<0.1按0.05处理,转为数值
代码:
\`\`\`python
try:
# 第1步:去除符号
df['creatinine_clean'] = df['creatinine'].astype(str).str.replace('>', '').str.replace('<', '')
# 第2步:处理特殊值
df.loc[df['creatinine_clean'] == '0.1', 'creatinine_clean'] = '0.05'
# 第3步:转为数值
df['creatinine_numeric'] = pd.to_numeric(df['creatinine_clean'], errors='coerce')
print(f'清洗完成:{df["creatinine_numeric"].notna().sum()}个有效值')
except Exception as e:
print(f'错误: {e}')
\`\`\`
说明: 分步处理复杂清洗任务,先去符号,再处理特殊值,最后转类型
方案B: 优化System Prompt
## 复杂场景处理建议
1. **数值清洗**:分步处理(去符号 → 处理特殊值 → 类型转换)
2. **日期操作**:先用pd.to_datetime()统一格式,再排序去重
3. **调试输出**:每步打印中间结果,便于错误定位
4. **错误处理**:使用try-except包裹每个子步骤
方案C: 调整重试策略
// 针对特定错误类型,提供更明确的修正提示
if (error.includes('日期') || error.includes('datetime')) {
enhancedMessage = `${userMessage}
注意:日期列可能包含缺失值或格式不一致,请:
1. 使用 pd.to_datetime(df['date'], errors='coerce')
2. 删除日期为NaT的行
3. 再进行排序和去重`;
}
实施计划:
- Day 4: 实现方案A(增强Few-shot示例)
- Day 4: 实现方案B(优化System Prompt)
- Day 5: 测试优化效果(目标:通过率达到95%+)
预期效果:
- 通过率从81.8%提升到95%+
- 复杂场景一次成功率提升50%
- 用户体验改善(减少等待时间)
🟢 P3: 长期规划(3个月+)
TD-C-007: 医学专业功能增强
创建日期: 2025-12-08
来源: 医学统计分析专家审查反馈
优先级: P3(功能按钮MVP完成后优先实施)
背景: 当前工具C功能按钮开发计划(V1.0)主要面向通用数据清洗场景。医学专业审查发现,针对临床研究数据的特殊需求,需要增加以下专业功能。
7.1 异常值检测器(优先级:高)
医学背景:
- 临床数据常存在录入错误(如:年龄999岁、体重500kg)
- 仪器故障导致的异常读数
- 需符合临床范围的数据验证
功能设计:
┌─────────────────────────────────────┐
│ 异常值检测 │
├─────────────────────────────────────┤
│ 选择列:[血糖 ▼] │
│ │
│ 检测方法: │
│ ● 临床范围(推荐) │
│ 正常范围:[3.9___] - [6.1___] │
│ 来源:[ADA指南 ▼] │
│ │
│ ○ 统计学方法 │
│ IQR法(1.5倍四分位距) │
│ Z-score法(±3标准差) │
│ │
│ 处理方式: │
│ ○ 仅标记 ● 删除 ○ 替换为缺失 │
│ │
│ 检测到:23个异常值 │
│ [查看详情] │
│ │
│ [取消] [执行] │
└─────────────────────────────────────┘
实现要点:
- 内置常用临床范围(年龄0-120、BMI 10-80、血糖2-30等)
- 支持自定义范围
- 可视化异常值分布(箱线图)
7.2 单位转换器(优先级:高)
医学背景:
- 不同国家/医院使用不同单位
- 文献meta分析需要统一单位
- 常见转换错误导致数据不可用
功能设计:
┌─────────────────────────────────────┐
│ 医学单位转换 │
├─────────────────────────────────────┤
│ 选择列:[血糖 ▼] │
│ │
│ 当前单位:[mg/dL ▼] │
│ 目标单位:[mmol/L ▼] │
│ │
│ 常用转换: │
│ • 血糖: mg/dL ↔ mmol/L (÷18.018) │
│ • 血脂: mg/dL ↔ mmol/L │
│ • 体重: kg ↔ lb (×2.20462) │
│ • 身高: cm ↔ inch │
│ • 肌酐: mg/dL ↔ μmol/L │
│ │
│ ☑️ 创建新列 │
│ 新列名:[血糖_mmol_L_________] │
│ │
│ 预览:5.5 mg/dL → 0.31 mmol/L │
│ │
│ [取消] [执行] │
└─────────────────────────────────────┘
实现要点:
- 内置医学常用转换公式
- 支持批量转换
- 自动验证转换后的合理性
7.3 日期计算器(优先级:高)
医学背景:
- 计算年龄、随访时间、生存时间是高频需求
- 日期格式不统一(2025-01-01 vs 2025/1/1)
- 需要处理闰年、时间窗等复杂场景
功能设计:
┌─────────────────────────────────────┐
│ 日期/时间计算 │
├─────────────────────────────────────┤
│ 计算类型: │
│ ● 计算年龄(从出生日期) │
│ 出生日期列:[birth_date ▼] │
│ 参考日期:● 今天 ○ 指定列 │
│ 新列名:[年龄_________] │
│ │
│ ○ 计算时间间隔 │
│ 开始日期:[入院日期 ▼] │
│ 结束日期:[出院日期 ▼] │
│ 单位:[天 ▼](天/周/月/年) │
│ 新列名:[住院天数_____] │
│ │
│ ○ 判断时间窗(是否在X天内) │
│ 事件日期:[随访日期 ▼] │
│ 基线日期:[入组日期 ▼] │
│ 时间窗:[30____] 天内 │
│ 新列名:[30天内随访____] │
│ │
│ [取消] [预览] [执行] │
└─────────────────────────────────────┘
实现要点:
- 自动检测日期格式
- 处理缺失日期
- 支持多种时间单位
7.4 临床截断值分箱(优先级:中)
医学背景:
- 医学分类应基于循证医学证据(如:WHO、ADA指南)
- 任意分箱会损失信息且无临床意义
- 需要可追溯的分类标准
功能改进:
在现有"生成分类变量"功能中增加:
┌─────────────────────────────────────┐
│ 连续变量分箱 │
├─────────────────────────────────────┤
│ 选择数值列:[BMI ▼] │
│ │
│ 分箱方式: │
│ ● 临床截断值(推荐)⭐ │
│ 标准:[WHO标准 ▼] │
│ <18.5: 低体重 │
│ 18.5-24.9: 正常 │
│ 25-29.9: 超重 │
│ ≥30: 肥胖 │
│ 参考:WHO 2000 │
│ │
│ [切换为中国标准 ▼] │
│ │
│ ○ 自定义切点(需注明依据) │
│ ○ 等宽/等频分箱(⚠️会损失信息) │
│ │
│ [取消] [预览分布] [执行] │
└─────────────────────────────────────┘
支持的临床标准:
- BMI分类:WHO、中国成人、儿童标准
- 血压分级:ESH/ESC高血压指南
- 肾功能分期:KDIGO CKD分期
- 年龄分组:WHO标准、临床试验常用
- 血糖分类:ADA糖尿病诊断标准
实现要点:
- 内置10+常用临床标准
- 可导出分类依据(供论文写作)
- 提示等宽分箱的局限性
7.5 高级缺失值填补(优先级:中)
医学背景:
- MICE假设数据MAR(随机缺失),但临床数据常为MNAR(非随机缺失)
- 病情严重患者更易失访(缺失非随机)
- 需要敏感性分析
功能改进:
在现有"缺失值填补"功能中增加:
┌─────────────────────────────────────┐
│ 缺失值填补(医学专用) │
├─────────────────────────────────────┤
│ 选择列:[FMA评分 ▼] [+] │
│ │
│ 填补方法: │
│ ● 末次观测值结转(LOCF)⭐ │
│ 适用:纵向数据,假设无变化 │
│ │
│ ○ 基线观测值结转(BOCF) │
│ 适用:保守估计,假设无改善 │
│ │
│ ○ 最坏情况插补(Worst Case) │
│ 适用:敏感性分析 │
│ 最坏值:[0____] │
│ │
│ ○ 中位数/均值填补 │
│ ☑️ 按分组填补 │
│ 分组列:[性别▼][年龄组▼] │
│ │
│ ○ 多重插补(MICE) │
│ ⚠️ 假设数据MAR,需检验适用性 │
│ │
│ 预览:将填补 32 个缺失值 │
│ │
│ [取消] [敏感性分析] [执行] │
└─────────────────────────────────────┘
实现要点:
- 明确各方法的适用前提
- 提供敏感性分析(对比不同方法结果)
- 生成填补报告(供论文方法学描述)
7.6 Codebook(数据字典)生成(优先级:中)
医学背景:
- GCP(药物临床试验质量管理规范)要求可追溯性
- 期刊要求提供数据字典
- 伦理审查需要变量说明
功能设计:
自动生成数据字典:
┌──────────────────────────────────────┐
│ 变量名 │ 原变量 │ 编码规则 │ 创建时间│
├────────┼────────┼──────────┼─────────┤
│研究中心│研究中心│1=黑龙江 │12-08 │
│_编码 │ │2=山东 │10:30 │
│ │ │3=广州 │ │
├────────┼────────┼──────────┼─────────┤
│BMI分类 │BMI │1=正常 │12-08 │
│ │ │2=超重 │10:35 │
│ │ │3=肥胖 │ │
│ │ │参考:WHO │ │
└────────┴────────┴──────────┴─────────┘
导出选项:
- Excel格式(常用)
- Word格式(伦理报告)
- CSV格式(SPSS导入)
实现要点:
- 每次重编码/分箱自动更新
- 记录操作人和时间
- 支持手动添加注释
7.7 样本筛选流程图(优先级:低)
医学背景:
- CONSORT声明要求报告筛选流程
- 期刊审稿要求提供流程图
- 有助于发现筛选逻辑错误
功能设计:
在"高级筛选"功能中增加:
自动生成筛选流程:
┌──────────────────────┐
│ 原始数据: 1000例 │
└──────┬───────────────┘
│
↓ 排除年龄<18岁
┌──────────────────────┐
│ 剩余: 950例 (-50) │
└──────┬───────────────┘
│
↓ 排除主要结局缺失
┌──────────────────────┐
│ 剩余: 920例 (-30) │
└──────┬───────────────┘
│
↓ 排除重复记录
┌──────────────────────┐
│ 最终纳入: 910例 │
└──────────────────────┘
[导出为图片] [导出为Word]
实现要点:
- 记录每步筛选的条件和结果
- 生成可发表的流程图
- 支持导出为高分辨率图片
7.8 数据质量报告(优先级:低)
医学背景:
- 数据质量直接影响研究结论
- 需要在分析前进行质量评估
- 期刊要求描述数据质量
功能设计:
点击"生成数据质量报告":
生成PDF报告,包含:
1. 数据概况
- 样本量、变量数
- 数据收集时间跨度
2. 完整性分析
- 各变量缺失率
- 缺失模式(MCAR/MAR/MNAR检验)
3. 一致性检查
- 逻辑错误(如:出生日期>死亡日期)
- 重复记录
4. 分布分析
- 连续变量分布(直方图+Q-Q图)
- 分类变量频数表
5. 异常值检测
- 箱线图
- 异常值列表
6. 建议操作
- 需要处理的问题清单
- 优先级排序
实现要点:
- 自动生成可发表的表格/图
- 支持导出为Word/PDF
- 符合临床研究报告规范
实施计划
| 功能 | 优先级 | 预计工时 | 计划时间 |
|---|---|---|---|
| 7.1 异常值检测器 | 高 | 2天 | Phase 4 |
| 7.2 单位转换器 | 高 | 1.5天 | Phase 4 |
| 7.3 日期计算器 | 高 | 2天 | Phase 4 |
| 7.4 临床截断值分箱 | 中 | 1天 | Phase 3增强 |
| 7.5 高级缺失值填补 | 中 | 1.5天 | Phase 3增强 |
| 7.6 Codebook生成 | 中 | 1天 | Phase 5 |
| 7.7 筛选流程图 | 低 | 1.5天 | Phase 5 |
| 7.8 数据质量报告 | 低 | 2天 | Phase 5 |
总计:12.5天工时
TD-C-008: 自定义函数库
愿景: 用户可保存常用代码为函数,一键复用
# 用户保存的自定义函数
my_functions = {
"血压分类": "df['bp_category'] = ...",
"年龄分组": "df['age_group'] = ...",
}
# 一键应用
apply_function("血压分类")
TD-C-009: 协作功能
愿景: 多人协作数据清洗
- 权限管理:查看/编辑/审核
- 操作日志:谁在什么时候做了什么
- 评论功能:对特定操作添加备注
TD-C-010: AI智能推荐
愿景: AI主动检测数据问题并推荐操作
quality_check = {
"发现23个异常值": "建议使用异常值检测器",
"年龄列缺失32%": "建议使用LOCF填补",
"BMI未分类": "建议使用WHO标准分箱",
}
📊 债务统计
按优先级
- P0: 1项(前端UI,阻塞发布)
- P1: 2项(Session持久化、Prompt优化)
- P2: 3项(版本管理、大文件、复杂场景优化)
- P3: 4项(长期规划 + 医学专业功能增强)
按工时
- 0.5天: 1项(复杂场景优化)
- 1天: 1项(Session持久化)
- 1-2天: 2项(版本管理、大文件)
- 3天以上: 1项(前端UI)
- 持续优化: 1项(Prompt优化)
- 医学专业功能: 12.5天(8个子功能)
总计
- 技术债务总数: 13项(含医学专业功能8个子项)
- 近期必做: 4项(P0-P1 + 复杂场景)
- 预计总工时: ~23-25天
- MVP相关:~10.5-12.5天
- 医学专业增强:~12.5天
🔄 更新记录
| 日期 | 版本 | 更新内容 | 更新人 |
|---|---|---|---|
| 2025-12-08 | V1.2 | 新增TD-C-007(医学专业功能增强8项) | AI Assistant |
| 2025-12-07 | V1.1 | 新增TD-C-006(复杂场景Prompt优化) | AI Assistant |
| 2025-12-06 | V1.0 | 初始创建,Day 3 MVP完成后梳理 | AI Assistant |
文档状态: ✅ 已更新
下次更新: Phase 4开发完成后