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:
2026-01-16 13:42:10 +08:00
parent 98d862dbd4
commit 66255368b7
560 changed files with 70424 additions and 52353 deletions

View File

@@ -1,80 +1,92 @@
# **<EFBFBD><EFBFBD>﹝ B嚗鍃DC <20><><EFBFBD><EFBFBD>?(REDCap) <20><><EFBFBD>航祕蝏<E7A595>挽霈?(V1.0)**
# **文档 BEDC 适配器 (REDCap) 技术详细设计 (V1.0)**
## **1\. <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>PRD V3 撖?REDCap <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>瘙?*
## **1\. 需求映射:PRD V3 REDCap 能力的诉求**
基于 IIT Manager Agent V3 的功能定义,适配器必须支持以下 REDCap 核心能力。
<EFBFBD><EFBFBD> IIT Manager Agent V3 <20><><EFBFBD><EFBFBD><EFBFBD>銋㚁<E98A8B><E39A81><EFBFBD><EFBFBD><EFBFBD><EFBFBD>憿餅𣈲<E9A485><F0A388B2>誑銝?REDCap <20><EFBFBD><E8A9A8><EFBFBD><E8B3A2>?
### **1.1 感知能力 (Read & Monitor)**
* **摰墧𧒄<EFBFBD>穃𨯬 (Real-time Hook)**嚗𡁜笆摨婙<EFBFBD>𨀣㺭<EFBFBD>株捶<EFBFBD>?Agent<6E><EFBFBD><E88588><EFBFBD> CRC 敶訫<E695B6><E8A8AB>唳旿<E594B3><EFBFBD>REDCap 敹<><EFBFBD>賭蜓<E8B3AD><EFBFBD>𨀣綫<F0A880A3>嘥枂鈭衤辣<E8A1A4>?
* **<EFBFBD>唳旿<EFBFBD><EFBFBD>/憓鮋<E68693>撖澆枂 (Data Export)**嚗𡁜笆摨婙<EFBFBD>𣈯★<EFBFBD>桃恣<EFBFBD>?Agent<6E><EFBFBD><E88588><EFBFBD><EFBFBD><E996AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>𡝗<EFBFBD><F0A19D97>㕑扇敶𤏪<E695B6>餈𥡝<E9A488><F0A5A19D><EFBFBD><E4BAA6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E6B8A1><EFBFBD><EFBFBD><E99C88><E288AA><EFBFBD>?
* **<EFBFBD><EFBFBD><EFBFBD><EFBFBD>銋㕑繮<EFBFBD>?(Metadata Export)**嚗𡁜笆摨婙<EFBFBD>𨀣䲮獢<EFBFBD>㺭摮堒<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㚚★<EFBFBD><EFBFBD>銵典<EFBFBD>蝏𤘪<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>畾萇掩<EFBFBD><EFBFBD>銝𧢲<EFBFBD>獢?<3F><>𧋦獢<F0A78BA6><E78DA2>嚗𣬚鍂鈭?AI <20>芸𢆡<E88AB8><F0A286A1><EFBFBD><EFBFBD><EFBFBD><E683A9>?
* **实时监听 (Real-time Hook)**:对应“数据质控 Agent”。当 CRC 录入数据时REDCap 必须能主动“推”出事件。
* **数据全量/增量导出 (Data Export)**:对应“项目管理 Agent”。需要定期抓取所有记录进行入组率、完整率的统计分析。
* **元数据定义获取 (Metadata Export)**:对应“方案数字化”。需要获取项目的表单结构、变量名、字段类型(下拉框/文本框),用于 AI 自动生成映射。
### **1.2 执行能力 (Write & Query)**
* **霈啣<EFBFBD>瘜典<EFBFBD>銝擧凒<EFBFBD>?(Record Import)**嚗𡁜笆摨婙<EFBFBD>𨀣㺭<EFBFBD>格惣<EFBFBD><EFBFBD><EFBFBD>?Agent<6E><EFBFBD><E88588>I 霂<><E99C82><EFBFBD><EFBFBD>蝏𤘪<E89D8F><F0A498AA>𡝗㺭<F0A19D97><EFBFBD><E6A185><EFBFBD><E59D94><EFBFBD><EFBFBD>摮埈挾<E59F88>?
* **韐函<EFBFBD>蝞∠<EFBFBD> (Query/Data Resolution)**嚗𡁜笆摨婙<EFBFBD>𡏭捶<EFBFBD>?Agent<6E><EFBFBD><E88588>I <20>𤑳緵<F0A491B3><EFBFBD><E6A185>𠬍<EFBFBD><F0A0AC8D><EFBFBD><EFBFBD><EFBFBD><E69C9E>亙藁<E4BA99>?REDCap 銝剖<E98A9D>撱算<E692B1>𡏭捶<F0A18FAD>?(Query)<EFBFBD><EFBFBD>?
* **<EFBFBD><EFBFBD>霈方<EFBFBD><EFBFBD><EFBFBD> (Auth API)**嚗𡁶&靽?Agent <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>瘜閧<EFBFBD> User Token 摰∟恣<EFBFBD>?
## **2\. <20><><EFBFBD><EFBFBD><E887AC><EFBFBD>External Module (EM) 銝?REST API 瘛瑕<E7989B><E79195><EFBFBD>**
* **记录注入与更新 (Record Import)**:对应“数据智能采集 Agent”。AI 识别出的结构化数据需写入指定字段。
* **质疑管理 (Query/Data Resolution)**:对应“质控 Agent”。AI 发现问题后,需通过接口在 REDCap 中创建“质疑 (Query)”。
* **用户认证映射 (Auth API)**:确保 Agent 操作时具备合法的 User Token 审计。
銝箔<EFBFBD>摰䂿緵瘛勗漲<EFBFBD><EFBFBD>銝𥪯<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嚗峕<EFBFBD>隞祇<EFBFBD><EFBFBD>?**<2A>諪M 靘扳<E99D98><E689B3>雴辣 \+ Node.js <20><><EFBFBD><EFBFBD><EFBFBD>?* <20><><EFBFBD><E6AFBD>䲮獢<E4B2AE><E78DA2>?
### **2.1 External Module (EM) <20><EFBFBD><E8A9A8>諹提嚗帋蜓<E5B88B>券偬摮?*
## **2\. 技术实现External Module (EM) 与 REST API 混合架构**
<EFBFBD><EFBFBD><EFBFBD>睲賑<EFBFBD><EFBFBD> REDCap 皞鞟<E79A9E>嚗峕<E59A97>隞砍<E99A9E><EFBFBD><E69298><EFBFBD>銝芸<E98A9D>銝?ai\_research\_assistant <20>?EM<45>?
* **<2A>唳旿靽嘥<E99DBD><E598A5><EFBFBD> (redcap\_save\_record)**嚗?
* **<2A><EFBFBD>**嚗𡁏<E59A97>敶栞扇敶蓥<E695B6>摮矋<E691AE>EM <20>閗繮敶枏<E695B6> project\_id <20>?record\_id<69>?
* **<2A><EFBFBD>**嚗𡁻<E59A97><EFBFBD> HTTP POST <20><EFBFBD>?Webhook 蝏?Node.js <20>𡒊垢<F0A1928A>?
* **隞瑕<E99A9E>?*嚗𡁜<E59A97><F0A1819C><EFBFBD>𡏭捶<F0A18FAD>?Agent<6E><EFBFBD>鈭𡁶<E988AD>蝥批<E89DA5>摨𢛵<E691A8>?
* **憿菟𢒰瘜典<E7989C><E585B8><EFBFBD> (redcap\_every\_page\_top)**嚗?
* **<2A><EFBFBD>**嚗𡁜銁<F0A1819C>唳旿敶訫<E695B6>憿菟𢒰瘜典<E7989C><E585B8><EFBFBD>銋?JS (ai\_assistant.js)<29>?
* **<2A><EFBFBD>**嚗𡁜銁敶訫<E695B6><EFBFBD><E78DA2><EFBFBD>曄內 AI 颲<>𨭌<EFBFBD>厰僼<E58EB0><EFBFBD>鈭株<E988AD><E6A0AA><EFBFBD><E6A0BC><EFBFBD>?
* **隞瑕<E99A9E>?*嚗𡁜<E59A97><F0A1819C><EFBFBD><E595A3>仿𧫴畾萇<E795BE><E89087>𨀣㺭摮堒𨭌<E5A092>𦥑<EFBFBD><EFBFBD><E598A5><EFBFBD><EFBFBD>?
### **2.2 Node.js EDC Adapter <20><EFBFBD><E8A9A8>諹提嚗朞◤<E69C9E>刻挪<E588BB>?*
为了实现深度融合且保持高性能,我们采用 **“EM 侧挂插件 \+ Node.js 适配器”** 的混合方案。
<EFBFBD><EFBFBD>蝡臬<EFBFBD>鋆?RedcapAdapter 蝐鳴<E89D90><EFBFBD><E686AD><EFBFBD><EFBFBD><EFBFBD>劐蜓<E58A90><EFBFBD><E586BD>碶遙<E7A2B6><EFBFBD>?
* **API 靚<>鍂撠<E98D82><E692A0>**嚗?
* exportRecords: <20><EFBFBD>銝游<E98A9D><E6B8B8>唳旿<E594B3>?
* importRecords: <20>𧼮<EFBFBD>敶勗<E695B6><E58B97><EFBFBD><E59786>霈文<E99C88><E69687><EFBFBD><EFBFBD><EFBFBD>?
* exportMetadata: <20><EFBFBD>銵典<E98AB5><E585B8><EFBFBD><EFBFBD><E79A9C><EFBFBD>?
* importQueries: (<28><EFBFBD> EM <20><>䌊摰帋<E691B0>憿菟𢒰) 摰䂿緵 AI <20>芸𢆡<E88AB8>𥕦遣韐函<E99F90><E587BD>?
## **3\. <20>喲睸<E596B2>亙藁皜<E89781><E79A9C>銝𤾸<E98A9D><F0A4BEB8><EFBFBD><E59581>?*
### **2.1 External Module (EM) 核心职责:主动钩子**
### **3.1 <20><EFBFBD>撖寞𦻖<E5AF9E>亙藁銵?*
由于我们拥有 REDCap 源码,我们将开发一个名为 ai\_research\_assistant 的 EM。
| 撖寞𦻖<E5AF9E><EFBFBD> | REDCap <20><EFBFBD> API / EM Hook | 撖孵<E69296><E5ADB5>?Agent <20><EFBFBD> |
* **数据保存钩子 (redcap\_save\_record)**
* **逻辑**每当记录保存EM 捕获当前 project\_id 和 record\_id。
* **动作**:通过 HTTP POST 发送 Webhook 给 Node.js 后端。
* **价值**:实现“质控 Agent”的亚秒级响应。
* **页面注入钩子 (redcap\_every\_page\_top)**
* **逻辑**:在数据录入页面注入自定义 JS (ai\_assistant.js)。
* **动作**:在录入框旁显示 AI 辅助按钮或高亮证据提醒。
* **价值**:实现录入阶段的“数字助手”入口。
### **2.2 Node.js EDC Adapter 核心职责:被动访问**
在后端封装 RedcapAdapter 类,处理所有主动抓取任务。
* **API 调用封装**
* exportRecords: 抓取临床数据。
* importRecords: 回写影子状态确认后的数据。
* exportMetadata: 获取表单变量清单。
* importQueries: (基于 EM 的自定义页面) 实现 AI 自动创建质疑。
## **3\. 关键接口清单与实现细节**
### **3.1 核心对接接口表**
| 对接功能 | REDCap 原生 API / EM Hook | 对应的 Agent 动作 |
| :---- | :---- | :---- |
| **摰墧𧒄<EFBFBD><EFBFBD><EFBFBD>𡁶䰻** | redcap\_save\_record (Hook) | 閫血<EFBFBD>韐冽綉璉<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>唳𠯫<EFBFBD>?|
| **<EFBFBD><EFBFBD><EFBFBD>唳旿<EFBFBD>峕郊** | exportRecords (API) | <EFBFBD><EFBFBD><EFBFBD><EFBFBD>冽𥁒頞见飵<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?|
| **AI <EFBFBD>芸𢆡敶訫<EFBFBD>** | importRecords (API) | <EFBFBD><EFBFBD><EFBFBD> Agent <EFBFBD><EFBFBD><EFBFBD>唳旿嚗<EFBFBD>蔣摮鞟霈文<EFBFBD>嚗?|
| **<EFBFBD>唳旿撘<EFBFBD>虜憸<EFBFBD>** | importQueries (<EFBFBD><EFBFBD>銋? | 韐冽綉 Agent <20>𥕦遣韐函<E99F90><E587BD>∠𤌍 |
| **实时入组通知** | redcap\_save\_record (Hook) | 触发质控检查、更新日报 |
| **全量数据同步** | exportRecords (API) | 生成周报趋势图、脱落分析 |
| **AI 自动录入** | importRecords (API) | 采集 Agent 写入数据(影子确认后) |
| **数据异常预警** | importQueries (自定义) | 质控 Agent 创建质疑条目 |
| **方案解析映射** | exportMetadata (API) | 获取变量清单进行 AI 语义映射 |
### **3.2 敶勗<EFBFBD><EFBFBD><EFBFBD>?(Shadow State) <EFBFBD><EFBFBD><EFBFBD><EFBFBD>䠷曎頝?*
### **3.2 影子状态 (Shadow State) 的回写链路**
这是白皮书的核心要求,其技术实现路径如下:
1. **撱箄悅<EFBFBD><EFBFBD><EFBFBD>**嚗鋫gent 蝏𤘪<E89D8F>摮睃<E691AE><E79D83>睲賑<E79DB2>?pending\_actions 銵具<EFBFBD>?
2. **鈭箇掩摰⊥瓲**嚗鋴RC <EFBFBD>?Workbench <EFBFBD>孵稬<EFBFBD>𦦵霈手<EFBFBD><EFBFBD>?
3. **<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?*嚗鐭ode.js <20>𣂼<EFBFBD>霂交辺<E4BAA4><EFBFBD> edc\_api\_token嚗𣬚<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> REDCap importRecords JSON <EFBFBD><EFBFBD><EFBFBD>?
4. **<EFBFBD>𧼮<EFBFBD><EFBFBD><EFBFBD>**嚗?
// REDCap <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>格聢撘讐內靘?
1. **建议生成**Agent 结果存入我们的 pending\_actions 表。
2. **人类审核**CRC Workbench 点击“确认”。
3. **适配器调用**Node.js 提取该条目的 edc\_api\_token,组装标准的 REDCap importRecords JSON 报文。
4. **回写执行**
// REDCap 接受的数据格式示例
\[
{"record\_id": "P001", "redcap\_repeat\_instance": 1, "field\_name": "ai\_qc\_status", "value": "2"}
\]
5. **摰∟恣<EFBFBD>剔㴓**嚗𡁜<E59A97><F0A1819C><EFBFBD><E8B9B1><EFBFBD>嚗峕凒<E5B395>?pending\_actions.status \= 'EXECUTED'<EFBFBD>?
5. **审计闭环**:回写成功后,更新 pending\_actions.status \= 'EXECUTED'
## **4\. 独特技术亮点External Module 对外合作机制**
<EFBFBD>拍鍂 REDCap <EFBFBD>?EM <EFBFBD><EFBFBD>嚗峕<EFBFBD>隞砍虾隞亙<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>?API <20>湔楛<E6B994><EFBFBD><E4BAA6><EFBFBD>嚗?
1. <20><EFBFBD>銋㕑<E98A8B><E39591>閖曎<E99696>?(links)嚗?
<20>?REDCap 撌虫儒撖潸⏛<E6BDB8>讐凒<E8AE90><EFBFBD><E4BA99>?<3F>𨅯ㄨ霂<E384A8>儐 AI <20><EFBFBD>銝剖<E98A9D><E58996>?<3F>?H5 <20>暹𦻖嚗諹悟<E8ABB9><EFBFBD>銝滚枂 EDC 撠梯<E692A0>雿輻鍂<E8BCBB>睲賑<E79DB2><E8B391><EFBFBD><EFBFBD><EFBFBD>?
2. 摰𡁏𧒄隞餃𦛚蝞∠<E89D9E> (crons)嚗?
<20>?REDCap 靘批⏚<E689B9>?Cron 閫血<E996AB>摰𡁏<E691B0><F0A1818F><EFBFBD><EFBFBD><EFBFBD>摨瑟<E691A8><E7919F><EFBFBD><E4BC90>讛蝠<E8AE9B>睲賑銝餌頂蝏毺<E89D8F>頧株砭<E6A0AA><EFBFBD><E8A781>?
3. 摮埈挾蝥折<E89DA5><E68A98><EFBFBD>鈭殷<E988AD>
<20><EFBFBD> EM 靽格㺿敶訫<E695B6>憿菟𢒰<E88F9F>?DOM嚗<4D><E59A97> Agent <20>𤑳緵<F0A491B3>厰䔮憸条<E686B8>摮埈挾<E59F88><E68CBE>扇銝粹<E98A9D><E7B2B9><EFBFBD>𠧧<EFBCBA>?
## **5\. 摰匧<E691B0>銝舘恕霂<E68195>挽霈?(Security)**
利用 REDCap EM 机制,我们可以实现比普通 API 更深入的整合:
* **<2A><EFBFBD> Token <20><EFBFBD>**嚗?
* **蝟餌<E89D9F>蝥?*嚗鍃M 霈輸䔮 Node.js <20><EFBFBD>Headers <20>箏蒂 X-Signature嚗𠃍MAC-SHA256 <20><EFBFBD>嚗剹<E59A97>?
* **<2A><EFBFBD>蝥?*嚗鐭ode.js 霈輸䔮 REDCap <20><EFBFBD>雿輻鍂<E8BCBB><EFBFBD>摮睃<E691AE><E79D83>?Personal API Token<65>?
* API <20><EFBFBD> (Rate Limiting)嚗?
<20><>笆憭找葉敹<E89189><EFBFBD><EFBFBD><E6AEB7><EFBFBD><EFBFBD><EFBFBD>刻䌊<E588BB>典笆 API 霂瑟<E99C82>餈𥡝<E9A488><F0A5A19D><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E7989A><EFBFBD>脫迫 REDCap <20>滚𦛚<E6BB9A><EFBFBD>擃㗛<E69383> AI 韐冽綉<E586BD><E7B689>援皞<E68FB4><E79A9E>?
**蝏湔擪<E6B994>?*嚗𡁏沲<F0A1818F><E6B2B2><EFBFBD> & REDCap 銝枏振 | **<EFBFBD><EFBFBD>?*嚗朞祕蝏<E7A595>挽霈<E99C88><E288AA>
1. 自定义菜单链接 (links)
在 REDCap 左侧导航栏直接嵌入 “壹证循 AI 控制中心” 的 H5 链接,让用户不出 EDC 就能使用我们的功能。
2. 定时任务管理 (crons)
在 REDCap 侧利用 Cron 触发定期的数据健康检查,减轻我们主系统的轮询压力。
3. 字段级颜色高亮:
通过 EM 修改录入页面的 DOM将 Agent 发现有问题的字段标记为黄色或红色。
## **5\. 安全与认证设计 (Security)**
* **双重 Token 校验**
* **系统级**EM 访问 Node.js 时Headers 携带 X-SignatureHMAC-SHA256 加密)。
* **用户级**Node.js 访问 REDCap 时,使用加密存储的 Personal API Token。
* API 限流 (Rate Limiting)
针对大中心项目,适配器自动对 API 请求进行分片和限流,防止 REDCap 服务器因高频 AI 质控而崩溃。
**维护者**:架构组 & REDCap 专家 | **状态**:详细设计完成