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
14 KiB
壹证循科技AI科研产品 - 技术架构白皮书
1. 执行摘要 (Executive Summary)
本文档为“壹证循科技”AI科研产品套件提供了一个统一的技术架构方案。
核心战略:采用**“演进式架构”。以“模块化单体”(Modular Monolith)启动,快速迭代;并为未来向“微服务”**(Microservices)架构的平滑过渡做好充分准备。
核心原则:
- 平台与产品分离:严格划分“底层通用模块”(如用户中心)和“上层业务模块”(如统计分析)。
- 一个架构,多种部署:设计一套灵活的架构,通过“容器化”和“逻辑重组”,同时支持①云端SaaS、②医院私有化部署、③混合部署和④医生个人单机版。
- 技术异构(Polyglot):采用“用最合适的工具做最合适的事”的原则,允许Node.js、R、Python、Java等技术栈在微服务架构中共存。
技术路径:
- 云端/私有化:采用 Docker(容器) + Kubernetes(编排) + API网关 的标准微服务部署方案。
- 单机版:采用 Electron 框架,100%复用前端UI代码,并通过 Node.js主进程 + 本地子进程(R/Python) 的方式重组后端逻辑,实现数据100%本地化。
2. 业务需求与架构挑战
2.1 产品功能矩阵 (7大模块)
- 智能统计分析 (SSA)
- 统计分析工具 (ST)
- AI智能回答 (AIA)
- AI智能文献 (ASL)
- 个人知识库 (PKB)
- 数据清洗整理 (DC)
- 个人中心 (UAM)
2.2 复杂的商业与部署挑战
- 多版本 (SaaS):云端版分为专业版、高级版、旗舰版。
- 模块化售卖:任何模块(如AI智能文献)都可能独立售卖。
- 私有化部署:医院要求将数据敏感模块(如SSA、DC)部署在内网服务器。
- 混合部署:医院本地使用SSA,同时又调用云端的ASL。
- 单机版部署:医生需要在个人电脑(Windows/Mac)上离线运行SSA、DC、ASL等模块,确保数据(文献、病例)不出本地。
3. 核心架构:API网关 + 微服务
为满足以上所有需求,我们推荐一个解耦的、面向服务的架构。
- 客户端 (Clients):包括Web浏览器、PC单机版(Electron)、移动端。
- API网关 (API Gateway):所有流量的统一入口。负责:
- 认证:校验用户Token。
- 路由:将请求转发给正确的后端微服务(如 /api/stats -> SSA服务)。
- 聚合:(未来)合并多个服务的数据。
- 后端服务 (Services):真正执行业务逻辑的单元。
4. 服务模块划分 (平台 vs 产品)
这是架构解耦的第一步。
4.1 底层通用模块 (平台层)
这些是所有产品共用的“地基”,必须稳固、统一。
- 用户与权限中心 (UAM)
- 功能:管理用户、角色、租户(医院)、权限。
- 价值:实现SaaS多版本(专业版/高级版)的功能开关(Feature Flag)控制。
- AI大模型网关 (LLM Gateway)
- 功能:统一管理所有对大模型的调用(DeepSeek, Claude等)。
- 价值:根据SaaS版本、成本考量动态切换模型。是AI功能的核心中枢。
- 账户/个人中心:管理用户配置、订单、帮助文档。
- 通知服务:邮件、站内信。
4.2 独立业务模块 (产品层)
这些是可插拔的“积木”,对应你们的7大功能,每个都应设计为独立的服务。
- 智能统计 (SSA) 服务 (可包含统计工具ST)
- AI问答 (AIA) 服务
- AI文献 (ASL) 服务
- 知识库 (PKB) 服务
- 数据清洗 (DC) 服务 (详见第6节)
5. 推荐技术栈 (技术异构)
我们允许“用最合适的工具做最合适的事”。
| 领域 | 推荐技术 | 理由 |
| 前端 (UI) | React 或 Vue | 1. 现代SPA框架。 2. 可100%复用于Web版和Electron单机版。 |
| API网关 & 粘合层 | Node.js | 1. 高并发I/O性能。 2. 作为“总指挥”粘合R/Python非常成熟。 3. Electron单机版后端复用。 |
| 统计分析 (SSA) | R 语言 | 统计分析的王者。通过 Plumber 包暴露为API,或通过子进程调用。 |
| AI/数据清洗 (DC) | Python | 强大的Pandas、Scikit-learn、NLP生态。通过 FastAPI 暴露API,或通过子进程调用。 |
| 数据库 | PostgreSQL + Vector DB | PostgreSQL处理结构化数据;向量数据库支持知识库(PKB)的RAG。 |
| 部署方案 | Docker + Kubernetes | 现代云原生的唯一标准,实现弹性和多环境部署。 |
| 单机版方案 | Electron | 唯一能原生支持Node.js后端、复用Web前端UI的跨平台方案。 |
6. 模块深度解析:(DC) 数据清洗整理服务
“数据清洗整理 (DC)” 模块是连接原始数据与有效分析的桥梁,技术挑战分为两部分:
- 海量表格ETL:处理百万行、多表格的结构化数据,执行高效的连接(Join)、重组(Pivot)和排序。
- 非结构化文本NER:从病理、出入院小结等大段文本中,提取结构化字段(如TNM分期、肿瘤大小)。
针对不同的部署场景,我们采用两种实现方案:
6.1 方案一:服务器最优版 (Cloud-Optimal)
此方案用于云端SaaS版和私有化部署,目标是追求极致的效率、准确率和质量(假设数据已脱敏)。
- 技术栈:Python (FastAPI) + Polars + LLM API (Claude/GPT) + PostgreSQL
- 工作流:
- API接收:FastAPI (Python) 服务接收用户上传的多个Excel文件。
- ETL (Polars):
- 放弃Pandas,采用Polars库。Polars基于Rust,天生多线程并行,内存效率极高。
- 在服务器的大内存中(如64GB+),Polars能以数秒或数十秒的速度,在内存中完成200万行数据的多表JOIN、GROUP BY等操作,速度是Pandas的10-100倍。
- NER (LLM API):
- FastAPI 服务并行调用 AI大模型网关(见4.1节)。
- 使用 Claude 3 或 GPT-4o 等SOTA模型,配合JSON Mode,从病理报告中提取结构化信息。
- 优势:准确率极高,能理解复杂上下文,无需训练模型。
- 交付:清洗完成的Polars DataFrame被存入PostgreSQL结果表,前端可在线浏览或导出。
- 架构融合:此 FastAPI + Polars 服务,就是白皮书架构中的“数据清洗 (DC) 微服务”,由“Node.js API网关”负责调用。
6.2 方案二:单机版 (Desktop-Offline)
此方案用于医生个人电脑,目标是100%数据隐私和离线可用性,是对性能和准确率的必要妥协。
- 技术栈:Electron (Node.js) + Python (Pandas) + SQLite + spaCy (本地NLP)
- 工作流:
- 总指挥 (Node.js):Electron的主进程作为总指挥,调度Python子进程。
- ETL (SQLite):
- 严禁将200万行数据一次性读入内存(会导致用户电脑崩溃)。
- Python脚本被调用,使用Pandas的chunksize参数,分块读取Excel,逐行写入一个本地SQLite数据库文件 (.db)。
- 关键:利用 SQLite 数据库引擎(而不是Pandas内存)来执行所有繁重的JOIN和GROUP BY。这是在低内存电脑上处理大数据的唯一稳定方案。
- NER (本地 spaCy):
- 严禁将原始病例(PHI)发送到任何云端API(重大违规)。
- Python脚本被调用,加载 spaCy 等100%本地运行的NLP模型,在用户电脑上提取实体。
- 劣势:spaCy准确率有限,无法处理复杂语义,效果远不如LLM。
- 交付:所有结果被写回本地 SQLite 数据库。Electron前端通过分页从SQLite中读取数据展示,或导出为Excel。
- 架构融合:此方案就是白皮书【7.4 场景四:医生单机版】的具体实现。
7. 关键路径:多部署模式实现
同一套代码库,如何支持所有商业场景?
7.1 场景一:云端SaaS版 (标准微服务)
- 架构:所有服务(UAM, SSA, ASL...)和数据库都在云端,通过K8s管理。
- 客户端:用户通过浏览器访问。
7.2 场景二:医院本地化部署 (私有化)
- 架构:将数据敏感的服务(如 SSA服务、DC服务)及其数据库打包为Docker容器。
- 部署:使用K8s或更轻量的K3s,在医院内网服务器上“一键部署”。
- 数据:数据100%留在医院内网。
7.3 场景三:混合部署
- 架构:在场景二的基础上,前端应用被智能配置。
- 流程:
- 用户访问 .../stats -> 前端调用医院内网API (http://192.168.x.x/api/stats)。
- 用户访问 .../literature -> 前端调用云端公网API (https://api.yizhengxun.com/api/lit)。
7.4 场景四:医生单机版 (Electron)
这是技术上最关键的“过渡”,它不是“打包”,而是**“架构重组”**。
云端版架构:
[浏览器UI] <-- (HTTP网络) --> [云端Node.js API] <-- (HTTP) --> [云端R/Python服务]
单机版架构:
[Electron UI (复用)] <-- (IPC本机通信) --> [Electron主进程 (Node.js复用)] <-- (Child Process本机调用) --> [本地R/Python脚本]
实现路径:
- 新建Electron项目。
- 移植前端 (UI复用):将云端版的React/Vue编译后的静态文件 (dist目录) 完整复制到Electron中。
- 重组后端 (逻辑复用):
- 云端版的 Node.js API逻辑,被移植到 Electron的主进程(main.js) 中。
- 云端版的 R 和 Python 脚本,被作为本地文件打包进安装包。
- main.js (Node.js) 通过 child_process.spawn(子进程)来本地调用这些R/Python脚本。(具体实现见第6.2节)
- 数据交换:Node.js、R、Python之间通过 stdin/stdout 和 JSON 字符串进行数据交换。
- 本地AI功能 (ASL模块):
- Node.js (fs模块) 读取本地文献夹中的PDF。
- Node.js (用 pdf-parse) 在本地提取摘要文本。
- Node.js (用 axios) 只将“摘要文本”发送给云端LLM API (如DeepSeek) 进行分析。(注意:这与DC模块的原始病例处理不同)。
- 文献原文件 (.pdf) 100% 不离开用户电脑。
- 本地存储:使用 SQLite(通过 npm install sqlite3)在本地存储文献的元数据、分析结果等。
8. 工程化与兼容性 (必读)
8.1 单机版的“全家桶”挑战
单机版的工程挑战不是开发,而是打包。
- 您的 .exe (Windows) 和 .dmg (Mac) 安装包必须是一个“全家桶”。
- 您需要使用 electron-builder 等工具,将以下所有内容捆绑进一个安装包:
- 您的Electron应用 (Node.js + 前端UI)。
- 一个嵌入式的 Python 运行时及所有依赖 (pandas, spaCy等)。
- 一个嵌入式的 R 运行时及所有依赖 (jsonlite等)。
- 这会使安装包体积变大(如500MB+),这对于专业软件是完全可以接受的。
8.2 必须放弃:Win 7 与 32位系统
这是一个商业和安全决策,不是技术选项。
必须声明: 您的单机版最低系统要求是 Windows 10 (64位)。
理由:
- 稳定性的“崩溃”问题:32位系统有4GB内存上限,APP最多用2-3GB。您的R语言统计分析和数据清洗都是内存消耗大户,处理真实数据时不是变卡,而是会直接崩溃闪退,导致用户数据丢失。
- 安全性的“漏洞”问题:微软已放弃Win 7。现代Electron, Node.js, Python, R生态已全部停止支持32位和Win 7。强行兼容意味着您必须使用5年前、充满已知安全漏洞的“古董”技术栈来处理敏感医疗数据,这是不可接受的。
9. 分阶段实施路线图 (Roadmap)
作为初创公司,我们必须务实。
9.1 阶段一:云端MVP (0-6个月) - “模块化单体”
- 目标:快速上线云端SaaS版,验证市场。
- 架构:一个代码仓库 (Monorepo),一个主后端服务(如Node.js)。
- 关键纪律 (打地基):
- 代码隔离:在代码目录上,严格按“平台模块”和“业务模块”划分。
- 数据隔离:在同一个PostgreSQL数据库中,严格使用不同的Schema (如 uam_schema, stats_schema) 来隔离数据。这是未来拆分微服务的生命线。
- 全员Docker:从第一天起,所有开发、测试、生产环境都必须基于 Docker 和 docker-compose。
9.2 阶段二:首次部署 (6-18个月) - “首次拆分”
- 触发点:迎来第一个“私有化部署”客户,或“单机版”需求。
- 架构:
- 引入K8s:在云端正式启用Kubernetes进行服务编排。
- 引入API网关:在K8s集群前部署Nginx或Kong。
- 执行首次拆分:将 SSA 和 DC 模块(连同它们的 stats_schema)从主应用中物理拆分出来,打包成第一个独立的微服务(采用6.1节的“最优版”架构)。
- 开发单机版:启动第一个Electron项目,按照【7.4】中的路径进行“重组”(采用6.2节的“单机版”架构)。
9.3 阶段三:全面微服务 (18个月+)
- 目标:支持灵活的业务组合和团队扩张。
- 架构:随着业务发展,将 ASL, PKB 等其他成熟模块也逐步拆分为独立的微服务,实现最终的“乐高积木式”的灵活架构。
10. 结论
本架构方案的核心是**“演进”**。它在初期(阶段一)通过“模块化单体”保证了初创公司的迭代速度,同时通过“代码/数据隔离”和“全面Docker化”的纪律,为未来(阶段二、三)向复杂微服务和多部署形态的平滑过渡打下了坚实的地基,避免了未来推倒重来的灾难性成本。