# 问题陈述 将 `upms` 从当前“基础演示能力”拆分为可支撑多租户教学业务的基础域模块,承接组织权限、班级关系、文件资源、站内信,并为 `auth/course/question/gateway` 提供统一主体与隔离上下文。 ## 当前状态(已确认) * 架构文档把 `upms` 定位为租户/组织/用户/角色/菜单的平台能力层,且要求核心表统一保留租户隔离字段。参考 `docs/architecture/logical-view.md (2-13)`、`docs/architecture/logical-view.md (74-77)`。 * API 设计中 `upms` 当前冻结接口仅覆盖 routes/currentUser/areas/tenants/departments,文件与消息接口仍为“建议补充”。参考 `docs/architecture/api-design.md (17-29)`。 * 代码层 `upms` 仅有查询接口,且服务实现为硬编码返回,未接数据库。参考 `backend/upms/src/main/java/com/k12study/upms/controller/UpmsController.java (1-52)`、`backend/upms/src/main/java/com/k12study/upms/service/impl/UpmsQueryServiceImpl.java (1-132)`、`backend/upms/src/main/resources/application.yml (1-18)`。 * `init` 已具备班级主表/成员表/班级课程关系、文件表、消息主表与收件人表等基础结构,可在设计阶段调整。参考 `init/pg/upms/10_create_upms_tables.sql (39-434)`。 ## 模块拆分与设计细节 ### 1) 子模块边界 * `upms-identity`:租户、组织、用户、角色、菜单、角色授权。 * `upms-class`:班级、班级成员、班级与课程关系(作为 class authoritative source)。 * `upms-file`:统一文件元数据、上传登记、跨域引用约束。 * `upms-message`:站内信投递、已读/点击回执、业务跳转。 * `upms-context`:向网关与业务域提供用户上下文(tenant/dept/roleCodes/clientType)。 ### 2) API 设计增补 * 保留现有 `/api/upms/routes|users/current|areas|tenants|departments`,其中 `routes` 仅用于 Web 端动态路由管理。 * 新增并冻结: * 班级:`/api/upms/classes`、`/api/upms/classes/{id}/members`、`/api/upms/classes/{id}/courses` * 文件:`POST /api/upms/files/upload`、`GET /api/upms/files/{fileId}` * 消息:`GET /api/upms/messages/inbox`、`POST /api/upms/messages/{messageId}/read` * 小程序端当前不做动态路由管理;仅保留业务可见性相关查询能力(如课堂练习/课后作业可见对象)。 ### 3) 数据与隔离策略 * 统一强制查询键:`tenant_id + (tenant_path/dept_path)`;所有列表与详情接口默认附加租户过滤。 * 身份区分以角色体系为准:在 `upms` 侧补齐用户-角色映射(建议新增 `tb_sys_user_role`),以 `role` 作为鉴权与端侧准入主依据;`client_scope` 用于端类型控制。 * 在 `tb_sys_user` 增补手机号绑定字段(如 `mobile_phone/mobile_verified_at/mobile_bind_status`);学生手机号在租户内唯一,用于手动登录主凭据。 * 小程序端仅开放 `STUDENT` 角色;`TEACHER/ORG_ADMIN` 角色不开放小程序登录授权。 * `tb_school_class_course_rel` 增补可见性配置(如 `mini_visible_scope`),用于后续小程序“仅课堂练习+课后作业”过滤联动。 * 为消息与文件接口建立“跨租户不可见 + 对象存在性校验”统一拦截器。 ## 问题点与风险 * 现状 `upms` 返回硬编码数据,和 SQL 实体脱节,后续联调会出现“接口有值但数据库无一致性”风险。 * 现有上下文仅传 `tenant_id/dept_id`,缺 `tenant_path/adcode/roleCodes/clientType`,不利于层级隔离与端侧差异控制。参考 `backend/common/common-core/src/main/java/com/k12study/common/core/constants/SecurityConstants.java (1-13)`。 * 班级实体虽已落表,但缺 API 与领域服务,`question` 当前仍需通过弱关联字段投放对象,存在错投/越权风险。 * 站内信与文件在产品链路中为关键公共能力,但目前仅有表结构和种子,缺完整业务闭环。 * 若 `tb_sys_user` 缺手机号唯一约束与换绑审计,会放大共享设备场景下的账号冒用与追责困难。 ## 已确定的实现决策 * 班级由 `upms` 完全统一托管,其他业务域仅通过 `class_id` 关联。 * `roleCodes/clientType` 放入 JWT claims,同时在 `upms` 角色关系中保留权威数据。 * `upms` 仅承担 Web 端路由资源管理;小程序端当前不做动态路由。 * 学生手机号换绑不启用“原手机号确认 + 班级归属校验 + 冷静期”三段式流程,采用手机号验证或线下联系老师处理。