Files
Neo-ZQYY/docs/prd/Neo_Specs/review-audit/P10-NS4-01.md
Neo 6f8f12314f feat: 累积功能变更 — 聊天集成、租户管理、小程序更新、ETL 增强、迁移脚本
包含多个会话的累积代码变更:
- backend: AI 聊天服务、触发器调度、认证增强、WebSocket、调度器最小间隔
- admin-web: ETL 状态页、任务管理、调度配置、登录优化
- miniprogram: 看板页面、聊天集成、UI 组件、导航更新
- etl: DWS 新任务(finance_area_daily/board_cache)、连接器增强
- tenant-admin: 项目初始化
- db: 19 个迁移脚本(etl_feiqiu 11 + zqyy_app 8)
- packages/shared: 枚举和工具函数更新
- tools: 数据库工具、报表生成、健康检查
- docs: PRD/架构/部署/合约文档更新

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-06 00:03:48 +08:00

108 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# P10-NS4-01角色权限管理的 CRUD 界面规范
## 简要结论
- 状态:⚠️ 部分解决
- 数据库层已建立完整的 RBAC 三表模型roles / permissions / role_permissions后端已实现权限查询与校验中间件但缺少角色权限管理的 CRUD 界面——无法通过 UI 创建角色、分配权限、展示权限树。
## 详细审查
### 数据库端
auth schema 中已存在完整的 RBAC 表结构(来源:`docs/database/ddl/zqyy_app__auth.sql`
| 表名 | 用途 | 关键字段 |
|------|------|----------|
| `auth.roles` | 角色定义 | id, code, name, description |
| `auth.permissions` | 权限定义 | id, code, name, description |
| `auth.role_permissions` | 角色-权限映射(多对多) | role_id → roles.id, permission_id → permissions.id |
| `auth.user_site_roles` | 用户-门店-角色绑定 | user_id, site_id, role_id → roles.id |
| `auth.tenant_admins` | 租户管理员账号 | managed_site_idsBIGINT[])控制管辖范围 |
种子数据已预置 4 个角色coach / staff / site_admin / tenant_admin和 5 个权限view_tasks / view_board / view_board_finance / view_board_customer / view_board_coach以及 14 条角色-权限映射。
结论:数据库层 RBAC 模型完整,支持角色-权限多对多关系。`tenant_admins` 表通过 `managed_site_ids` 数组实现租户级/店铺级管理员的管辖范围控制,与 P10 spec 中描述的两种权限级别一致。
### 后端代码
**已实现:**
1. **权限查询服务**`apps/backend/app/services/role.py`
- `get_user_permissions(user_id, site_id)` — 三表联查获取用户权限 code 列表
- `get_user_sites(user_id)` — 获取用户关联的所有店铺及角色
- `check_user_has_site_role(user_id, site_id)` — 检查用户是否有角色绑定
2. **权限校验中间件**`apps/backend/app/middleware/permission.py`
- `require_permission(*codes)` — 依赖注入工厂,校验用户 approved 状态 + 指定权限
- `require_approved()` — 仅校验 approved 状态
- 已在看板路由(`xcx_board.py`)中实际使用:`view_board_finance``view_board_customer``view_board_coach`
3. **租户管理员 CRUD**`apps/backend/app/routers/admin_tenant_admins.py`
- 列表(分页+搜索、创建、编辑display_name / managed_site_ids / is_active、重置密码
- 这是管理员账号的 CRUD不是角色/权限的 CRUD
4. **租户管理员认证**`apps/backend/app/auth/tenant_admins.py` + `tenant_auth.py`
- JWT 签发含 managed_site_idsaud=tenant-admin 与小程序隔离
- `site_filter_clause()` / `verify_site_access()` 实现数据隔离
**未实现:**
-`roles` 表的 CRUD API创建角色、编辑角色、删除角色
-`permissions` 表的 CRUD API创建权限、编辑权限、删除权限
-`role_permissions` 映射的管理 API为角色分配/取消权限)
- 角色和权限数据完全依赖种子 SQL 预置,无法通过 API 动态管理
### 前端代码
**tenant-admin租户管理后台页面清单**
- `Login/` — 登录页 ✅
- `UserApproval/` — 用户审核 ✅
- `UserManagement/` — 用户管理 ✅
- `ExcelUpload/` — Excel 上传 ✅
- `RetentionClues/` — 维客线索管理 ✅
- ❌ 无角色管理页面
- ❌ 无权限管理页面
- ❌ 无权限树组件
**tenant-admin 组件清单:**
- `DiffTable/` — 冲突 diff 交互 ✅
- `ClueEditor/` — 线索编辑 ✅
- `SiteSelector/` — 门店选择器 ✅
- ❌ 无 PermissionTree / RoleEditor 等权限管理组件
**admin-web系统管理后台**
- `TenantAdmins/index.tsx` — 租户管理员 CRUD 页面 ✅
- 功能:列表(分页+搜索)、创建 Modal用户名/密码/显示名称/tenantId/managedSiteIds、编辑 Modal显示名称/managedSiteIds/isActive、重置密码 Modal
- ❌ 无角色选择/分配功能
- ❌ 无权限树展示
### 差距分析
| P10 标杆要求 | 当前实现 | 差距 |
|-------------|---------|------|
| 租户级管理员(管辖所有店铺) | ✅ managed_site_ids 数组控制 | 无 |
| 店铺级管理员(只管指定 site_id | ✅ managed_site_ids 数组控制 | 无 |
| 角色定义coach/staff/site_admin/tenant_admin | ✅ 种子数据预置 | 无法动态增删改 |
| 权限定义5 个 view_* 权限) | ✅ 种子数据预置 | 无法动态增删改 |
| 角色-权限映射 | ✅ 种子数据预置 14 条映射 | 无法通过 UI 调整 |
| 创建角色界面 | ❌ 不存在 | 完全缺失 |
| 分配权限界面 | ❌ 不存在 | 完全缺失 |
| 权限树展示 | ❌ 不存在 | 完全缺失 |
| 用户审核时分配角色 | ⚠️ 部分 | 审核通过时可指定 role但角色列表硬编码非从 roles 表动态读取 |
核心差距RBAC 数据模型已就绪权限校验链路已打通roles → role_permissions → permissions → middleware但管理侧完全依赖种子数据和数据库直接操作缺少面向管理员的 CRUD 界面。这意味着:
- 新增角色需要写 SQL
- 调整角色权限需要写 SQL
- 管理员无法自助查看权限分配全貌
### 建议
1. **短期(低成本)**:在 admin-web 的 TenantAdmins 页面增加"角色权限"只读展示面板,展示当前 4 个角色及其权限映射,让管理员了解权限全貌。无需 CRUD因为当前角色/权限体系相对固定。
2. **中期(按需)**:如果业务发展需要动态角色管理(如新增"前台"角色、调整权限粒度),则需要:
- 后端:新增 `admin_roles.py` 路由roles CRUD + role_permissions 分配)
- 前端:在 admin-web 新增 RoleManagement 页面(角色列表 + 权限树 Ant Design Tree 组件 + 分配交互)
- 在 tenant-admin 的用户审核/管理页面中,角色选择改为从 API 动态获取
3. **权限树组件规范**:如需实现,建议使用 Ant Design `<Tree>` 组件,数据结构为权限按功能模块分组(如"看板"下挂 view_board_*),支持勾选/取消勾选批量分配。
4. **NS4 spec 补充**:在 NS4 文档中明确说明当前权限模型为"预置角色 + 种子数据"模式,角色/权限的动态管理界面作为后续迭代项,避免与 P10 标杆文件的隐含期望产生歧义。