feat: add tenant class student scopes

This commit is contained in:
Codex
2026-06-29 00:50:22 +08:00
parent b262e87af9
commit 61240c5833
12 changed files with 1172 additions and 25 deletions

View File

@@ -1,6 +1,6 @@
# 后端当前能力盘点
更新时间2026-06-28
更新时间2026-06-29
当前后端已经完成商用 SaaS 题库系统的主干骨架PostgreSQL 多租户 schema、Node.js 业务 API、PocketBase 数据导入工具、本地 seed、API 集成测试和对象存储签名 provider。
@@ -42,7 +42,8 @@
| 微信网页/QQ OAuth | 待补齐 | 目前仍是 placeholder需要 code 换 token、回调域名、账号合并和审计 |
| 平台管理员鉴权 | 可联调 | 已支持平台管理员 Supabase JWT`x-platform-admin-key` 仅作本地/迁移期兼容且可通过配置禁用 |
| 租户角色权限 | 可联调 | `tenant_memberships.role + permissions + role_template_id`,接口有权限点校验 |
| 自定义角色模板 | 可联调 | `tenant_role_templates` + `/api/tenant-admin/role-templates`,支持权限、菜单、模块、字段、数据范围配置;前端 UI 和班级/学生范围继续补 |
| 自定义角色模板 | 可联调 | `tenant_role_templates` + `/api/tenant-admin/role-templates`,支持权限、菜单、模块、字段、数据范围配置;前端 UI 继续补 |
| 班级/教师/学生范围权限 | 可联调 | `tenant_classes``tenant_class_members` + `/api/tenant-admin/classes``classes/members``students``teachers`;教师默认只看自己负责班级,字段权限可脱敏学生手机号 |
## 学生端题库主链路
@@ -114,6 +115,7 @@
| 活动、Banner、FAQ、公告 | 可联调 | `/api/tenant-admin/banners``faqs``announcements` |
| 激活码批次/生成/列表 | 可联调 | `/api/tenant-admin/code-batches``activation-codes` |
| 成员/角色权限/审计 | 可联调 | `/api/tenant-admin/members``permissions``role-templates``audit-logs` |
| 班级/学生/教师管理 | 可联调 | `/api/tenant-admin/classes``classes/members``students``teachers`,支持班级范围权限和审计 |
| 平台租户/套餐/订阅/账单/用量 | 可联调 | `/api/platform-admin/*` |
| 数据看板聚合接口 | 待补齐 | 表基础已有,缺完整 dashboard API |

View File

@@ -14,11 +14,12 @@
- `commerce`:订单、支付确认、激活码兑换、权益查询。
- `referral`:销售/代理邀请码、首绑客资保护、销售统计、团队关系、CRM 队列。
- `platform-admin`平台方租户管理、SaaS 套餐、订阅、账单、服务费收款、使用量。
- `tenant-admin`:租户资料、品牌、公开设置、域名、支付账户、登录 provider、私密密钥掩码、活动内容、激活码批次、优惠券、成员管理、角色模板、权限矩阵、审计查询。
- `tenant-admin`:租户资料、品牌、公开设置、域名、支付账户、登录 provider、私密密钥掩码、活动内容、激活码批次、优惠券、成员管理、角色模板、班级/学生/教师范围权限、权限矩阵、审计查询。
- `tenant-content`:租户后台内容入口、任意深度分类树、考试意向标记、题目集合、练习蓝图、题目、视频、分数线、单词、知识手册、资料资源、题目/单词/知识手册 JSON 导入维护。
- `tenant`:域名/租户解析。
- 鉴权上下文已支持 Supabase Auth JWT 和迁移期 `tk_` session 双入口JWT 通过 `auth.users.id -> platform_users.auth_user_id -> tenant_memberships` 映射业务用户和租户;平台管理员 JWT 已可访问平台后台。
- 租户自定义角色模板已落库:`tenant_role_templates` 支持权限、菜单、模块、字段和数据范围配置,成员可通过 `role_template_id` 绑定模板。
- 班级与学生范围权限已落库:`tenant_classes``tenant_class_members` 支持教师/班主任/助教/学生分组,教师按负责班级查看学生,字段权限可脱敏学生手机号。
- `learning` 已接入商用访问控制免费用户每日题量、SVIP 范围、SVIP-only 内容、答题 session 快照保护由后端强制执行。
- `src/services/supabaseApi.ts` 已加入新 API 客户端方法,供旧 Web 逐步替换和后续 Taro 复用。
- 已新增 `npm run db:smoke-seed`,用于 `supabase:reset` 后恢复最小烟测数据。
@@ -135,6 +136,18 @@ GET /api/crm/config
PUT /api/crm/config
GET /api/crm/queue
GET /api/tenant-admin/permissions
GET /api/tenant-admin/role-templates
PUT /api/tenant-admin/role-templates
POST /api/tenant-admin/role-templates/disable
GET /api/tenant-admin/classes
PUT /api/tenant-admin/classes
POST /api/tenant-admin/classes/disable
GET /api/tenant-admin/classes/members
PUT /api/tenant-admin/classes/members
POST /api/tenant-admin/classes/members/remove
GET /api/tenant-admin/students
PUT /api/tenant-admin/students
GET /api/tenant-admin/teachers
GET /api/tenant-admin/overview
PUT /api/tenant-admin/branding
PUT /api/tenant-admin/settings
@@ -177,7 +190,8 @@ GET /api/tenant-admin/audit-logs
- 激活码兑换和支付成功都走同一套 `grantSvipEntitlement` 权益开通逻辑。
- 租户支付账户、短信、OAuth 登录配置接口只保存公开配置;密钥进入 `app_private.tenant_secrets` 或生产 KMS/VaultAPI 只返回 `secretRef` 和掩码状态。
- `tenant-admin` 采用角色默认权限 + `tenant_memberships.permissions` 覆盖的权限矩阵。成员可进入后台,但每个接口会校验具体权限点;学生和跨租户成员会被拒绝。
- 当前默认角色:`tenant_owner`/`tenant_admin` 全权限,`tenant_operator` 可维护内容和活动,`teacher` 可维护内容,`sales` 可维护激活码和优惠券,`agent` 只读部分兑换码/优惠券。
- 当前默认角色:`tenant_owner`/`tenant_admin` 全权限,`tenant_operator` 可维护内容和活动,`teacher` 可维护内容并按班级范围查看学生`sales` 可维护激活码和优惠券,`agent` 只读部分兑换码/优惠券。
- 班级学生 API 会按 `tenant_memberships.role_template_id -> tenant_role_templates.data_scope`、成员显式权限和 `tenant_class_members` 共同确定可见范围;非全局权限教师只能查看自己负责班级的学生。
- 销售/代理客资采用首绑保护:普通扫码/分享事件不会覆盖已有归属,只有具备 `referral:write` 的租户成员可手动强制补绑。
- CRM 当前完成配置、密钥入私密表、客资入队和队列查询;真实 webhook 发送、重试、签名在后续 `apps/worker` 中实现。
- 内容资源当前完成台账、租户后台维护、学生端 SVIP 下载权限,以及 `local_dev`、阿里云 OSS、腾讯 COS、Supabase Storage 的上传/下载签名 provider。真实对象存在性校验、PDF 预览渲染、防盗链、水印和大文件上传后 worker 校验仍需继续补。

View File

@@ -144,7 +144,7 @@ provider event id 幂等
| tenant_owner | `*` |
| tenant_admin | `*` |
| tenant_operator | 内容、营销、兑换码/优惠券只读、客资/CRM 只读 |
| teacher | 内容维护 |
| teacher | 内容维护、班级查看、学生查看 |
| sales | 兑换码、优惠券、客资 |
| agent | 兑换码/优惠券只读、本人的客资 |
| student | 无后台权限 |
@@ -156,11 +156,14 @@ provider event id 幂等
- 模板可保存 `menuPermissions``modulePermissions``fieldPermissions``dataScope`,供 Taro/管理台做菜单、模块、字段可见性和数据范围 UI。
- 模板含 `*``tenant_owner``tenant_admin` 等管理员级能力时,只有租户 owner 可创建或授予;普通租户管理员不能自造全权限模板。
- 角色模板创建、更新、禁用都会写入 `audit_logs`
- `tenant_classes``tenant_class_members` 提供班级、班主任、教师、助教、学生分组边界。
- 教师如无 `classes:write``students:write``members:read` 等全局管理权限,只能查看自己在 `tenant_class_members` 中负责的班级及这些班级下的学生;也可由角色模板 `dataScope.classIds` 显式限定。
- 学生手机号等敏感字段可由 `fieldPermissions` 控制,后端会对不可见字段返回 `null`,前端不得绕过其它接口补取。
后续要补:
- 前端角色模板配置 UI。
- 班级/教师/学生范围权限
- 更细的数据范围 UI例如地区、题库、销售团队、本人客资、班级学生组合规则
## 上线前安全验收清单
@@ -170,6 +173,7 @@ provider event id 幂等
- 跨租户学生读取题目/订单/资料返回拒绝。
- 销售只能查看自己权限范围内客资。
- 代理不能查看其他代理客资。
- 教师只能查看自己负责班级的学生,不能查看其它班级或跨租户学生。
- 教师不能修改租户商户密钥。
- 学生不能访问租户后台接口。
- 未开通权益不能下载 SVIP 资料或播放会员视频。

View File

@@ -1,6 +1,6 @@
# 后续开发 TODO
更新时间2026-06-22
更新时间2026-06-29
## 当前后端基线
@@ -17,6 +17,7 @@
- 模考报告与学习统计:`practice_session_reports/practice_session_report_sections` 支持交卷、评分、题型/小节统计、错题解析汇总和历史查询;`/api/learning/stats``trend``practice-sessions/history``wrong-questions/review-plan` 可支撑个人中心和学习报告基础页。
- 练习访问控制:`practice_daily_usage/practice_access_events` 支持免费每日额度、SVIP 范围校验、SVIP-only 内容拦截和答题 session 快照保护。
- 内容导入:题目、单词、知识手册 JSON 预览、校验、导入、幂等、审计。
- 租户组织范围:班级、班级成员、教师/班主任/助教/学生分组,教师按负责班级查看学生,字段权限可脱敏学生手机号。
- 本地验证:`npm run check:refactor` 已通过。
当前更适合进入前端联调前阅读的总览文档:
@@ -30,7 +31,7 @@
1. 生产鉴权
- 已支持 Supabase Auth JWT 和迁移期 `tk_` session 双入口JWT 通过 `auth.users.id -> platform_users.auth_user_id -> tenant_memberships` 映射业务身份。
- 已覆盖学生、租户管理员、平台管理员、错租户、坏签名、禁用 legacy header 的 API 集成测试。
- 已补自定义角色模板、菜单/模块/字段级配置 API继续补真实云端 Auth/JWKS 回归RLS 深测和班级/学生范围权限
- 已补自定义角色模板、菜单/模块/字段级配置 API、班级/学生范围权限;继续补真实云端 Auth/JWKS 回归RLS 深测。
- 前端联调时禁止继续使用 `x-user-id``x-tenant-id` 只作为租户上下文,不能作为身份依据。
2. 对象存储
@@ -88,7 +89,11 @@
- 套餐销量、运营动态、24h 活跃度、激活码使用情况。
- 销售/代理转化、分佣结算、客资跟进效果。
8. AI 择校推荐
8. 学生运营管理
- 已完成学生列表、学生资料维护、班级分组和教师范围可见。
- 继续补学生批量导入、禁用/恢复、批量分班、批量 CRM 推送、学习督导任务和家校/班主任备注。
9. AI 择校推荐
- 地区考试数据上下文。
- 学生输入 schema。
- AI 返回 JSON schema。
@@ -98,8 +103,9 @@
1. 自定义角色
- 已完成租户内角色模板、菜单可见、模块可见、字段级权限和权限变更审计基础 API。
- 已完成班级/教师/学生范围权限 API教师只能查看自己负责班级的学生。
- 继续补租户后台可视化配置 UI。
- 继续补班级/教师/学生范围权限
- 继续补更细的数据范围 UI例如地区、题库、销售团队、本人客资、班级学生组合规则
2. 主题系统
- 平台默认三套主题。

View File

@@ -171,6 +171,10 @@ tenant:<tenantId>:theme
| 激活码兑换 | `POST /api/commerce/activation-codes/redeem` |
| 个人中心 | `GET/PATCH /api/profile/me` |
| 销售分享 | `/api/referral/resolve``track-event``bind` |
| 租户班级 | `GET/PUT /api/tenant-admin/classes``POST /api/tenant-admin/classes/disable` |
| 班级成员 | `GET/PUT /api/tenant-admin/classes/members``POST /api/tenant-admin/classes/members/remove` |
| 租户学生 | `GET/PUT /api/tenant-admin/students` |
| 租户教师 | `GET /api/tenant-admin/teachers` |
## 练习访问控制契约
@@ -438,6 +442,8 @@ content_entries
- 小程序分享路径必须带 tenantCode 和 referral code。
- 用户首绑归属由后端保护,前端不要提供“换绑销售”入口。
- 管理后台菜单按 `GET /api/tenant-admin/permissions` 返回的 `current.permissions``current.templatePermissions``current.menuPermissions``current.modulePermissions` 渲染;接口权限仍以后端校验为准。
- 教师、班主任、助教类账号进入租户后台时,学生列表以 `GET /api/tenant-admin/students` 返回的 `scoped``items` 为准;前端不要自行用本地班级 ID 放大查询范围。
- 学生手机号、订单金额、客资归属等敏感字段按 `fieldPermissions` 控制显示;字段被后端返回为 `null` 时前端展示脱敏占位,不要从其它接口补取。
- H5 自定义域名下要注意缓存隔离,不能把 A 租户主题缓存用到 B 租户。
## 登录对接
@@ -602,6 +608,7 @@ GET /api/commerce/entitlements
- 品牌/主题/域名/公开设置
- 支付账户/登录 provider/密钥引用
- 用户与成员权限
- 班级/教师/学生:`/api/tenant-admin/classes``classes/members``students``teachers`
- 角色模板:`GET/PUT /api/tenant-admin/role-templates``POST /api/tenant-admin/role-templates/disable`
- 内容入口/分类树/题目集合/练习蓝图
- 题目/单词/知识手册/分数线/视频维护
@@ -609,7 +616,7 @@ GET /api/commerce/entitlements
- Banner/FAQ/公告/激活码/优惠券
- 销售/代理/CRM 队列
租户后台不应在前端自行决定权限;隐藏菜单只是体验优化,接口仍会校验权限。角色模板用于让租户配置“运营、教师、销售、代理”等自定义后台体验,成员绑定模板后,前端按模板的菜单/模块/字段权限渲染,后端按 permission keys 执行真正的访问控制。
租户后台不应在前端自行决定权限;隐藏菜单只是体验优化,接口仍会校验权限。角色模板用于让租户配置“运营、教师、销售、代理”等自定义后台体验,成员绑定模板后,前端按模板的菜单/模块/字段权限渲染,后端按 permission keys 执行真正的访问控制。班级/学生范围权限由后端根据角色、模板 `dataScope.classIds``tenant_class_members` 计算,教师默认只能看到自己负责班级。
## 联调顺序