feat(admin): Add user management and upgrade to module permission system
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
This commit is contained in:
@@ -1,65 +1,65 @@
|
||||
# 蜈ィ譁<EFBFBD>、咲ュ帛シ蜿題ョー蠖?- Day 2 & Day 3
|
||||
# 全文复筛开发记录 - Day 2 & Day 3
|
||||
|
||||
**譌・譛<EFBFBD>**: 2025蟷?1譛?2譌?
|
||||
**蠑蜿鷹亳谿?*: MVP譬ク蠢<EFBDB8>粥閭ス蠑蜿?
|
||||
**雍溯エ」莠?*: AI Assistant
|
||||
**迥カ諤?*: 笨?蟾イ螳梧<E89EB3>?
|
||||
**日期**: 2025年11月22日
|
||||
**开发阶段**: MVP核心功能开发
|
||||
**负责人**: AI Assistant
|
||||
**状态**: ✅ 已完成
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>搭 蠑蜿第ヲりァ?
|
||||
## 📋 开发概览
|
||||
|
||||
譛ャ谺。蠑蜿大ョ梧<EFBFBD>莠<EFBFBD><EFBFBD>譁<EFBFBD>、咲ュ帷噪譬ク蠢キLM譛榊苅蜥碁ェ瑚ッ∫ウサ扈滂シ梧カオ逶縫ay 2蜥轡ay 3逧<EFBFBD>園譛芽ョ。蛻剃ササ蜉。<EFBFBD>悟ケカ霑幄。御コ<EFBFBD><EFBFBD>髱「逧<EFBFBD>寔謌先オ玖ッ募柱髣ョ鬚倅ソョ螟阪?
|
||||
本次开发完成了全文复筛的核心LLM服务和验证系统,涵盖Day 2和Day 3的所有计划任务,并进行了全面的集成测试和问题修复。
|
||||
|
||||
---
|
||||
|
||||
## 笨?蟾イ螳梧<E89EB3>蜉溯<E89C89>?
|
||||
## ✅ 已完成功能
|
||||
|
||||
### Day 2: LLM 12字段服务
|
||||
|
||||
#### 2.1 謠千、コ隸榊キ・遞倶ス鍋ウ?
|
||||
#### 2.1 提示词工程体系
|
||||
|
||||
**核心文件**:
|
||||
- `backend/src/modules/asl/fulltext-screening/prompts/system_prompt.md` (6,601字符)
|
||||
- 9000+字详细System Prompt
|
||||
- Section-Aware遲也払<EFBFBD>?豁・螟<EFBDA5>炊豕包シ?
|
||||
- Section-Aware策略(4步处理法)
|
||||
- Lost in the Middle现象缓解
|
||||
- 閾ェ鬪瑚ッ∵惻蛻カ<EFBFBD><EFBFBD>elf-Verification<EFBFBD>?
|
||||
- 自验证机制(Self-Verification)
|
||||
- Chain-of-Thought引导
|
||||
|
||||
- `backend/src/modules/asl/fulltext-screening/prompts/user_prompt_template.md` (199陦?
|
||||
- PICOS荳贋ク区枚豕ィ蜈?
|
||||
- `backend/src/modules/asl/fulltext-screening/prompts/user_prompt_template.md` (199行)
|
||||
- PICOS上下文注入
|
||||
- 文档格式自适应
|
||||
- 蛻<EFBFBD>ォ<EFBFBD>闃よ署蜿匁欠蠑?
|
||||
- 分章节提取指引
|
||||
|
||||
- `backend/src/modules/asl/fulltext-screening/prompts/json_schema.json`
|
||||
- 荳・譬シ逧?2蟄玲ョオJSON Schema
|
||||
- 譛蟆丞シ慕畑髟ソ蠎ヲ郤ヲ譚滂シ遺<EFBFBD>?0蟄礼ャヲ<EFBDAC>?
|
||||
- 严格的12字段JSON Schema
|
||||
- 最小引用长度约束(≥50字符)
|
||||
- 必需字段:processing_log、verification
|
||||
|
||||
**Cochrane譬<EFBFBD>㊥**<EFBFBD><EFBFBD>VP證ゆク榊刈霓ス<EFBFBD>?
|
||||
- `prompts/cochrane_standards/髫乗惻蛹匁婿豕?md`
|
||||
**Cochrane标准**(MVP暂不加载):
|
||||
- `prompts/cochrane_standards/随机化方法.md`
|
||||
- `prompts/cochrane_standards/盲法.md`
|
||||
- `prompts/cochrane_standards/扈捺棡螳梧紛諤?md`
|
||||
- `prompts/cochrane_standards/结果完整性.md`
|
||||
|
||||
**Few-shot Examples**<EFBFBD>亥キイ遘サ髯、莉・莨伜喧Prompt髟ソ蠎ヲ<EFBFBD>?
|
||||
- ~~`prompts/few_shot_examples/菫。諱ッ蝨ィ荳ュ髣エ菴咲スョ譯井セ?md`~~ (蟾イ蛻<EFBFBD>髯?
|
||||
**Few-shot Examples**(已移除以优化Prompt长度):
|
||||
- ~~`prompts/few_shot_examples/信息在中间位置案例.md`~~ (已删除)
|
||||
|
||||
**设计决策**:
|
||||
- 笨?菫晉蕗System Prompt蜥袈ser Prompt蜴溷ァ狗沿譛ャ<EFBFBD>域悴邊セ邂<EFBFBD>?
|
||||
- 笨?遘サ髯、Few-shot examples莉・蜃丞ー善rompt髟ソ蠎ヲ<EFBFBD>井サ<EFBFBD>74KB髯崎<EFBFBD>52KB<EFBFBD>?
|
||||
- 笨?MVP髦カ谿オ荳榊刈霓スCochrane譬<EFBFBD>㊥<EFBFBD>亥㍼蟆善rompt髟ソ蠎ヲ縲<EFBFBD>剄菴取<EFBFBD>譛ャ<EFBFBD><EFBFBD>
|
||||
- ✅ 保留System Prompt和User Prompt原始版本(未精简)
|
||||
- ✅ 移除Few-shot examples以减少Prompt长度(从74KB降至52KB)
|
||||
- ✅ MVP阶段不加载Cochrane标准(减少Prompt长度、降低成本)
|
||||
|
||||
#### 2.2 PromptBuilder服务
|
||||
|
||||
**譁<EFBFBD>サカ**: `backend/src/modules/asl/common/llm/PromptBuilder.ts` (275陦?
|
||||
**文件**: `backend/src/modules/asl/common/llm/PromptBuilder.ts` (275行)
|
||||
|
||||
**核心功能**:
|
||||
- 动态组装System Prompt和User Prompt
|
||||
- 可选加载Cochrane标准
|
||||
- 可选加载Few-shot examples
|
||||
- 扈捺棡郛灘ュ假シ亥㍼蟆第枚莉カI/O<EFBFBD>?
|
||||
- 讓。譚ソ蜿倬㍼譖ソ謐「<EFBFBD><EFBFBD>ICOS縲∫コウ蜈?謗帝勁譬<E58B81>㊥<EFBFBD>?
|
||||
- 结果缓存(减少文件I/O)
|
||||
- 模板变量替换(PICOS、纳入/排除标准)
|
||||
|
||||
**MVP配置**:
|
||||
```typescript
|
||||
@@ -70,33 +70,33 @@ const DEFAULT_MVP_CONFIG = {
|
||||
```
|
||||
|
||||
**修复问题**:
|
||||
- 笨?菫ョ螟<EFBDAE> `__dirname` 蝨ィES讓。蝮嶺クュ逧<EFBFBD>スソ逕ィ<EFBFBD>域隼逕?`fileURLToPath`<EFBFBD>?
|
||||
- 笨?菫ョ螟肴枚莉カ霍ッ蠕<EFBDAF>漠隸ッ<E99AB8><EFBDAF>src/modules/modules/asl` 竊?`src/modules/asl`<EFBFBD>?
|
||||
- 笨?豺サ蜉<EFBDBB> `.js` 謇ゥ螻募錐莉・隨ヲ蜷<EFBFBD>S讓。蝮苓ァ<EFBFBD>激
|
||||
- ✅ 修复 `__dirname` 在ES模块中的使用(改用 `fileURLToPath`)
|
||||
- ✅ 修复文件路径错误(`src/modules/modules/asl` → `src/modules/asl`)
|
||||
- ✅ 添加 `.js` 扩展名以符合ES模块规范
|
||||
|
||||
#### 2.3 LLM12FieldsService核心服务
|
||||
|
||||
**譁<EFBFBD>サカ**: `backend/src/modules/asl/common/llm/LLM12FieldsService.ts` (547陦?
|
||||
**文件**: `backend/src/modules/asl/common/llm/LLM12FieldsService.ts` (547行)
|
||||
|
||||
**核心功能**:
|
||||
1. **Nougat优先提取策略**
|
||||
- 闍ア譁⑰DF莨伜<EFBFBD>菴ソ逕ィNougat<EFBFBD>育サ捺桷蛹邦arkdown<EFBFBD>?
|
||||
- 雍ィ驥乗」譟?+ PyMuPDF髯咲コァ
|
||||
- 英文PDF优先使用Nougat(结构化Markdown)
|
||||
- 质量检查 + PyMuPDF降级
|
||||
- 支持中文PDF直接使用PyMuPDF
|
||||
|
||||
2. **蜿梧ィ。蝙句ケカ陦瑚ー<EFBFBD><EFBFBD>?*
|
||||
2. **双模型并行调用**
|
||||
- DeepSeek-V3 + Qwen-Max
|
||||
- 使用 `Promise.allSettled` 实现容错
|
||||
- 荳荳ェ讓。蝙句、ア雍・荳榊スア蜩榊嘗荳荳?
|
||||
- 一个模型失败不影响另一个
|
||||
|
||||
3. **3层JSON解析策略**(关键创新)
|
||||
```typescript
|
||||
Layer 1: 严格 JSON.parse()
|
||||
Layer 2: json-repair 閾ェ蜉ィ菫ョ螟搾シ亥、<EFBFBD>炊蟶ク隗´LM譬シ蠑城漠隸ッ<EFBFBD>?
|
||||
Layer 2: json-repair 自动修复(处理常见LLM格式错误)
|
||||
Layer 3: 提取Markdown代码块中的JSON
|
||||
```
|
||||
- 成功率:100%(测试验证)
|
||||
- 閾ェ蜉ィ螟<EFBFBD>炊LLM霎灘<EFBFBD>逧<EFBFBD>推遘肴<EFBFBD>シ蠑城琉鬚?
|
||||
- 自动处理LLM输出的各种格式问题
|
||||
|
||||
4. **模型名称映射**
|
||||
```typescript
|
||||
@@ -105,7 +105,7 @@ const DEFAULT_MVP_CONFIG = {
|
||||
'qwen-max': 'qwen3-72b',
|
||||
};
|
||||
```
|
||||
- 隗」蜀ウ逕ィ謌キ蜿句・ス蜷咲ァー荳主<EFBFBD>驛ィModelType逧<EFBFBD>丐蟆<EFBFBD>琉鬚?
|
||||
- 解决用户友好名称与内部ModelType的映射问题
|
||||
|
||||
5. **结果缓存**
|
||||
- 基于内容哈希的缓存键
|
||||
@@ -115,63 +115,63 @@ const DEFAULT_MVP_CONFIG = {
|
||||
6. **成本计算**
|
||||
- 中英文混合Token估算
|
||||
- 实时成本跟踪
|
||||
- 騾乗<EFBFBD>逧<EFBFBD>エケ逕ィ扈溯ョ?
|
||||
- 透明的费用统计
|
||||
|
||||
**修复问题**:
|
||||
- 笨?菫ョ螟広LM譁ケ豕戊ー<E6888A>畑<EFBFBD><E79591>generateText` 竊?`chat`<EFBFBD>?
|
||||
- 笨?菫ョ螟広LMFactory蟇シ蜈・霍ッ蠕<EFBDAF>
|
||||
- 笨?豺サ蜉<EFBDBB>MODEL_NAME_MAP隗」蜀ウ讓。蝙狗アサ蝙倶ク榊源驟?
|
||||
- 笨?螳樒鴫3螻<33>SON隗」譫千ュ也払菫ョ螟崎ァ」譫宣漠隸ッ
|
||||
- 笨?謾ケ逕ィPromise.allSettled蠅槫シコ蜿梧ィ。蝙句ョケ髞?
|
||||
- ✅ 修复LLM方法调用(`generateText` → `chat`)
|
||||
- ✅ 修复LLMFactory导入路径
|
||||
- ✅ 添加MODEL_NAME_MAP解决模型类型不匹配
|
||||
- ✅ 实现3层JSON解析策略修复解析错误
|
||||
- ✅ 改用Promise.allSettled增强双模型容错
|
||||
|
||||
**諤ァ閭ス謖<EFBFBD><EFBFBD><EFBFBD>**<EFBFBD>亥黒遽⑰DF豬玖ッ包シ?
|
||||
- 諤サ閠玲慮<E78EB2>?62遘?
|
||||
- DeepSeek-V3<EFBFBD>?3,404 tokens<EFBFBD>個?.0234
|
||||
- Qwen-Max<EFBFBD>?8,464 tokens<EFBFBD>個?.0739
|
||||
**性能指标**(单篇PDF测试):
|
||||
- 总耗时:262秒
|
||||
- DeepSeek-V3:23,404 tokens,¥0.0234
|
||||
- Qwen-Max:18,464 tokens,¥0.0739
|
||||
- 总成本:¥0.0973
|
||||
|
||||
---
|
||||
|
||||
### Day 3: 鬪瑚ッ∵恪蜉。 + 蜀イ遯∵」豬?
|
||||
### Day 3: 验证服务 + 冲突检测
|
||||
|
||||
#### 3.1 MedicalLogicValidator - 医学逻辑验证
|
||||
|
||||
**譁<EFBFBD>サカ**: `backend/src/modules/asl/common/validation/MedicalLogicValidator.ts` (413陦?
|
||||
**文件**: `backend/src/modules/asl/common/validation/MedicalLogicValidator.ts` (413行)
|
||||
|
||||
**核心功能**:
|
||||
- 5条医学逻辑规则验证
|
||||
1. RCT研究必须有随机化方法
|
||||
2. 逶イ豕穂ク守<EFBDB8>皮ゥカ隶セ隶。荳閾エ諤?
|
||||
3. 扈灘ア謖<C280><E8AC96><EFBFBD>ク守サ捺棡螳梧紛諤ァ荳閾エ諤?
|
||||
4. 扈溯ョ。譁ケ豕穂ク守<EFBDB8>皮ゥカ隶セ隶。蛹ケ驟?
|
||||
5. 蝓コ郤ソ蜿ッ豈疲ァ荳朱囂譛コ蛹門<E89BB9>邉?
|
||||
2. 盲法与研究设计一致性
|
||||
3. 结局指标与结果完整性一致性
|
||||
4. 统计方法与研究设计匹配
|
||||
5. 基线可比性与随机化关系
|
||||
|
||||
**容错增强**:
|
||||
```typescript
|
||||
safeGetFieldValue(fieldData: any): string {
|
||||
// 处理 null/undefined
|
||||
// 螟<EFBFBD>炊蟇ケ雎。邀サ蝙具シ域署蜿紡ssessment蟄玲ョオ<EFBFBD>?
|
||||
// 螟<EFBFBD>炊蟄礼ャヲ荳イ邀サ蝙?
|
||||
// 霑泌屓遨コ蟄礼ャヲ荳イ菴應クコ鮟倩ョ、蛟?
|
||||
// 处理对象类型(提取assessment字段)
|
||||
// 处理字符串类型
|
||||
// 返回空字符串作为默认值
|
||||
}
|
||||
```
|
||||
- 笨?謇譛芽ァ<E88ABD><EFBDA7>菴ソ逕?`safeGetFieldValue` 謠仙叙蟄玲ョオ蛟?
|
||||
- 笨?莨倬寉螟<E5AF89>炊LLM霎灘<E99C8E>逧<EFBFBD>推遘肴焚謐ョ扈捺<E68988>?
|
||||
- ✅ 所有规则使用 `safeGetFieldValue` 提取字段值
|
||||
- ✅ 优雅处理LLM输出的各种数据结构
|
||||
|
||||
**测试结果**:
|
||||
- DeepSeek-V3: 笨?5/5 騾夊ソ<EFBFBD>
|
||||
- Qwen-Max: 笨?5/5 騾夊ソ<EFBFBD>
|
||||
- DeepSeek-V3: ✅ 5/5 通过
|
||||
- Qwen-Max: ✅ 5/5 通过
|
||||
|
||||
#### 3.2 EvidenceChainValidator - 隸∵紺體セ鬪瑚ッ?
|
||||
#### 3.2 EvidenceChainValidator - 证据链验证
|
||||
|
||||
**譁<EFBFBD>サカ**: `backend/src/modules/asl/common/validation/EvidenceChainValidator.ts` (464陦?
|
||||
**文件**: `backend/src/modules/asl/common/validation/EvidenceChainValidator.ts` (464行)
|
||||
|
||||
**核心功能**:
|
||||
- 鬪瑚ッ∵ッ丈クェ蟄玲ョオ逧<EFBDB5>ッ∵紺體セ螳梧紛諤?
|
||||
- 蜴滓枚蠑慕畑髟ソ蠎ヲ<E8A08E>遺翁50蟄礼ャヲ<EFBDAC>?
|
||||
- 蠑慕畑菴咲スョ譛画譜諤?
|
||||
- 螟<>炊譌・蠢怜ョ梧紛諤?
|
||||
- 閾ェ鬪瑚ッ∬ョー蠖募ョ梧紛諤?
|
||||
- 验证每个字段的证据链完整性
|
||||
- 原文引用长度(≥50字符)
|
||||
- 引用位置有效性
|
||||
- 处理日志完整性
|
||||
- 自验证记录完整性
|
||||
|
||||
**容错增强**:
|
||||
```typescript
|
||||
@@ -180,34 +180,34 @@ if (!fields || typeof fields !== 'object') {
|
||||
return validationResult;
|
||||
}
|
||||
```
|
||||
- 笨?螳牙<E89EB3>螟<EFBFBD>炊 `undefined`/`null` fields
|
||||
- 笨?驕ソ蜈<EFBDBF> `Object.entries()` 蟠ゥ貅<EFBDA9>
|
||||
- ✅ 安全处理 `undefined`/`null` fields
|
||||
- ✅ 避免 `Object.entries()` 崩溃
|
||||
|
||||
**测试结果**:
|
||||
- DeepSeek-V3: 笞<EFBFBD><EFBFBD><EFBFBD> 荳榊ョ梧紛<E6A2A7><E7B49B>ields荳コundefined<EFBFBD>悟キイ螳ケ髞呻シ?
|
||||
- Qwen-Max: 笨?12/12 蟄玲ョオ螳梧紛
|
||||
- DeepSeek-V3: ⚠️ 不完整(fields为undefined,已容错)
|
||||
- Qwen-Max: ✅ 12/12 字段完整
|
||||
|
||||
#### 3.3 ConflictDetectionService - 蜀イ遯∵」豬?
|
||||
#### 3.3 ConflictDetectionService - 冲突检测
|
||||
|
||||
**譁<EFBFBD>サカ**: `backend/src/modules/asl/common/validation/ConflictDetectionService.ts` (432陦?
|
||||
**文件**: `backend/src/modules/asl/common/validation/ConflictDetectionService.ts` (432行)
|
||||
|
||||
**核心功能**:
|
||||
1. **蟄玲ョオ郤ァ蜀イ遯∵」豬?*
|
||||
- 蟇ケ豈比ク、荳ェ讓。蝙狗<E89D99>?2蟄玲ョオ隸<EFBDB5>シー扈捺棡
|
||||
1. **字段级冲突检测**
|
||||
- 对比两个模型的12字段评估结果
|
||||
- 识别评估不一致的字段
|
||||
|
||||
2. **关键字段识别**
|
||||
- 蜈ウ髞ョ蟄玲ョオ<EFBDAE>夐囂譛コ蛹匁婿豕輔∫峇豕輔∫サ捺棡螳梧紛諤?
|
||||
- 驥崎ヲ∝ュ玲ョオ<EFBDAE>壻ココ鄒、迚ケ蠕√∝ケイ鬚<EFBDB2>蒔譁ス縲∝ッケ辣ァ謗ェ譁ス縲∫サ灘ア謖<C280><E8AC96><EFBFBD>∫サ溯ョ。譁ケ豕?
|
||||
- 关键字段:随机化方法、盲法、结果完整性
|
||||
- 重要字段:人群特征、干预措施、对照措施、结局指标、统计方法
|
||||
- 普通字段:其他字段
|
||||
|
||||
3. **严重程度分级**
|
||||
- High: 关键字段冲突或总体决策冲突
|
||||
- Medium: 重要字段冲突
|
||||
- Low: 莉<EFBFBD>勸騾壼ュ玲ョオ蜀イ遯?
|
||||
- Low: 仅普通字段冲突
|
||||
|
||||
4. **螟肴<EFBFBD>ク莨伜<EFBFBD>郤ァ隶。邂?*
|
||||
- 蝓コ莠主<E88EA0>遯∽ク・驥咲ィ句コヲ縲∝ュ玲ョオ謨ー驥?
|
||||
4. **复核优先级计算**
|
||||
- 基于冲突严重程度、字段数量
|
||||
- 0-100分制
|
||||
- 自动计算建议复核截止时间
|
||||
|
||||
@@ -218,13 +218,13 @@ if (!fieldsA || typeof fieldsA !== 'object') {
|
||||
return { conflictFields: [], fieldConflictDetails: [] };
|
||||
}
|
||||
```
|
||||
- 笨?螳牙<E89EB3>螟<EFBFBD>炊 `undefined`/`null` fields
|
||||
- 笨?菫ョ螟<EFBDAE> logger 隹<EFBFBD>畑<EFBFBD><EFBFBD>this.logger` 竊?`logger`<60>?
|
||||
- ✅ 安全处理 `undefined`/`null` fields
|
||||
- ✅ 修复 logger 调用(`this.logger` → `logger`)
|
||||
|
||||
**测试结果**:
|
||||
- 笨?謌仙粥譽豬句<E8B1AC>遯<EFBFBD>シ<EFBFBD>ndefined vs 豁」蟶クfields<EFBFBD>?
|
||||
- 笨?螳ケ髞呎惻蛻カ蟾・菴懈ュ」蟶ク
|
||||
- 笨?荳榊<E88DB3>蟠ゥ貅<EFBDA9>
|
||||
- ✅ 成功检测冲突(undefined vs 正常fields)
|
||||
- ✅ 容错机制工作正常
|
||||
- ✅ 不再崩溃
|
||||
|
||||
---
|
||||
|
||||
@@ -235,34 +235,34 @@ if (!fieldsA || typeof fieldsA !== 'object') {
|
||||
1. **`__tests__/integration-test.ts`** (完整集成测试)
|
||||
- 测试2-3篇真实PDF
|
||||
- 完整LLM调用流程
|
||||
- 閠玲慮<E78EB2>夐「<E5A490>ョ?-10蛻<30>帖
|
||||
- 耗时:预计5-10分钟
|
||||
|
||||
2. **`__tests__/quick-test.ts`** (蠢ォ騾滓オ玖ッ?
|
||||
2. **`__tests__/quick-test.ts`** (快速测试)
|
||||
- 测试1篇PDF
|
||||
- 邂豢∬セ灘<EFBDBE>?
|
||||
- 简洁输出
|
||||
- 耗时:约3分钟
|
||||
|
||||
3. **`__tests__/cached-result-test.ts`** (容错验证)
|
||||
- 逶エ謗・豬玖ッ暮ェ瑚ッ∝<EFBDAF>?
|
||||
- 直接测试验证器
|
||||
- 模拟各种异常输出
|
||||
- 秒级完成
|
||||
|
||||
### 测试结果总结
|
||||
|
||||
**笨?3螻<33>SON隗」譫千ュ也払鬪瑚ッ<E7919A>**:
|
||||
- Qwen-Max: Layer 2閾ェ蜉ィ菫ョ螟搾シ井ソョ螟?0蟄苓鰍譬シ蠑城漠隸ッ<E99AB8>?
|
||||
- DeepSeek-V3: Layer 3莉皿arkdown莉」遐∝摎謠仙<EFBFBD>?
|
||||
**✅ 3层JSON解析策略验证**:
|
||||
- Qwen-Max: Layer 2自动修复(修复10字节格式错误)
|
||||
- DeepSeek-V3: Layer 3从Markdown代码块提取
|
||||
- **成功率:100%**
|
||||
|
||||
**笨?蜿梧ィ。蝙句ョケ髞咎ェ瑚ッ?*:
|
||||
**✅ 双模型容错验证**:
|
||||
- Promise.allSettled正常工作
|
||||
- 两个模型并行处理成功
|
||||
|
||||
**笨?蛹サ蟄ヲ騾サ霎鷹ェ瑚ッ<E7919A>**:
|
||||
- DeepSeek-V3: 5/5 笨?
|
||||
- Qwen-Max: 5/5 笨?
|
||||
**✅ 医学逻辑验证**:
|
||||
- DeepSeek-V3: 5/5 ✅
|
||||
- Qwen-Max: 5/5 ✅
|
||||
|
||||
**笨?蜀イ遯∵」豬句ョケ髞?*:
|
||||
**✅ 冲突检测容错**:
|
||||
- 成功处理undefined fields
|
||||
- 不再崩溃
|
||||
|
||||
@@ -270,15 +270,15 @@ if (!fieldsA || typeof fieldsA !== 'object') {
|
||||
|
||||
## 🐛 问题修复记录
|
||||
|
||||
### 髣ョ鬚<EFBFBD>1: ES讓。蝮<EFBFBD> `__dirname` 譛ェ螳壻ケ?
|
||||
### 问题1: ES模块 `__dirname` 未定义
|
||||
**错误**: `ReferenceError: __dirname is not defined in ES module scope`
|
||||
|
||||
**修复**:
|
||||
```typescript
|
||||
// 菫ョ螟榊<E89E9F>?
|
||||
// 修复前
|
||||
const promptDir = path.join(__dirname, '../../fulltext-screening/prompts');
|
||||
|
||||
// 菫ョ螟榊<EFBFBD>?
|
||||
// 修复后
|
||||
import { fileURLToPath } from 'url';
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
@@ -299,10 +299,10 @@ const __dirname = path.dirname(__filename);
|
||||
|
||||
---
|
||||
|
||||
### 髣ョ鬚<EFBFBD>3: ES讓。蝮怜ッシ蜈・郛コ蟆<EFBFBD> `.js` 謇ゥ螻募<EFBFBD>?
|
||||
**髞呵ッッ**: `蠖?"--moduleResolution" 荳?"node16" 謌?"nodenext" 譌カ<EFBFBD>檎嶌蟇ケ蟇シ蜈・霍ッ蠕<EFBFBD>怙隕?ECMAScript 蟇シ蜈・荳ュ逧<EFBDAD>仞蠑乗枚莉カ謇ゥ螻募錐`
|
||||
### 问题3: ES模块导入缺少 `.js` 扩展名
|
||||
**错误**: `当 "--moduleResolution" 为 "node16" 或 "nodenext" 时,相对导入路径需要 ECMAScript 导入中的显式文件扩展名`
|
||||
|
||||
**菫ョ螟<EFBFBD>**: 謇譛臥嶌蟇ケ蟇シ蜈・豺サ蜉?`.js` 謇ゥ螻募<EFBFBD>?
|
||||
**修复**: 所有相对导入添加 `.js` 扩展名
|
||||
```typescript
|
||||
import { PromptBuilder } from './PromptBuilder.js';
|
||||
import type { LLM12FieldsResult } from './types.js';
|
||||
@@ -312,17 +312,17 @@ import type { LLM12FieldsResult } from './types.js';
|
||||
|
||||
---
|
||||
|
||||
### 髣ョ鬚<EFBFBD>4: LLM譁ケ豕穂ク榊ュ伜<EFBFBD>?
|
||||
**髞呵ッッ**: `邀サ蝙<EFBFBD>"ILLMAdapter"荳贋ク榊ュ伜惠螻樊?generateText"`
|
||||
### 问题4: LLM方法不存在
|
||||
**错误**: `类型"ILLMAdapter"上不存在属性"generateText"`
|
||||
|
||||
**原因**: ILLMAdapter接口只有`chat`方法,没有`generateText`
|
||||
|
||||
**修复**:
|
||||
```typescript
|
||||
// 菫ョ螟榊<EFBFBD>?
|
||||
// 修复前
|
||||
const response = await adapter.generateText(prompt);
|
||||
|
||||
// 菫ョ螟榊<EFBFBD>?
|
||||
// 修复后
|
||||
const response = await adapter.chat(messages);
|
||||
```
|
||||
|
||||
@@ -330,7 +330,7 @@ const response = await adapter.chat(messages);
|
||||
|
||||
---
|
||||
|
||||
### 髣ョ鬚<EFBFBD>5: 讓。蝙狗アサ蝙倶ク榊源驟?
|
||||
### 问题5: 模型类型不匹配
|
||||
**错误**: `Unsupported model type: qwen-max`
|
||||
|
||||
**原因**: `LLMFactory`期望的ModelType是`qwen3-72b`,但传入的是`qwen-max`
|
||||
@@ -364,7 +364,7 @@ try {
|
||||
return JSON.parse(jsonrepair(text));
|
||||
} catch {}
|
||||
|
||||
// Layer 3: 謠仙叙Markdown莉」遐∝<EFBFBD>?
|
||||
// Layer 3: 提取Markdown代码块
|
||||
const match = text.match(/```json\s*\n([\s\S]*?)\n```/);
|
||||
if (match) {
|
||||
return JSON.parse(match[1]);
|
||||
@@ -373,12 +373,12 @@ if (match) {
|
||||
|
||||
**影响文件**: `LLM12FieldsService.ts`
|
||||
|
||||
**萓晁オ<EFBFBD>**: 螳芽」<E88ABD> `json-repair` 蠎?
|
||||
**依赖**: 安装 `json-repair` 库
|
||||
|
||||
---
|
||||
|
||||
### 问题7: MedicalLogicValidator无法处理对象类型字段
|
||||
**髞呵ッッ**: 蟄玲ョオ蛟シ蜿ッ閭ス譏ッ蟇ケ雎。<E99B8E><EFBDA1>{ assessment: '螳梧紛', confidence: 0.9 }`<EFBFBD>芽碁撼蟄礼ャヲ荳?
|
||||
**错误**: 字段值可能是对象(`{ assessment: '完整', confidence: 0.9 }`)而非字符串
|
||||
|
||||
**修复**: 添加 `safeGetFieldValue` 辅助函数
|
||||
```typescript
|
||||
@@ -399,9 +399,9 @@ private safeGetFieldValue(fieldData: any): string {
|
||||
### 问题8: EvidenceChainValidator处理undefined fields崩溃
|
||||
**错误**: `Cannot convert undefined or null to object`
|
||||
|
||||
**蜴溷屏**: `Object.entries(fields)` 蝨?`fields` 荳?`undefined` 譌カ蟠ゥ貅?
|
||||
**原因**: `Object.entries(fields)` 在 `fields` 为 `undefined` 时崩溃
|
||||
|
||||
**菫ョ螟<EFBFBD>**: 豺サ蜉<EFBFBD>null譽譟?
|
||||
**修复**: 添加null检查
|
||||
```typescript
|
||||
if (!fields || typeof fields !== 'object') {
|
||||
this.logger.warn('Fields is undefined, null, or not an object');
|
||||
@@ -413,17 +413,17 @@ if (!fields || typeof fields !== 'object') {
|
||||
|
||||
---
|
||||
|
||||
### 髣ョ鬚<EFBFBD>9: ConflictDetectionService logger譛ェ螳壻ケ?
|
||||
### 问题9: ConflictDetectionService logger未定义
|
||||
**错误**: `Cannot read properties of undefined (reading 'warn')`
|
||||
|
||||
**蜴溷屏**: 菴ソ逕ィ莠?`this.logger.warn`<EFBFBD>御ス<EFBFBD>ッ・邀サ菴ソ逕ィ蜈ィ螻 `logger`
|
||||
**原因**: 使用了 `this.logger.warn`,但该类使用全局 `logger`
|
||||
|
||||
**修复**:
|
||||
```typescript
|
||||
// 菫ョ螟榊<E89E9F>?
|
||||
// 修复前
|
||||
this.logger.warn('fieldsA is null, undefined, or not an object');
|
||||
|
||||
// 菫ョ螟榊<EFBFBD>?
|
||||
// 修复后
|
||||
logger.warn('fieldsA is null, undefined, or not an object');
|
||||
```
|
||||
|
||||
@@ -455,7 +455,7 @@ if (results[1].status === 'fulfilled') { /* 使用结果B */ }
|
||||
```json
|
||||
{
|
||||
"dependencies": {
|
||||
"json-repair": "^0.x.x" // JSON閾ェ蜉ィ菫ョ螟榊コ?
|
||||
"json-repair": "^0.x.x" // JSON自动修复库
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -470,83 +470,83 @@ npm install json-repair
|
||||
|
||||
## 📊 代码统计
|
||||
|
||||
**譁ー蠅樊枚莉カ**: 22荳?
|
||||
**諤サ莉」遐∬。梧<EFBFBD>?*: ~4,500陦?
|
||||
**新增文件**: 22个
|
||||
**总代码行数**: ~4,500行
|
||||
|
||||
**核心服务**:
|
||||
- `PromptBuilder.ts`: 275陦?
|
||||
- `LLM12FieldsService.ts`: 547陦?
|
||||
- `MedicalLogicValidator.ts`: 413陦?
|
||||
- `EvidenceChainValidator.ts`: 464陦?
|
||||
- `ConflictDetectionService.ts`: 432陦?
|
||||
- `PromptBuilder.ts`: 275行
|
||||
- `LLM12FieldsService.ts`: 547行
|
||||
- `MedicalLogicValidator.ts`: 413行
|
||||
- `EvidenceChainValidator.ts`: 464行
|
||||
- `ConflictDetectionService.ts`: 432行
|
||||
|
||||
**謠千、コ隸肴枚莉?*:
|
||||
**提示词文件**:
|
||||
- `system_prompt.md`: 6,601字符
|
||||
- `user_prompt_template.md`: 199陦?
|
||||
- Cochrane譬<EFBFBD>㊥: 3荳ェ譁<EFBDAA>サ?
|
||||
- `user_prompt_template.md`: 199行
|
||||
- Cochrane标准: 3个文件
|
||||
|
||||
**测试文件**:
|
||||
- `integration-test.ts`: ~200陦?
|
||||
- `quick-test.ts`: 266陦?
|
||||
- `cached-result-test.ts`: 129陦?
|
||||
- `integration-test.ts`: ~200行
|
||||
- `quick-test.ts`: 266行
|
||||
- `cached-result-test.ts`: 129行
|
||||
|
||||
---
|
||||
|
||||
## 🎯 质量保证
|
||||
|
||||
### 代码质量
|
||||
- 笨?謇譛瑛inter髞呵ッッ蟾イ菫ョ螟?
|
||||
- 笨?TypeScript邀サ蝙句ョ牙<EFBFBD>
|
||||
- 笨?ES讓。蝮苓ァ<E88B93>激驕オ蠕ェ
|
||||
- 笨?螳梧紛逧<E7B49B>漠隸ッ螟<EFBDAF><E89E9F>?
|
||||
- 笨?隸ヲ扈<EFBDA6>噪譌・蠢苓ョー蠖?
|
||||
- ✅ 所有linter错误已修复
|
||||
- ✅ TypeScript类型安全
|
||||
- ✅ ES模块规范遵循
|
||||
- ✅ 完整的错误处理
|
||||
- ✅ 详细的日志记录
|
||||
|
||||
### 测试覆盖
|
||||
- 笨?蜊募<E89C8A>豬玖ッ包シ磯ェ瑚ッ∝勣<E2889D>?
|
||||
- 笨?髮<><E9ABAE>豬玖ッ包シ亥ョ梧紛豬∫ィ具シ<E585B7>
|
||||
- 笨?螳ケ髞呎オ玖ッ包シ亥シょクク螟<EFBDB8>炊<EFBFBD><E7828A>
|
||||
- 笨?逵溷ョ霸DF豬玖ッ<E78E96>
|
||||
- ✅ 单元测试(验证器)
|
||||
- ✅ 集成测试(完整流程)
|
||||
- ✅ 容错测试(异常处理)
|
||||
- ✅ 真实PDF测试
|
||||
|
||||
### 性能优化
|
||||
- 笨?扈捺棡郛灘ュ假シ磯∩蜈埼㍾螟崎ー<E5B48E>畑<EFBFBD><E79591>
|
||||
- 笨?蟷カ陦悟、<E6829F>炊<EFBFBD>亥曙讓。蝙具シ?
|
||||
- 笨?Prompt莨伜喧<E4BC9C>育ァサ髯、Few-shot<EFBFBD>悟㍼蟆?4KB竊?2KB<EFBFBD>?
|
||||
- 笨?謌先悽霑ス雕ェ<E99B95>磯乗<C280>逧<EFBFBD>エケ逕ィ扈溯ョ。<EFBDAE><EFBDA1>
|
||||
- ✅ 结果缓存(避免重复调用)
|
||||
- ✅ 并行处理(双模型)
|
||||
- ✅ Prompt优化(移除Few-shot,减少74KB→52KB)
|
||||
- ✅ 成本追踪(透明的费用统计)
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>噫 荳倶ク豁・隶。蛻?
|
||||
## 🚀 下一步计划
|
||||
|
||||
譬ケ謐ョ蠑蜿題ョ。蛻?`04-蜈ィ譁<EFBDA8>、咲ュ帛シ蜿題ョ。蛻?md`<EFBFBD>?
|
||||
根据开发计划 `04-全文复筛开发计划.md`:
|
||||
|
||||
**Day 4: 謇ケ螟<EFBFBD>炊莉サ蜉。譛榊<EFBFBD>?* (蠕<>シ蟋?
|
||||
**Day 4: 批处理任务服务** (待开始)
|
||||
- 任务队列管理
|
||||
- 批量处理逻辑
|
||||
- 进度跟踪
|
||||
- 并发控制
|
||||
|
||||
**Day 5: 蜑咲ォッUI蠑蜿?* (蠕<>シ蟋?
|
||||
**Day 5: 前端UI开发** (待开始)
|
||||
- 设置页面
|
||||
- 蟾・菴懷床鬘オ髱?
|
||||
- 工作台页面
|
||||
- 结果页面
|
||||
- 蜿瑚ァ<E7919A>崟螳。髦<EFBDA1>シケ遯?
|
||||
- 双视图审阅弹窗
|
||||
|
||||
**Day 6: API髮<EFBFBD><EFBFBD>荳手#隹?* (蠕<>シ蟋?
|
||||
**Day 6: API集成与联调** (待开始)
|
||||
- RESTful API实现
|
||||
- 蜑榊錘遶ッ閨碑ー?
|
||||
- 遶ッ蛻ー遶ッ豬玖ッ?
|
||||
- 前后端联调
|
||||
- 端到端测试
|
||||
|
||||
---
|
||||
|
||||
## <EFBFBD>庁 蜈ウ髞ョ謚譛ッ蜀ウ遲?
|
||||
## 💡 关键技术决策
|
||||
|
||||
### 决策1: 移除Few-shot Examples
|
||||
**理由**:
|
||||
- Prompt莉?4KB髯崎<EFBFBD>52KB
|
||||
- 髯堺ス鮫LM隹<4D>畑謌先悽郤?0%
|
||||
- MVP髦カ谿オ莨伜<EFBFBD>騾溷コヲ蜥梧<EFBFBD>譛?
|
||||
- Prompt从74KB降至52KB
|
||||
- 降低LLM调用成本约30%
|
||||
- MVP阶段优先速度和成本
|
||||
|
||||
**蜷守サュ**: 蜿ッ蝨ィ逕滉コァ邇ッ蠅<EFBFBD><EFBFBD>ケ謐ョ蜃<EFBFBD>。ョ邇<EFBFBD>怙豎る㍾譁ー隸<EFBFBD>シ?
|
||||
**后续**: 可在生产环境根据准确率需求重新评估
|
||||
|
||||
### 决策2: MVP不加载Cochrane标准
|
||||
**理由**:
|
||||
@@ -554,21 +554,21 @@ npm install json-repair
|
||||
- 降低LLM调用成本
|
||||
- 专注核心Section-Aware策略
|
||||
|
||||
**蜷守サュ**: 蜿ッ騾夊ソ<EFBFBD><EFBFBD>鄂ョ蠑蜈ウ轣オ豢サ蜷ッ逕?
|
||||
**后续**: 可通过配置开关灵活启用
|
||||
|
||||
### 决策3: 3层JSON解析策略
|
||||
**理由**:
|
||||
- LLM霎灘<EFBFBD>譬シ蠑丈ク咲ィウ螳?
|
||||
- LLM输出格式不稳定
|
||||
- 避免解析失败导致整个任务失败
|
||||
- 激进修复策略,快速MVP交付
|
||||
|
||||
**謨域棡**: 豬玖ッ穂ク?00%謌仙粥邇?
|
||||
**效果**: 测试中100%成功率
|
||||
|
||||
### 决策4: Promise.allSettled容错
|
||||
**理由**:
|
||||
- 荳荳ェ讓。蝙句、ア雍・荳榊スア蜩榊嘗荳荳?
|
||||
- 莨倬寉髯咲コァ<EFBDBA><EFBDA7>egraded Mode<EFBFBD>?
|
||||
- 謠宣ォ倡ウサ扈溷庄髱<E5BA84>諤?
|
||||
- 一个模型失败不影响另一个
|
||||
- 优雅降级(Degraded Mode)
|
||||
- 提高系统可靠性
|
||||
|
||||
**效果**: 双模型容错验证通过
|
||||
|
||||
@@ -578,32 +578,32 @@ npm install json-repair
|
||||
|
||||
### 成功经验
|
||||
|
||||
1. **貂占ソ帛シ丞シ蜿?*: 蜈亥ョ樒鴫譬ク蠢<EFBDB8>粥閭ス<E996AD>悟<EFBFBD>莨伜喧扈<E596A7><E68988>?
|
||||
1. **渐进式开发**: 先实现核心功能,再优化细节
|
||||
2. **完整测试**: 单元测试 + 集成测试 + 容错测试
|
||||
3. **螳ケ髞呵ョセ隶。**: 螟壼アる亟謚、<EFBFBD>御シ倬寉髯咲コ?
|
||||
4. **諤ァ閭ス莨伜<E88EA8>**: Prompt莨伜喧縲∫シ灘ュ俶惻蛻カ縲∝ケカ陦悟、<EFBFBD><EFBFBD>?
|
||||
3. **容错设计**: 多层防护,优雅降级
|
||||
4. **性能优先**: Prompt优化、缓存机制、并行处理
|
||||
|
||||
### 教训
|
||||
|
||||
1. **ES讓。蝮苓ソ∫ァサ**: 髴隕∵ウィ諢?`__dirname`縲~.js` 謇ゥ螻募錐遲臥サ<EFBFBD>鰍
|
||||
2. **LLM霎灘<EFBFBD>荳咲ィウ螳?*: 蠢<>。サ譛詠obust逧<74>ァ」譫仙柱鬪瑚ッ∵惻蛻カ
|
||||
3. **TypeScript邀サ蝙区」譟?*: 譌ゥ譛溷書邇ー貎懷惠髣ョ鬚<EFBDAE>
|
||||
4. **譌・蠢苓ョー蠖<EFBDB0>**: 隸ヲ扈<EFBFBD>律蠢怜ッケ隹<EFBFBD>ッ戊<EFBFBD>蜈ウ驥崎ヲ?
|
||||
1. **ES模块迁移**: 需要注意 `__dirname`、`.js` 扩展名等细节
|
||||
2. **LLM输出不稳定**: 必须有robust的解析和验证机制
|
||||
3. **TypeScript类型检查**: 早期发现潜在问题
|
||||
4. **日志记录**: 详细日志对调试至关重要
|
||||
|
||||
---
|
||||
|
||||
## 📎 相关文档
|
||||
|
||||
- **蠑蜿題ョ。蛻?*: `04-蠑蜿題ョ。蛻?04-蜈ィ譁<EFBDA8>、咲ュ帛シ蜿題ョ。蛻?md`
|
||||
- **雍ィ驥丈ソ晞囿遲也払**: `02-謚譛ッ隶セ隶?08-蜈ィ譁<EFBDA8>、咲ュ幄エィ驥丈ソ晞囿遲也払.md`
|
||||
- **API隶セ隶。**: `02-謚譛ッ隶セ隶?02-API隶セ隶。隗<EFBDA1>激.md`
|
||||
- **謨ー謐ョ蠎楢ョセ隶?*: `02-謚譛ッ隶セ隶?01-謨ー謐ョ蠎楢ョセ隶?md`
|
||||
- **开发计划**: `04-开发计划/04-全文复筛开发计划.md`
|
||||
- **质量保障策略**: `02-技术设计/08-全文复筛质量保障策略.md`
|
||||
- **API设计**: `02-技术设计/02-API设计规范.md`
|
||||
- **数据库设计**: `02-技术设计/01-数据库设计.md`
|
||||
|
||||
---
|
||||
|
||||
**螳梧<EFBFBD>譌・譛<EFBFBD>**: 2025蟷?1譛?2譌?
|
||||
**迥カ諤?*: 笨?Day 2 & Day 3 蜈ィ驛ィ螳梧<EFBFBD>
|
||||
**荳倶ク豁?*: Day 4 謇ケ螟<EFBDB9>炊莉サ蜉。譛榊<E8AD9B>?
|
||||
**完成日期**: 2025年11月22日
|
||||
**状态**: ✅ Day 2 & Day 3 全部完成
|
||||
**下一步**: Day 4 批处理任务服务
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user