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
237 lines
5.0 KiB
Markdown
237 lines
5.0 KiB
Markdown
# Node.js 后端 - 镜像修复记录
|
||
|
||
> **修复时间**:2025-12-24
|
||
> **问题原因**:Docker镜像中缺少config目录
|
||
> **解决方案**:重新构建镜像v1.1
|
||
|
||
---
|
||
|
||
## 🐛 问题描述
|
||
|
||
### 错误信息
|
||
```
|
||
Error: ENOENT: no such file or directory, open '/app/config/agents.yaml'
|
||
```
|
||
|
||
### 根本原因
|
||
- 应用启动时需要读取 `/app/config/agents.yaml` 配置文件
|
||
- Dockerfile v1.0 中只复制了 `dist` 和 `prisma` 目录
|
||
- **遗漏了 `config` 目录**
|
||
|
||
---
|
||
|
||
## ✅ 解决方案
|
||
|
||
### 1. 修改Dockerfile
|
||
|
||
**修改位置1**:构建阶段(第32行)
|
||
```dockerfile
|
||
# 5. 复制本地已编译好的 dist 文件夹(跳过TypeScript编译)
|
||
COPY dist ./dist
|
||
|
||
# 6. 复制配置文件(agents.yaml等)✨ 新增
|
||
COPY config ./config
|
||
```
|
||
|
||
**修改位置2**:运行阶段(第61行)
|
||
```dockerfile
|
||
# 从构建阶段复制产物
|
||
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 ✨ 新增
|
||
```
|
||
|
||
### 2. 重新构建镜像
|
||
|
||
**构建命令**:
|
||
```bash
|
||
docker build -t crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.1 .
|
||
```
|
||
|
||
**构建结果**:
|
||
- ✅ 构建成功
|
||
- ✅ 耗时:59.4秒
|
||
- ✅ 镜像大小:~186MB(压缩后)
|
||
|
||
### 3. 推送到ACR
|
||
|
||
**推送命令**:
|
||
```bash
|
||
docker push crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.1
|
||
```
|
||
|
||
**推送结果**:
|
||
- ✅ 推送成功
|
||
- ✅ Digest: `sha256:f309cec92d2ebb7fd40c38916980d7fcc2d589e61d10a8875f2976c267eac890`
|
||
|
||
---
|
||
|
||
## 📦 新版本镜像信息
|
||
|
||
### 版本对比
|
||
|
||
| 项目 | v1.0(旧版本) | v1.1(新版本) |
|
||
|------|--------------|--------------|
|
||
| **Dockerfile修改** | ❌ 缺少config | ✅ 包含config |
|
||
| **镜像大小** | 838MB | 838MB(基本一致) |
|
||
| **构建时间** | ~5分钟 | ~1分钟(缓存优化) |
|
||
| **状态** | ❌ 启动失败 | ✅ 待验证 |
|
||
|
||
### 新版本镜像地址
|
||
|
||
**公网地址**(用于本地拉取):
|
||
```
|
||
crpi-cd5ij4pjt65mweeo.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.1
|
||
```
|
||
|
||
**VPC地址**(SAE部署使用):
|
||
```
|
||
crpi-cd5ij4pjt65mweeo-vpc.cn-beijing.personal.cr.aliyuncs.com/ai-clinical/backend-service:v1.1
|
||
```
|
||
|
||
---
|
||
|
||
## 🎯 下一步操作
|
||
|
||
### 步骤1:登录SAE控制台
|
||
访问:https://sae.console.aliyun.com/
|
||
|
||
### 步骤2:更新应用镜像版本
|
||
|
||
1. 找到应用:`nodejs-backend-test`
|
||
2. 点击【配置管理】→【部署配置】
|
||
3. 找到"镜像设置"部分
|
||
4. 修改镜像版本:
|
||
- 从:`backend-service:v1.0`
|
||
- 改为:`backend-service:v1.1` ✨
|
||
|
||
### 步骤3:保存并重新部署
|
||
|
||
1. 点击【保存】
|
||
2. 点击【重新部署】
|
||
3. 等待3-5分钟
|
||
4. 查看实时日志
|
||
|
||
---
|
||
|
||
## ✅ 预期结果
|
||
|
||
### 成功的日志输出
|
||
|
||
```
|
||
============================================================
|
||
🚀 AI临床研究平台 - 后端服务器启动成功!
|
||
============================================================
|
||
📍 服务地址: http://0.0.0.0:3001
|
||
🔍 健康检查: 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] Database connected successfully
|
||
[INFO] Health check endpoint available
|
||
```
|
||
|
||
### 关键验证点
|
||
|
||
- [x] 应用状态:运行中(绿色)
|
||
- [x] 健康检查:通过(绿色)
|
||
- [x] 日志中出现:`Config loaded: /app/config/agents.yaml` ✅
|
||
- [x] 无ENOENT错误
|
||
|
||
---
|
||
|
||
## 📝 修复总结
|
||
|
||
**问题根源**:Dockerfile不完整,遗漏配置文件
|
||
**修复方式**:添加2行COPY指令
|
||
**影响范围**:仅需重新构建和部署,无需修改代码
|
||
**修复时间**:约5分钟(构建1分钟 + 推送1分钟 + 部署3分钟)
|
||
|
||
---
|
||
|
||
## 🔍 预防措施
|
||
|
||
### 1. Dockerfile检查清单
|
||
|
||
创建完整的文件复制清单:
|
||
```dockerfile
|
||
✅ COPY package*.json ./
|
||
✅ COPY prisma ./prisma/
|
||
✅ COPY dist ./dist/
|
||
✅ COPY config ./config/ # 不要遗漏!
|
||
❓ COPY public ./public/ # 如果有静态文件
|
||
❓ COPY scripts ./scripts/ # 如果有启动脚本
|
||
```
|
||
|
||
### 2. 本地测试流程
|
||
|
||
在推送镜像前,先在本地测试:
|
||
```bash
|
||
# 1. 构建镜像
|
||
docker build -t backend-test:local .
|
||
|
||
# 2. 本地运行测试
|
||
docker run -p 3001:3001 \
|
||
-e DATABASE_URL="..." \
|
||
-e JWT_SECRET="..." \
|
||
backend-test:local
|
||
|
||
# 3. 访问健康检查
|
||
curl http://localhost:3001/health
|
||
|
||
# 4. 确认无错误后再推送
|
||
```
|
||
|
||
### 3. CI/CD集成
|
||
|
||
建议在GitHub Actions中添加:
|
||
```yaml
|
||
- name: Build Docker Image
|
||
run: docker build -t backend:${{ github.sha }} .
|
||
|
||
- name: Test Docker Image
|
||
run: |
|
||
docker run -d -p 3001:3001 backend:${{ github.sha }}
|
||
sleep 10
|
||
curl http://localhost:3001/health
|
||
```
|
||
|
||
---
|
||
|
||
**文档创建时间**:2025-12-24
|
||
**维护人员**:运维团队
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|