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,39 +1,39 @@
|
||||
# 2026-01-11 数据库事故总结
|
||||
|
||||
> 事故等级: **严重**
|
||||
> 蜿醍函譌カ髣エ: 2026-01-11 郤?11:00
|
||||
> 諱「螟肴慮髣エ: 2026-01-11 郤?13:00
|
||||
> 蠖ア蜩崎激蝗エ: 豬玖ッ慕識蠅<E8AD98>焚謐ョ蠎?
|
||||
> 发生时间: 2026-01-11 约 11:00
|
||||
> 恢复时间: 2026-01-11 约 13:00
|
||||
> 影响范围: 测试环境数据库
|
||||
|
||||
---
|
||||
|
||||
## 1. 事故概述
|
||||
|
||||
蝨ィ蠑蜿題ソ占是邂。逅<EFBFBD>ォッ<EFBFBD><EFBFBD>DMIN<EFBFBD>画ィ。蝮玲慮<EFBFBD>御クコ莠<EFBFBD>峩譁ー逕ィ謌キ陦ィ扈捺桷<EFBFBD>域キサ蜉<EFBFBD>謇区惻蜿キ逋サ蠖輔∫ァ滓姐蜈ウ閨皮ュ牙ュ玲ョオ<EFBFBD>会シ碁漠隸ッ菴ソ逕ィ莠?`prisma db push --force-reset` 蜻ス莉、<E88E89>悟ッシ閾エ謨ー謐ョ蠎謎クュ髱<EFBDAD> Prisma 邂。逅<EFBDA1>噪蟇ケ雎。陲ォ蛻<EFBDAB>髯、縲?
|
||||
在开发运营管理端(ADMIN)模块时,为了更新用户表结构(添加手机号登录、租户关联等字段),错误使用了 `prisma db push --force-reset` 命令,导致数据库中非 Prisma 管理的对象被删除。
|
||||
|
||||
---
|
||||
|
||||
## 2. 莠区腐譌カ髣エ郤?
|
||||
## 2. 事故时间线
|
||||
|
||||
| 时间 | 事件 |
|
||||
|------|------|
|
||||
| 11:00 | 菫ョ謾ケ schema.prisma<EFBFBD>梧キサ蜉<EFBFBD>譁ー逧<EFBFBD>畑謌キ蟄玲ョオ蜥檎ァ滓姐陦?|
|
||||
| 11:00 | 修改 schema.prisma,添加新的用户字段和租户表 |
|
||||
| 11:05 | 执行 `prisma db push`,报错:现有数据与新 schema 冲突 |
|
||||
| 11:10 | **髞呵ッッ蜀ウ遲<EFBFBD>**<EFBFBD>壽鴬陦?`prisma db push --force-reset` |
|
||||
| 11:15 | 謨ー謐ョ蠎楢「ォ驥咲スョ<EFBFBD>碁撼 Prisma 邂。逅<EFBDA1>噪蟇ケ雎。荳「螟?|
|
||||
| 11:10 | **错误决策**:执行 `prisma db push --force-reset` |
|
||||
| 11:15 | 数据库被重置,非 Prisma 管理的对象丢失 |
|
||||
| 11:20 | 执行 seed 脚本,补充基础数据 |
|
||||
| 11:30 | 用户报告:后端启动报错,pg-boss 队列无法注册 |
|
||||
| 11:45 | 诊断:`platform_schema.create_queue()` 函数丢失 |
|
||||
| 12:00 | 从备份文件提取并恢复 pg-boss 函数 |
|
||||
| 12:15 | 隸頑妙<EFBFBD>啻platform_schema.job_common` 陦ィ荳「螟?|
|
||||
| 12:20 | 莉主、<EFBFBD>サス譁<EFBFBD>サカ謠仙叙蟷カ諱「螟<EFBFBD> job_common 陦?|
|
||||
| 12:15 | 诊断:`platform_schema.job_common` 表丢失 |
|
||||
| 12:20 | 从备份文件提取并恢复 job_common 表 |
|
||||
| 12:30 | 用户报告:RVW 模块上传失败 |
|
||||
| 12:35 | 诊断:mock 用户 `user-mock-001` 丢失 |
|
||||
| 12:40 | 蛻帛サコ mock 逕ィ謌キ蛻?public.users 蜥?platform_schema.users |
|
||||
| 12:50 | 逕ィ謌キ謚・蜻奇シ啀KB 讓。蝮怜<E89DAE>蟒コ遏・隸<EFBDA5>コ灘、ア雍?|
|
||||
| 12:55 | 隸頑妙<EFBFBD>壼、夜醗郤ヲ譚滂シ碁怙隕∝惠荳、荳ェ schema 逧?users 陦ィ驛ス譛?mock 逕ィ謌キ |
|
||||
| 12:40 | 创建 mock 用户到 public.users 和 platform_schema.users |
|
||||
| 12:50 | 用户报告:PKB 模块创建知识库失败 |
|
||||
| 12:55 | 诊断:外键约束,需要在两个 schema 的 users 表都有 mock 用户 |
|
||||
| 13:00 | **系统恢复正常** |
|
||||
| 13:15 | 螳梧紛螟<EFBFBD>サス蠖灘燕謨ー謐ョ蠎?|
|
||||
| 13:15 | 完整备份当前数据库 |
|
||||
|
||||
---
|
||||
|
||||
@@ -41,41 +41,41 @@
|
||||
|
||||
### 3.1 直接原因
|
||||
|
||||
菴ソ逕ィ莠<EFBFBD>些髯ゥ蜻ス莉?`prisma db push --force-reset`<EFBFBD>瑚ッ・蜻ス莉、莨夲シ<EFBFBD>
|
||||
使用了危险命令 `prisma db push --force-reset`,该命令会:
|
||||
1. 删除数据库中所有表
|
||||
2. 譬ケ謐ョ schema.prisma 驥肴眠蛻帛サコ陦?
|
||||
3. **荳堺シ<EFBFBD>**諱「螟<EFBDA2> Prisma 荳咲ョ。逅<EFBDA1>噪蟇ケ雎。<E99B8E>亥<EFBFBD>謨ー縲∵汾莠幄。ィ<EFBDA1>?
|
||||
2. 根据 schema.prisma 重新创建表
|
||||
3. **不会**恢复 Prisma 不管理的对象(函数、某些表)
|
||||
|
||||
### 3.2 深层原因
|
||||
|
||||
1. **遏・隸<EFBFBD>峇蛹コ**<EFBFBD>壻ク堺コ<EFBFBD>ァ」 Prisma 逧<>ョ。逅<EFBDA1>セケ逡?
|
||||
- Prisma 蜿ェ邂。逅?schema.prisma 荳ュ螳壻ケ臥噪蟇ケ雎。
|
||||
- pg-boss 霑占。梧慮蛻帛サコ逧<EFBFBD><EFBFBD>謨ー蜥瑚。ィ荳榊惠 Prisma 邂。逅<EFBDA1>激蝗エ蜀?
|
||||
1. **知识盲区**:不了解 Prisma 的管理边界
|
||||
- Prisma 只管理 schema.prisma 中定义的对象
|
||||
- pg-boss 运行时创建的函数和表不在 Prisma 管理范围内
|
||||
|
||||
2. **郛コ荵丞、<EFBFBD>サス諢剰ッ<EFBFBD>**<EFBFBD>壽桃菴懷燕豐。譛牙、<EFBFBD>サス謨ー謐ョ蠎?
|
||||
2. **缺乏备份意识**:操作前没有备份数据库
|
||||
|
||||
3. **缺乏规范文档**:没有数据库操作规范指导
|
||||
|
||||
### 3.3 Prisma 管理边界
|
||||
|
||||
```
|
||||
笏娯楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
笏? 謨ー謐ョ蠎灘ョ梧紛蜀<EFBFBD>ョ? 笏?
|
||||
笏? 笏娯楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏? 笏?
|
||||
笏? 笏? Prisma 邂。逅<EFBFBD>噪蟇ケ雎? 笏? 笏?
|
||||
笏? 笏? - schema.prisma 荳ュ螳壻ケ臥噪 model 笏? 笏?
|
||||
笏? 笏? - schema.prisma 荳ュ螳壻ケ臥噪 enum 笏? 笏?
|
||||
笏? 笏? - Prisma 蛻帛サコ逧<EFBFBD>エ「蠑募柱郤ヲ譚<EFBFBD> 笏? 笏?
|
||||
笏? 笏披楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏? 笏?
|
||||
笏? 笏?
|
||||
笏? 笏娯楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏? 笏?
|
||||
笏? 笏? Prisma 荳咲ョ。逅<EFBFBD>噪蟇ケ雎。 笞<><E7AC9E><EFBFBD> 笏? 笏?
|
||||
笏? 笏? - pg-boss 蛻帛サコ逧?job_common 陦? 笏? 笏?
|
||||
笏? 笏? - pg-boss 蛻帛サコ逧?create_queue() 蜃ス謨ー 笏? 笏?
|
||||
笏? 笏? - pg-boss 蛻帛サコ逧?delete_queue() 蜃ス謨ー 笏? 笏?
|
||||
笏? 笏? - 謇句勘蛻帛サコ逧<EFBDBA>ュ伜お霑<E3818A>ィ九∬ァヲ蜿大勣縲∬ァ<E288AC><EFBDA7>? 笏? 笏?
|
||||
笏? 笏披楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏? 笏?
|
||||
笏披楳笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏笏?
|
||||
┌─────────────────────────────────────────────────────────────┐
|
||||
│ 数据库完整内容 │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ Prisma 管理的对象 │ │
|
||||
│ │ - schema.prisma 中定义的 model │ │
|
||||
│ │ - schema.prisma 中定义的 enum │ │
|
||||
│ │ - Prisma 创建的索引和约束 │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌─────────────────────────────────────────────────────┐ │
|
||||
│ │ Prisma 不管理的对象 ⚠️ │ │
|
||||
│ │ - pg-boss 创建的 job_common 表 │ │
|
||||
│ │ - pg-boss 创建的 create_queue() 函数 │ │
|
||||
│ │ - pg-boss 创建的 delete_queue() 函数 │ │
|
||||
│ │ - 手动创建的存储过程、触发器、视图 │ │
|
||||
│ └─────────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
@@ -84,23 +84,23 @@
|
||||
|
||||
### 4.1 数据丢失
|
||||
|
||||
| 鬘ケ逶ョ | 迥カ諤?| 隸エ譏<EFBDB4> |
|
||||
| 项目 | 状态 | 说明 |
|
||||
|------|------|------|
|
||||
| 用户数据 | ⚠️ 丢失后通过 seed 恢复 | 测试数据,可接受 |
|
||||
| 荳壼苅讓。蝮苓。ィ扈捺<EFBFBD>?| 笨?譛ェ蜿怜スア蜩<EFBDB1> | Prisma 豁」遑ョ驥榊サコ |
|
||||
| 业务模块表结构 | ✅ 未受影响 | Prisma 正确重建 |
|
||||
| 业务模块数据 | ⚠️ 清空 | 测试数据,可接受 |
|
||||
| pg-boss 蜃ス謨ー | 笶?荳「螟ア | 髴謇句勘諱「螟<EFBDA2> |
|
||||
| job_common 陦?| 笶?荳「螟ア | 髴謇句勘諱「螟<EFBDA2> |
|
||||
| pg-boss 函数 | ❌ 丢失 | 需手动恢复 |
|
||||
| job_common 表 | ❌ 丢失 | 需手动恢复 |
|
||||
|
||||
### 4.2 功能影响
|
||||
|
||||
| 功能 | 影响 | 恢复措施 |
|
||||
|------|------|----------|
|
||||
| 蜷守ォッ蜷ッ蜉ィ | 笶?螟ア雍・ | 諱「螟<EFBDA2> pg-boss 蜃ス謨ー蜥瑚。ィ |
|
||||
| RVW 鬚<EFBFBD>ョ。遞?| 笶?500髞呵ッッ | 蛻帛サコ mock 逕ィ謌キ |
|
||||
| PKB 遏・隸<EFBFBD>コ?| 笶?500髞呵ッッ | 蛻帛サコ mock 逕ィ謌キ |
|
||||
| ASL 譁<EFBFBD>鍵遲幃?| 笨?豁」蟶ク | - |
|
||||
| DC 謨ー謐ョ貂<EFBFBD>エ<EFBFBD> | 笨?豁」蟶ク | - |
|
||||
| 后端启动 | ❌ 失败 | 恢复 pg-boss 函数和表 |
|
||||
| RVW 预审稿 | ❌ 500错误 | 创建 mock 用户 |
|
||||
| PKB 知识库 | ❌ 500错误 | 创建 mock 用户 |
|
||||
| ASL 文献筛选 | ✅ 正常 | - |
|
||||
| DC 数据清洗 | ✅ 正常 | - |
|
||||
|
||||
---
|
||||
|
||||
@@ -109,7 +109,7 @@
|
||||
### 5.1 恢复 pg-boss 对象
|
||||
|
||||
```bash
|
||||
# 諱「螟<EFBFBD> job_common 陦?
|
||||
# 恢复 job_common 表
|
||||
npx prisma db execute --file restore_job_common.sql --schema prisma/schema.prisma
|
||||
|
||||
# 恢复 pg-boss 函数
|
||||
@@ -130,9 +130,9 @@ VALUES ('user-mock-001', '13800000000', ..., 'tenant-mock-001', ...);
|
||||
|
||||
### 5.3 恢复文件清单
|
||||
|
||||
| 譁<EFBFBD>サカ | 逕ィ騾?| 菴咲スョ |
|
||||
| 文件 | 用途 | 位置 |
|
||||
|------|------|------|
|
||||
| `restore_job_common.sql` | 諱「螟<EFBFBD> job_common 陦?| backend/ |
|
||||
| `restore_job_common.sql` | 恢复 job_common 表 | backend/ |
|
||||
| `restore_pgboss_functions.sql` | 恢复 pg-boss 函数 | backend/ |
|
||||
| `create_mock_user.sql` | 创建 public.users mock 用户 | backend/ |
|
||||
| `create_mock_user_platform.sql` | 创建 platform_schema.users mock 用户 | backend/ |
|
||||
@@ -141,51 +141,51 @@ VALUES ('user-mock-001', '13800000000', ..., 'tenant-mock-001', ...);
|
||||
|
||||
## 6. 改进措施
|
||||
|
||||
### 6.1 遶句叉謗ェ譁ス<EFBFBD>亥キイ螳梧<EFBFBD><EFBFBD>?
|
||||
### 6.1 立即措施(已完成)
|
||||
|
||||
- [x] 蛻帛サコ謨ー謐ョ蠎灘、<EFBFBD>サ?`backup_20260111_131506.sql`
|
||||
- [x] 创建数据库备份 `backup_20260111_131506.sql`
|
||||
- [x] 更新 schema.prisma 添加警告注释
|
||||
- [x] 创建恢复脚本文件
|
||||
- [x] 郛門<EFBFBD>謨ー謐ョ蠎灘シ蜿題ァ<EFBFBD>激譁<EFBFBD>。?
|
||||
- [x] 编写数据库开发规范文档
|
||||
|
||||
### 6.2 短期措施(本周)
|
||||
|
||||
- [ ] 将恢复脚本添加到版本控制
|
||||
- [ ] 蝨?CI/CD 荳ュ豺サ蜉<EFBFBD>謨ー謐ョ蠎灘、<EFBFBD>サス豁・鬪、
|
||||
- [ ] 在 CI/CD 中添加数据库备份步骤
|
||||
- [ ] 团队培训:Prisma 使用规范
|
||||
|
||||
### 6.3 长期措施
|
||||
|
||||
- [ ] 建立自动备份机制
|
||||
- [ ] 謨ー謐ョ蠎灘序譖エ螳。謇ケ豬∫ィ?
|
||||
- [ ] 数据库变更审批流程
|
||||
- [ ] 定期演练数据恢复
|
||||
|
||||
---
|
||||
|
||||
## 7. 经验教训
|
||||
|
||||
### 7.1 謚譛ッ螻る<EFBFBD>?
|
||||
### 7.1 技术层面
|
||||
|
||||
1. **莠<EFBFBD>ァ」蟾・蜈キ霎ケ逡<EFBFBD>**<EFBFBD>壽ッ丈クェ蟾・蜈キ驛ス譛牙<EFBFBD>邂。逅<EFBFBD>激蝗エ<EFBFBD>碁怙隕∽コ<EFBFBD>ァ」霎ケ逡?
|
||||
2. **螟<EFBFBD>サス莨伜<EFBFBD>**<EFBFBD>壻ササ菴墓焚謐ョ蠎捺桃菴懷燕蠢<EFBFBD>。サ螟<EFBFBD>サ?
|
||||
3. **蠅樣㍼蜿俶峩**<EFBFBD>壻シ伜<EFBFBD>菴ソ逕?`prisma migrate dev` 閠碁撼 `db push`
|
||||
1. **了解工具边界**:每个工具都有其管理范围,需要了解边界
|
||||
2. **备份优先**:任何数据库操作前必须备份
|
||||
3. **增量变更**:优先使用 `prisma migrate dev` 而非 `db push`
|
||||
|
||||
### 7.2 流程层面
|
||||
|
||||
1. **荳画晏錘陦?*<2A>壽鴬陦悟些髯ゥ蜻ス莉、蜑榊、夐琉蜃<E79089>荳ェ髣ョ鬚<EFBDAE>
|
||||
1. **三思后行**:执行危险命令前多问几个问题
|
||||
2. **文档先行**:操作规范文档要提前准备
|
||||
3. **蠢ォ騾溷桃蠎?*<2A>壼書邇ー髣ョ鬚伜錘蠢ォ騾溯ッ頑妙蜥梧△螟<E296B3>
|
||||
3. **快速响应**:发现问题后快速诊断和恢复
|
||||
|
||||
### 7.3 团队层面
|
||||
|
||||
1. **遏・隸<EFBFBD><EFBFBD>莠ォ**<EFBFBD>壽橿譛ッ扈城ェ碁怙隕∝所譌カ豐画キ蜥悟<EFBFBD>莠?
|
||||
1. **知识共享**:技术经验需要及时沉淀和分享
|
||||
2. **Code Review**:数据库操作应有审批机制
|
||||
|
||||
---
|
||||
|
||||
## 8. 相关文档
|
||||
|
||||
- [謨ー謐ョ蠎灘シ蜿題ァ<EFBFBD>激](../04-蠑蜿題ァ<E9A18C><EFBDA7>?09-謨ー謐ョ蠎灘シ蜿題ァ<E9A18C><EFBDA7>?md)
|
||||
- [数据库开发规范](../04-开发规范/09-数据库开发规范.md)
|
||||
- [Prisma Schema 文件](../../backend/prisma/schema.prisma)
|
||||
- [备份文件](../../backup_20260111_131506.sql)
|
||||
|
||||
@@ -200,8 +200,7 @@ VALUES ('user-mock-001', '13800000000', ..., 'tenant-mock-001', ...);
|
||||
|
||||
---
|
||||
|
||||
> **螢ー譏<EFBFBD>**<2A>壽悽谺。莠区腐蜿醍函蝨ィ豬玖ッ慕識蠅<E8AD98>シ梧悴蠖ア蜩咲函莠ァ謨ー謐ョ縲ゆス<E38286>垓髴イ逧<EFBDB2>琉鬚伜酔譬キ蜿ッ閭ス蝨ィ逕滉コァ邇ッ蠅<EFBDAF>書逕滂シ碁怙隕<E68099>ォ伜コヲ驥崎ァ<E5B48E>?
|
||||
|
||||
> **声明**:本次事故发生在测试环境,未影响生产数据。但暴露的问题同样可能在生产环境发生,需要高度重视。
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user