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,6 +1,6 @@
|
||||
# Node.js 后端 - 镜像修复记录
|
||||
|
||||
> **ä¿®å¤<EFBFBD>æ—¶é—´**ï¼?025-12-24
|
||||
> **修复时间**:2025-12-24
|
||||
> **问题原因**:Docker镜像中缺少config目录
|
||||
> **解决方案**:重新构建镜像v1.1
|
||||
|
||||
@@ -14,74 +14,74 @@ Error: ENOENT: no such file or directory, open '/app/config/agents.yaml'
|
||||
```
|
||||
|
||||
### 根本原因
|
||||
- 应用å<EFBFBD>¯åŠ¨æ—¶éœ€è¦<EFBFBD>读å<EFBFBD>?`/app/config/agents.yaml` é…<EFBFBD>置文件
|
||||
- Dockerfile v1.0 ä¸å<EFBFBD>ªå¤<EFBFBD>制äº?`dist` å’?`prisma` 目录
|
||||
- **é<EFBFBD>—æ¼<EFBFBD>äº?`config` 目录**
|
||||
- 应用启动时需要读取 `/app/config/agents.yaml` 配置文件
|
||||
- Dockerfile v1.0 中只复制了 `dist` 和 `prisma` 目录
|
||||
- **遗漏了 `config` 目录**
|
||||
|
||||
---
|
||||
|
||||
## �解决方案
|
||||
## ✅ 解决方案
|
||||
|
||||
### 1. 修改Dockerfile
|
||||
|
||||
**修改ä½<EFBFBD>ç½®1**:构建阶段(ç¬?2行)
|
||||
**修改位置1**:构建阶段(第32行)
|
||||
```dockerfile
|
||||
# 5. å¤<EFBFBD>制本地已编译好çš?dist 文件夹(跳过TypeScript编译ï¼?
|
||||
# 5. 复制本地已编译好的 dist 文件夹(跳过TypeScript编译)
|
||||
COPY dist ./dist
|
||||
|
||||
# 6. å¤<EFBFBD>制é…<EFBFBD>置文件(agents.yamlç‰ï¼‰âœ?新增
|
||||
# 6. 复制配置文件(agents.yaml等)✨ 新增
|
||||
COPY config ./config
|
||||
```
|
||||
|
||||
**修改ä½<EFBFBD>ç½®2**:è¿<C3A8>行阶段(ç¬?1行)
|
||||
**修改位置2**:运行阶段(第61行)
|
||||
```dockerfile
|
||||
# 从构建阶段å¤<EFBFBD>制产ç‰?
|
||||
# 从构建阶段复制产物
|
||||
COPY --from=builder --chown=nodejs:nodejs /app/node_modules ./node_modules
|
||||
COPY --from=builder --chown=nodejs:nodejs /app/dist ./dist
|
||||
COPY --from=builder --chown=nodejs:nodejs /app/package*.json ./
|
||||
COPY --from=builder --chown=nodejs:nodejs /app/prisma ./prisma
|
||||
COPY --from=builder --chown=nodejs:nodejs /app/config ./config �新增
|
||||
COPY --from=builder --chown=nodejs:nodejs /app/config ./config ✨ 新增
|
||||
```
|
||||
|
||||
### 2. 重新构建镜像
|
||||
|
||||
**构建命令**�
|
||||
**构建命令**:
|
||||
```bash
|
||||
docker build -t crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.1 .
|
||||
```
|
||||
|
||||
**构建结果**�
|
||||
- âœ?构建æˆ<C3A6>功
|
||||
- �耗时�9.4�
|
||||
- âœ?镜åƒ<C3A5>大å°<C3A5>:~186MB(压缩å<C2A9>Žï¼?
|
||||
**构建结果**:
|
||||
- ✅ 构建成功
|
||||
- ✅ 耗时:59.4秒
|
||||
- ✅ 镜像大小:~186MB(压缩后)
|
||||
|
||||
### 3. 推送到ACR
|
||||
|
||||
**推é€<EFBFBD>命ä»?*ï¼?
|
||||
**推送命令**:
|
||||
```bash
|
||||
docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.1
|
||||
```
|
||||
|
||||
**推é€<EFBFBD>结æž?*ï¼?
|
||||
- âœ?推é€<C3A9>æˆ<C3A6>åŠ?
|
||||
- �Digest: `sha256:f309cec92d2ebb7fd40c38916980d7fcc2d589e61d10a8875f2976c267eac890`
|
||||
**推送结果**:
|
||||
- ✅ 推送成功
|
||||
- ✅ Digest: `sha256:f309cec92d2ebb7fd40c38916980d7fcc2d589e61d10a8875f2976c267eac890`
|
||||
|
||||
---
|
||||
|
||||
## 📦 新版本镜åƒ<C3A5>ä¿¡æ<C2A1>?
|
||||
## 📦 新版本镜像信息
|
||||
|
||||
### 版本对比
|
||||
|
||||
| 项目 | v1.0(旧版本�| v1.1(新版本�|
|
||||
| 项目 | v1.0(旧版本) | v1.1(新版本) |
|
||||
|------|--------------|--------------|
|
||||
| **Dockerfile修改** | â<EFBFBD>?缺少config | âœ?包å<E280A6>«config |
|
||||
| **Dockerfile修改** | ❌ 缺少config | ✅ 包含config |
|
||||
| **镜像大小** | 838MB | 838MB(基本一致) |
|
||||
| **构建时间** | ~5分钟 | ~1分钟(缓存优化) |
|
||||
| **状æ€?* | â<>?å<>¯åŠ¨å¤±è´¥ | âœ?待验è¯?|
|
||||
| **状态** | ❌ 启动失败 | ✅ 待验证 |
|
||||
|
||||
### 新版本镜像地址
|
||||
|
||||
**公网地å<EFBFBD>€**(用于本地拉å<E280B0>–)ï¼?
|
||||
**公网地址**(用于本地拉取):
|
||||
```
|
||||
crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.1
|
||||
```
|
||||
@@ -93,54 +93,54 @@ crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backen
|
||||
|
||||
---
|
||||
|
||||
## 🎯 ä¸‹ä¸€æ¥æ“<C3A6>ä½?
|
||||
## 🎯 下一步操作
|
||||
|
||||
### æ¥éª¤1:登录SAE控制å<EFBFBD>?
|
||||
### 步骤1:登录SAE控制台
|
||||
访问:https://sae.console.aliyun.com/
|
||||
|
||||
### æ¥éª¤2:更新应用镜åƒ<EFBFBD>版æœ?
|
||||
### 步骤2:更新应用镜像版本
|
||||
|
||||
1. 找到应用:`nodejs-backend-test`
|
||||
2. 点击ã€<EFBFBD>é…<EFBFBD>置管ç<EFBFBD>†ã€‘→ã€<EFBFBD>部署é…<EFBFBD>ç½®ã€?
|
||||
2. 点击【配置管理】→【部署配置】
|
||||
3. 找到"镜像设置"部分
|
||||
4. 修改镜åƒ<EFBFBD>版本ï¼?
|
||||
4. 修改镜像版本:
|
||||
- 从:`backend-service:v1.0`
|
||||
- 改为:`backend-service:v1.1` �
|
||||
- 改为:`backend-service:v1.1` ✨
|
||||
|
||||
### 步骤3:保存并重新部署
|
||||
|
||||
1. 点击ã€<EFBFBD>ä¿<EFBFBD>å˜ã€?
|
||||
2. 点击ã€<EFBFBD>é‡<EFBFBD>新部署ã€?
|
||||
1. 点击【保存】
|
||||
2. 点击【重新部署】
|
||||
3. 等待3-5分钟
|
||||
4. 查看实时日志
|
||||
|
||||
---
|
||||
|
||||
## �预期结果
|
||||
## ✅ 预期结果
|
||||
|
||||
### æˆ<EFBFBD>功的日志输å‡?
|
||||
### 成功的日志输出
|
||||
|
||||
```
|
||||
============================================================
|
||||
🚀 AI临床研究平台 - 后端服务器启动成功!
|
||||
============================================================
|
||||
📍 服务地址: http://0.0.0.0:3001
|
||||
ðŸ”<EFBFBD> å<>¥åº·æ£€æŸ? http://0.0.0.0:3001/health
|
||||
🔍 健康检查: http://0.0.0.0:3001/health
|
||||
📡 API入口: http://0.0.0.0:3001/api/v1
|
||||
🌍 运行环境: production
|
||||
============================================================
|
||||
|
||||
[INFO] Server listening at http://0.0.0.0:3001
|
||||
[INFO] Config loaded: /app/config/agents.yaml �
|
||||
[INFO] Config loaded: /app/config/agents.yaml ✅
|
||||
[INFO] Database connected successfully
|
||||
[INFO] Health check endpoint available
|
||||
```
|
||||
|
||||
### 关键验è¯<EFBFBD>ç‚?
|
||||
### 关键验证点
|
||||
|
||||
- [x] 应用状æ€<EFBFBD>:è¿<EFBFBD>行ä¸ï¼ˆç»¿è‰²ï¼?
|
||||
- [x] 应用状态:运行中(绿色)
|
||||
- [x] 健康检查:通过(绿色)
|
||||
- [x] 日志ä¸å‡ºçŽ°ï¼š`Config loaded: /app/config/agents.yaml` âœ?
|
||||
- [x] 日志中出现:`Config loaded: /app/config/agents.yaml` ✅
|
||||
- [x] 无ENOENT错误
|
||||
|
||||
---
|
||||
@@ -148,24 +148,24 @@ crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backen
|
||||
## 📝 修复总结
|
||||
|
||||
**问题根源**:Dockerfile不完整,遗漏配置文件
|
||||
**ä¿®å¤<EFBFBD>æ–¹å¼<EFBFBD>**:添åŠ?行COPY指令
|
||||
**修复方式**:添加2行COPY指令
|
||||
**影响范围**:仅需重新构建和部署,无需修改代码
|
||||
**ä¿®å¤<EFBFBD>æ—¶é—´**:约5分钟(构å»?分钟 + 推é€?分钟 + 部署3分钟ï¼?
|
||||
**修复时间**:约5分钟(构建1分钟 + 推送1分钟 + 部署3分钟)
|
||||
|
||||
---
|
||||
|
||||
## 🔍 预防措施
|
||||
|
||||
### 1. Dockerfile检查清å<EFBFBD>?
|
||||
### 1. Dockerfile检查清单
|
||||
|
||||
创建完整的文件复制清单:
|
||||
```dockerfile
|
||||
�COPY package*.json ./
|
||||
�COPY prisma ./prisma/
|
||||
�COPY dist ./dist/
|
||||
âœ?COPY config ./config/ # ä¸<EFBFBD>è¦<EFBFBD>é<EFBFBD>—æ¼<EFBFBD>ï¼?
|
||||
â<EFBFBD>?COPY public ./public/ # 如果有é<EFBFBD>™æ€<EFBFBD>æ–‡ä»?
|
||||
â<EFBFBD>?COPY scripts ./scripts/ # 如果有å<EFBFBD>¯åŠ¨è„šæœ?
|
||||
✅ COPY package*.json ./
|
||||
✅ COPY prisma ./prisma/
|
||||
✅ COPY dist ./dist/
|
||||
✅ COPY config ./config/ # 不要遗漏!
|
||||
❓ COPY public ./public/ # 如果有静态文件
|
||||
❓ COPY scripts ./scripts/ # 如果有启动脚本
|
||||
```
|
||||
|
||||
### 2. 本地测试流程
|
||||
@@ -181,10 +181,10 @@ docker run -p 3001:3001 \
|
||||
-e JWT_SECRET="..." \
|
||||
backend-test:local
|
||||
|
||||
# 3. 访问å<EFBFBD>¥åº·æ£€æŸ?
|
||||
# 3. 访问健康检查
|
||||
curl http://localhost:3001/health
|
||||
|
||||
# 4. ç¡®è®¤æ— é”™è¯¯å<EFBFBD>Žå†<EFBFBD>推é€?
|
||||
# 4. 确认无错误后再推送
|
||||
```
|
||||
|
||||
### 3. CI/CD集成
|
||||
@@ -203,9 +203,8 @@ curl http://localhost:3001/health
|
||||
|
||||
---
|
||||
|
||||
**文档创建时间**�025-12-24
|
||||
**维护人员**:è¿<C3A8>维团é˜?
|
||||
|
||||
**文档创建时间**:2025-12-24
|
||||
**维护人员**:运维团队
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user