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
587 lines
16 KiB
Markdown
587 lines
16 KiB
Markdown
# ASL模块开发 - 新AI交接文档
|
||
|
||
**日期**: 2025-11-18
|
||
**当前阶段**: Week 2 - 前端UI开发
|
||
**阅读时间**: 5分钟
|
||
|
||
---
|
||
|
||
## 🎯 项目概述
|
||
|
||
### 这是什么项目?
|
||
|
||
**AIclinicalresearch** - 医学临床研究AI平台
|
||
|
||
一个覆盖医学研究全生命周期的AI辅助平台,包括7大业务模块。**当前正在开发ASL模块**(AI智能文献筛选)。
|
||
|
||
---
|
||
|
||
### 系统架构(三层)
|
||
|
||
```
|
||
┌─────────────────────────────────────────┐
|
||
│ 业务模块层 (Business Layer) │
|
||
│ - ASL (AI智能文献) ← 当前开发中 │
|
||
│ - AIA, PKB, DC, SSA, ST, RVW │
|
||
└─────────────────────────────────────────┘
|
||
↓ 依赖
|
||
┌─────────────────────────────────────────┐
|
||
│ 能力层 (Capability Layer) │
|
||
│ - LLM Gateway (5个模型已集成) ✅ │
|
||
│ - Document Processing Engine │
|
||
│ - RAG Engine, ETL, Medical NLP │
|
||
└─────────────────────────────────────────┘
|
||
↓ 依赖
|
||
┌─────────────────────────────────────────┐
|
||
│ 平台基础设施层 (Platform Layer) │
|
||
│ 8个核心模块 - 已完成 ✅ │
|
||
│ Storage, Logging, Caching, Jobs, etc. │
|
||
└─────────────────────────────────────────┘
|
||
```
|
||
|
||
**关键特性**:
|
||
- **Schema隔离**: 10个独立PostgreSQL Schema
|
||
- **模块化**: 每个业务模块独立开发、部署、销售
|
||
- **云原生**: 优化Alibaba Cloud SAE部署
|
||
|
||
---
|
||
|
||
## 📍 当前状态(2025-11-18)
|
||
|
||
### ✅ Week 1 已完成(提前4天)
|
||
|
||
**后端开发** (100%):
|
||
- ✅ 数据库Schema设计(4个表,asl_schema)
|
||
- ✅ 后端API框架(10个接口)
|
||
- ✅ LLM双模型筛选服务
|
||
- ✅ 三种筛选风格(宽松/标准/严格)
|
||
- ✅ JSON解析器修复(支持中文引号)
|
||
- ✅ API测试完成(7/7通过)
|
||
|
||
**核心成果**:
|
||
1. **双模型筛选**: DeepSeek-V3 + Qwen-Max并行
|
||
2. **三种Prompt**: 宽松/标准/严格模式
|
||
3. **理由展示**: 保存两个模型的完整判断理由
|
||
4. **冲突检测**: 只检测conclusion冲突,不检测PICO差异
|
||
|
||
---
|
||
|
||
### ⬜ Week 2 待开始(当前任务)
|
||
|
||
**前端UI开发** (0%):
|
||
- ⬜ Day 1-2: 项目管理界面
|
||
- ⬜ Day 3-4: 文献导入界面
|
||
- ⬜ Day 5: 筛选结果展示
|
||
|
||
---
|
||
|
||
## 🔧 技术栈
|
||
|
||
### 前端
|
||
- **框架**: React 18 + TypeScript
|
||
- **UI库**: Ant Design 5
|
||
- **路由**: React Router v6
|
||
- **状态**: React Query + Zustand
|
||
- **架构**: Frontend-v2(模块化注册)
|
||
|
||
### 后端
|
||
- **框架**: Fastify + TypeScript
|
||
- **ORM**: Prisma
|
||
- **数据库**: PostgreSQL (asl_schema)
|
||
- **LLM**: DeepSeek-V3, Qwen-Max, GPT-4o, Claude-4.5
|
||
|
||
### 已完成的平台服务(可直接使用)
|
||
```typescript
|
||
import { logger } from '@/common/logging'; // 日志
|
||
import { storage } from '@/common/storage'; // 存储
|
||
import { cache } from '@/common/cache'; // 缓存
|
||
import { jobQueue } from '@/common/jobs'; // 异步任务
|
||
import { prisma } from '@/config/database'; // 数据库
|
||
```
|
||
|
||
---
|
||
|
||
## 📂 关键目录结构
|
||
|
||
### 前端(待开发)
|
||
```
|
||
frontend-v2/src/modules/asl/
|
||
├── pages/ # 页面组件
|
||
│ ├── ProjectList/ # 项目列表页 ← Week 2 Day 1
|
||
│ ├── ProjectDetail/ # 项目详情页 ← Week 2 Day 2
|
||
│ ├── LiteratureImport/ # 文献导入页 ← Week 2 Day 3-4
|
||
│ └── ScreeningResults/ # 筛选结果页 ← Week 2 Day 5
|
||
├── components/ # 通用组件
|
||
├── hooks/ # 自定义Hooks
|
||
├── services/ # API调用
|
||
├── types/ # TypeScript类型
|
||
└── index.tsx # 模块入口
|
||
```
|
||
|
||
### 后端(已完成)✅
|
||
```
|
||
backend/src/modules/asl/
|
||
├── controllers/ # 控制器 ✅
|
||
├── services/ # 业务逻辑 ✅
|
||
│ └── llmScreeningService.ts # 核心筛选服务
|
||
├── routes/ # 路由 ✅
|
||
├── schemas/ # JSON Schema + Prompt生成 ✅
|
||
├── types/ # 类型定义 ✅
|
||
└── prompts/ # 三种Prompt模板 ✅
|
||
├── v1.1.0-lenient.txt # 宽松模式
|
||
├── v1.1.0-standard.txt # 标准模式
|
||
└── v1.1.0-strict.txt # 严格模式
|
||
```
|
||
|
||
---
|
||
|
||
## 🌟 核心功能说明
|
||
|
||
### 1. 双模型筛选机制
|
||
|
||
**工作流程**:
|
||
```
|
||
1. 用户上传文献(Excel)
|
||
2. 系统解析文献(标题+摘要)
|
||
3. 并行调用两个LLM模型:
|
||
- DeepSeek-V3
|
||
- Qwen-Max
|
||
4. 两个模型独立判断(include/exclude)
|
||
5. 系统检测冲突(conclusion是否一致)
|
||
6. 返回结果:
|
||
- 一致 → finalDecision = 模型结论
|
||
- 冲突 → finalDecision = pending(需人工复核)
|
||
```
|
||
|
||
**重要**: 保存两个模型的**完整理由**供用户查看
|
||
|
||
---
|
||
|
||
### 2. 三种筛选风格
|
||
|
||
| 风格 | 特点 | 使用场景 |
|
||
|------|------|----------|
|
||
| **宽松模式** | 宁可多纳入,不错过 | 初筛阶段 |
|
||
| **标准模式** | 平衡准确率和召回率 | 常规使用 |
|
||
| **严格模式** | 宁可错杀,保证质量 | 精筛阶段 |
|
||
|
||
**实现**: 已在后端实现,前端需添加选择器
|
||
|
||
---
|
||
|
||
### 3. 数据模型(asl_schema)
|
||
|
||
**4个核心表**:
|
||
```sql
|
||
screening_projects -- 筛选项目(存PICOS、纳排标准)
|
||
literatures -- 文献条目(标题、摘要、PDF链接)
|
||
screening_results -- 筛选结果(两个模型的判断+理由)
|
||
screening_tasks -- 筛选任务(批量任务进度跟踪)
|
||
```
|
||
|
||
---
|
||
|
||
## 🎨 UI原型参考
|
||
|
||
**位置**: `docs/03-业务模块/ASL-AI智能文献/03-UI设计/AI智能文献-标题摘要初筛原型.html`
|
||
|
||
**核心页面**:
|
||
1. **项目列表** - 显示所有筛选项目
|
||
2. **项目详情** - PICOS标准、纳排标准、文献列表
|
||
3. **文献导入** - Excel上传、预览、导入
|
||
4. **筛选结果** - 显示筛选结果、两个模型的理由、冲突标记
|
||
|
||
---
|
||
|
||
## 📋 Week 2 开发任务(详细清单)
|
||
|
||
### Day 1-2: 项目管理界面
|
||
|
||
**任务**:
|
||
- [ ] 创建项目列表页(`/asl/projects`)
|
||
- [ ] 创建项目按钮 + 创建项目表单
|
||
- 项目名称
|
||
- PICOS标准(5个字段)
|
||
- 纳入标准(文本域)
|
||
- 排除标准(文本域)
|
||
- **筛选风格选择**(Radio: 宽松/标准/严格)⭐
|
||
- [ ] 项目列表展示(Table)
|
||
- [ ] 项目详情页(`/asl/projects/:id`)
|
||
|
||
**API接口**(已完成):
|
||
- `POST /api/v1/asl/projects` - 创建项目
|
||
- `GET /api/v1/asl/projects` - 获取项目列表
|
||
- `GET /api/v1/asl/projects/:id` - 获取项目详情
|
||
|
||
---
|
||
|
||
### Day 3-4: 文献导入界面
|
||
|
||
**任务**:
|
||
- [ ] 文献导入页(`/asl/projects/:id/import`)
|
||
- [ ] Excel文件上传(Dragger)
|
||
- [ ] 文献预览(Table)
|
||
- [ ] 格式验证提示
|
||
- [ ] 确认导入按钮
|
||
- [ ] 导入进度提示
|
||
|
||
**API接口**(已完成):
|
||
- `POST /api/v1/asl/projects/:id/literatures/import-json` - 导入文献
|
||
- `GET /api/v1/asl/projects/:id/literatures` - 获取文献列表
|
||
|
||
**Excel格式**:
|
||
```
|
||
必须字段: title, abstract
|
||
可选字段: pmid, authors, journal, publicationYear, doi
|
||
```
|
||
|
||
---
|
||
|
||
### Day 5: 筛选结果展示 ⭐ **重点**
|
||
|
||
**任务**:
|
||
- [ ] 筛选结果列表页(`/asl/projects/:id/results`)
|
||
- [ ] 结果筛选(全部/纳入/排除/待复核)
|
||
- [ ] 结果详情弹窗 ⭐ **关键**
|
||
- 文献信息(标题、摘要)
|
||
- 最终决策(include/exclude/pending)
|
||
- **两个模型的完整结果**:
|
||
- DeepSeek-V3:结论 + 理由 + 置信度
|
||
- Qwen-Max:结论 + 理由 + 置信度
|
||
- 冲突提示(如果两个模型不一致)
|
||
- 人工复核按钮
|
||
|
||
**API接口**(已完成):
|
||
- `GET /api/v1/asl/projects/:id/results` - 获取筛选结果
|
||
|
||
**响应格式**:
|
||
```typescript
|
||
{
|
||
literatureId: string;
|
||
title: string;
|
||
abstract: string;
|
||
finalDecision: 'include' | 'exclude' | 'pending';
|
||
|
||
// ⭐ 两个模型的详细结果
|
||
model1Result: {
|
||
modelName: 'DeepSeek-V3';
|
||
conclusion: 'exclude';
|
||
confidence: 0.92;
|
||
reason: '完整的排除理由...'; // ← 前端需显示
|
||
judgment: { P: 'match', I: 'match', C: 'mismatch', S: 'match' };
|
||
},
|
||
model2Result: {
|
||
modelName: 'Qwen-Max';
|
||
conclusion: 'include';
|
||
confidence: 0.85;
|
||
reason: '完整的纳入理由...'; // ← 前端需显示
|
||
judgment: { ... };
|
||
},
|
||
|
||
hasConflict: true; // 两个模型不一致
|
||
conflictFields: ['conclusion'];
|
||
}
|
||
```
|
||
|
||
---
|
||
|
||
## 🔥 Week 2 开发重点
|
||
|
||
### 1. 筛选风格选择器 ⭐
|
||
|
||
**位置**: 创建项目表单
|
||
|
||
```jsx
|
||
<Form.Item label="筛选风格" name="screeningStyle">
|
||
<Radio.Group defaultValue="standard">
|
||
<Radio.Button value="lenient">
|
||
🔓 宽松模式
|
||
<Tooltip title="初筛推荐,宁可多纳入">
|
||
<QuestionCircleOutlined />
|
||
</Tooltip>
|
||
</Radio.Button>
|
||
<Radio.Button value="standard">
|
||
⚖️ 标准模式
|
||
</Radio.Button>
|
||
<Radio.Button value="strict">
|
||
🔒 严格模式
|
||
</Radio.Button>
|
||
</Radio.Group>
|
||
</Form.Item>
|
||
```
|
||
|
||
---
|
||
|
||
### 2. 两个模型理由展示 ⭐⭐⭐ **最重要**
|
||
|
||
**位置**: 筛选结果详情弹窗
|
||
|
||
```jsx
|
||
<Modal title="筛选详情" width={1000}>
|
||
{/* 最终决策 */}
|
||
<Alert type={finalDecision === 'pending' ? 'warning' : 'success'}>
|
||
<strong>最终决策:</strong> {finalDecision}
|
||
</Alert>
|
||
|
||
{/* 冲突提示 */}
|
||
{hasConflict && (
|
||
<Alert type="warning" showIcon style={{marginTop: 16}}>
|
||
⚠️ 两个模型判断不一致,建议人工复核
|
||
</Alert>
|
||
)}
|
||
|
||
<Divider />
|
||
|
||
{/* ⭐ 两个模型的详细结果(并排显示)*/}
|
||
<Row gutter={16}>
|
||
<Col span={12}>
|
||
<Card title="🤖 DeepSeek-V3" size="small">
|
||
<Descriptions column={1} size="small">
|
||
<Descriptions.Item label="结论">
|
||
<Tag color={model1.conclusion === 'include' ? 'green' : 'red'}>
|
||
{model1.conclusion}
|
||
</Tag>
|
||
</Descriptions.Item>
|
||
<Descriptions.Item label="置信度">
|
||
{(model1.confidence * 100).toFixed(0)}%
|
||
</Descriptions.Item>
|
||
</Descriptions>
|
||
|
||
<Divider style={{margin: '12px 0'}} />
|
||
|
||
<div>
|
||
<strong>判断理由:</strong>
|
||
<p style={{marginTop: 8, whiteSpace: 'pre-wrap'}}>
|
||
{model1.reason} {/* ⭐ 显示完整理由 */}
|
||
</p>
|
||
</div>
|
||
|
||
<Divider style={{margin: '12px 0'}} />
|
||
|
||
<Collapse ghost size="small">
|
||
<Panel header="PICO维度详情" key="1">
|
||
<Descriptions column={2} size="small">
|
||
<Descriptions.Item label="P">{model1.judgment.P}</Descriptions.Item>
|
||
<Descriptions.Item label="I">{model1.judgment.I}</Descriptions.Item>
|
||
<Descriptions.Item label="C">{model1.judgment.C}</Descriptions.Item>
|
||
<Descriptions.Item label="S">{model1.judgment.S}</Descriptions.Item>
|
||
</Descriptions>
|
||
</Panel>
|
||
</Collapse>
|
||
</Card>
|
||
</Col>
|
||
|
||
<Col span={12}>
|
||
<Card title="🤖 Qwen-Max" size="small">
|
||
{/* 同上,显示model2的结果 */}
|
||
</Card>
|
||
</Col>
|
||
</Row>
|
||
|
||
{/* 人工复核按钮 */}
|
||
<div style={{marginTop: 16, textAlign: 'center'}}>
|
||
<Button type="primary" onClick={handleManualReview}>
|
||
人工复核此文献
|
||
</Button>
|
||
</div>
|
||
</Modal>
|
||
```
|
||
|
||
**为什么这么重要?**
|
||
- 用户需要看到AI的思考过程
|
||
- 当两个模型冲突时,用户需要对比理由来做决策
|
||
- 即使人类专家也可能犯错,理由帮助验证
|
||
|
||
---
|
||
|
||
## 📚 重要文档索引
|
||
|
||
### 必读文档(开发前)
|
||
1. **任务分解**: `docs/03-业务模块/ASL-AI智能文献/04-开发计划/03-任务分解.md`
|
||
- Week 2详细任务清单
|
||
|
||
2. **UI原型**: `docs/03-业务模块/ASL-AI智能文献/03-UI设计/AI智能文献-标题摘要初筛原型.html`
|
||
- 界面参考
|
||
|
||
3. **API设计**: `docs/03-业务模块/ASL-AI智能文献/02-技术设计/02-API设计规范.md`
|
||
- API接口文档
|
||
|
||
### 参考文档(需要时查阅)
|
||
1. **系统架构**: `docs/00-系统总体设计/00-系统当前状态与开发指南.md`
|
||
2. **前端模块化**: `docs/00-系统总体设计/前后端模块化架构设计-V2.md`
|
||
3. **数据库设计**: `docs/03-业务模块/ASL-AI智能文献/02-技术设计/01-数据库设计.md`
|
||
|
||
---
|
||
|
||
## 🚀 快速启动
|
||
|
||
### 1. 启动后端(已完成)
|
||
```bash
|
||
cd backend
|
||
npm run dev
|
||
# 后端运行在 http://localhost:3001
|
||
# API前缀: /api/v1/asl
|
||
```
|
||
|
||
### 2. 启动前端(待开发)
|
||
```bash
|
||
cd frontend-v2
|
||
npm run dev
|
||
# 前端运行在 http://localhost:5173
|
||
```
|
||
|
||
### 3. 测试API
|
||
```bash
|
||
# 健康检查
|
||
curl http://localhost:3001/api/v1/asl/health
|
||
|
||
# 获取项目列表
|
||
curl http://localhost:3001/api/v1/asl/projects
|
||
```
|
||
|
||
---
|
||
|
||
## ⚠️ 重要注意事项
|
||
|
||
### 1. 临时测试模式
|
||
**JWT认证暂时绕过**,使用默认测试用户:
|
||
```typescript
|
||
const userId = requestBody.userId || 'asl-test-user-001';
|
||
```
|
||
|
||
**生产环境需要**: 实现真实的JWT认证
|
||
|
||
---
|
||
|
||
### 2. 筛选风格参数
|
||
创建项目时,记得传递筛选风格:
|
||
```typescript
|
||
const projectData = {
|
||
projectName: '...',
|
||
picoCriteria: { ... },
|
||
inclusionCriteria: '...',
|
||
exclusionCriteria: '...',
|
||
screeningConfig: {
|
||
style: 'lenient', // ← 筛选风格
|
||
models: ['deepseek-chat', 'qwen-max']
|
||
}
|
||
};
|
||
```
|
||
|
||
---
|
||
|
||
### 3. 两个模型理由是核心功能
|
||
**必须在前端显示**,不能省略!
|
||
|
||
这是用户最重要的需求,帮助他们理解AI的判断逻辑。
|
||
|
||
---
|
||
|
||
## 🎯 Week 2 成功标准
|
||
|
||
### 功能完整性
|
||
- [ ] 用户可以创建项目(包含PICOS和筛选风格选择)
|
||
- [ ] 用户可以上传Excel文件导入文献
|
||
- [ ] 用户可以查看筛选结果列表
|
||
- [ ] 用户可以查看**两个模型的详细理由** ⭐
|
||
- [ ] 用户可以识别冲突的文献
|
||
|
||
### 界面质量
|
||
- [ ] UI符合Ant Design规范
|
||
- [ ] 响应式布局(适配不同屏幕)
|
||
- [ ] 加载状态提示
|
||
- [ ] 错误处理友好
|
||
|
||
### 代码质量
|
||
- [ ] TypeScript类型完整
|
||
- [ ] 组件职责清晰
|
||
- [ ] API调用封装好
|
||
- [ ] 代码符合ESLint规范
|
||
|
||
---
|
||
|
||
## 💡 开发建议
|
||
|
||
### 1. 先做框架,再填内容
|
||
```
|
||
Day 1: 搭建页面框架 + 路由
|
||
Day 2: 实现表单和列表
|
||
Day 3-4: 文献导入功能
|
||
Day 5: 筛选结果展示(重点)
|
||
```
|
||
|
||
### 2. 组件复用
|
||
```
|
||
- ProjectForm.tsx(创建/编辑项目表单)
|
||
- LiteratureTable.tsx(文献列表表格)
|
||
- ScreeningResultCard.tsx(筛选结果卡片)
|
||
- ModelComparisonPanel.tsx(模型对比面板)⭐
|
||
```
|
||
|
||
### 3. 状态管理
|
||
```typescript
|
||
// 使用React Query管理服务端状态
|
||
const { data: projects } = useQuery(['projects'], fetchProjects);
|
||
|
||
// 使用Zustand管理客户端状态
|
||
const useAslStore = create((set) => ({
|
||
currentProject: null,
|
||
setCurrentProject: (project) => set({ currentProject: project }),
|
||
}));
|
||
```
|
||
|
||
---
|
||
|
||
## 🔄 后续计划
|
||
|
||
### Week 3-4: MVP完成
|
||
- 批量筛选
|
||
- 结果导出
|
||
- 测试上线
|
||
|
||
### Week 5-7: Phase 2(可选)
|
||
- 智能Prompt生成模块
|
||
- 用户自定义PICOS
|
||
- AI分析边界情况
|
||
|
||
**详见**: `docs/03-业务模块/ASL-AI智能文献/02-技术设计/07-智能Prompt生成模块开发计划.md`
|
||
|
||
---
|
||
|
||
## 📞 关键联系信息
|
||
|
||
- **项目文档**: `AIclinicalresearch/docs/`
|
||
- **代码仓库**: `AIclinicalresearch/`
|
||
- **前端代码**: `frontend-v2/src/modules/asl/`
|
||
- **后端代码**: `backend/src/modules/asl/`
|
||
|
||
---
|
||
|
||
## ✅ 交接检查清单
|
||
|
||
新AI应该确认理解:
|
||
- [ ] 项目是什么(医学文献AI筛选)
|
||
- [ ] 当前状态(Week 1完成,Week 2待开始)
|
||
- [ ] 技术栈(React + Ant Design + Fastify + Prisma)
|
||
- [ ] Week 2任务(3个页面:项目管理、文献导入、结果展示)
|
||
- [ ] 核心功能(双模型筛选、三种风格、显示理由)
|
||
- [ ] 重点任务(显示两个模型的完整理由)⭐
|
||
|
||
---
|
||
|
||
**祝新AI开发顺利!** 🚀
|
||
|
||
**文档版本**: v1.0
|
||
**创建日期**: 2025-11-18
|
||
**维护人**: Previous AI Assistant
|
||
**用途**: 新AI快速上手指南
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|