基础平台实施规划

Summary

以正式鉴权规格和后台规格为输入,先交付注册—登录—身份—退出,再增量交付只读后台、账户管理、角色权限和菜单展示编辑。权限、数据与会话决策只在 core;web 使用已批准 Refine 方案。

本规划已进入产品实现:后端 52 项完整测试和真实 Docker 栈 12 项浏览器场景通过,证据见 evidence。前端框架 ADR-001、后端 ADR-002 已 Accepted,域名命名空间依 ADR-004 为 team.lab_edu。技术选择依据见 research;文档校验与产品测试分别保留证据。

Technical Context

项目 本次方案 权威与状态
core [APPROVED,原 INFERRED] Spring Boot 3.5.16、JDK 21 LTS、Maven 3.9.x 在既定 3.x 范围内;依据 research R1,未来 pom 锁定
认证与授权 Spring Security,方法/请求授权使用 authority,默认拒绝 宪法已定;业务许可目录见 contracts
持久化 [APPROVED,原 INFERRED] PostgreSQL 18.x、Spring Data JPA、Flyway、Boot 管理的驱动与迁移适配 research R2、ADR-002 Accepted
会话与密码 [APPROVED,原 INFERRED] Spring Session JDBC、框架 PBKDF2、HttpSession CSRF research R3—R4;绝对期限和版本失效为薄策略适配
web 已批准 Next.js App Router、Refine CORE 5.x、Ant Design 5.x ADR-001;实验精确组合见兼容报告,正式 package.json/锁文件负责版本
网络 [APPROVED,原 INFERRED] 同源 /api/v1 直达 core;开发纯转发,生产 infra 编排入口 不创建业务 BFF 或前端身份服务
测试 [APPROVED,原 INFERRED] Boot Test、Security Test、JUnit/MockMvc;同 PostgreSQL 的集成测试;Playwright 浏览器验收 宪法要求单元测试;框架测试依赖版本由 BOM/锁文件承接
目标 单机基础平台 MVP,中文桌面浏览器 不设计实验业务、个人例外或通用数据范围授权
性能/容量 本阶段无额外 QPS/SLA 承诺;列表只读单次最多 50 条 不把测试样例量当生产容量;以后有要求再评审
当前环境 本地 JDK 21、Maven、Node 可用;未发现 Docker;尚无新工程仓库 不安装或检查旧 GitLab 仓库弥补上下文

Constitution Check

设计前与设计后各查一次;“偏离”表示放行证据尚缺,不是默认许可。

原则 Gate 问题 设计前 设计后 Evidence
§2 web 是否只消费 core,不存数据或裁决角色权限? 通过 通过 本文网络与 provider 边界、contracts
§3 是否保持 Boot 3.x、Next.js 与 Spring Security? 通过 通过 Technical Context、research R1
§4 通用会话、密码、持久化是否复用框架?新选择是否获准? 通过 通过:ADR-002 已随本轮确认采用 research R2—R7、ADR-002
§5 是否规划认证/授权/会话单元测试及既有测试不回退? 通过 通过:仅计划层面 tasks Tests、quickstart
§5 DRY 权限目录与契约是否只有一份定义,前端不另写角色映射? 通过 通过 contracts/access-control.md、openapi.json
§6/7 正式需求与草案设计是否分离? 通过 通过 docs/specs 与当前 docs/specs/platform-001
§8 是否新增实验任务、通知、导出或通用授权引擎? 通过 通过:均未纳入 正式规格范围与 tasks

Project Structure

下列为当前工程布局;core/web/infra 均已建立。文档保留在 lab-edu/docs/,旧 agents/platform-001 链接兼容指向本设计包。GitLab 新仓库尚未创建,位置记录于仓库规划,不得读取 group 内旧仓库。

lab-edu/
  docs/
    specs/                       # 已批准规格
    adr/                         # 采用与拟议决策
    agents/platform-001/         # 本轮设计包
  core/
    pom.xml
    src/main/java/team/lab_edu/
      LabEduApplication.java
      security/                  # 框架配置、期限/版本适配
      account/                   # 注册、本人密码、用户管理
      access/                    # 角色目录、赋权、导航
      governance/                # 跨行恢复约束
    src/main/resources/db/migration/
    src/test/java/team/lab_edu/
  web/
    package.json
    src/app/(public)/register/page.tsx
    src/app/(public)/login/page.tsx
    src/app/(protected)/page.tsx
    src/app/(protected)/change-password/page.tsx
    src/app/(protected)/admin/users/page.tsx
    src/app/(protected)/admin/roles/page.tsx
    src/app/(protected)/admin/permissions/page.tsx
    src/app/(protected)/admin/menus/page.tsx
    src/providers/
    tests/
  infra/                         # 独立骨架交付规划后初始化

四个本地目录将分别对应独立新仓库,不在 lab-edu 根创建包住所有子仓库的 Git 历史;目录搬迁需要先查引用并保留入口,不能从新项目接续旧仓库。

设计:认证、期限与安全上下文

  1. 浏览器先 GET csrf-tokens,再 POST registrations 或 sessions。注册请求只接收登录名、显示名和密码,拒绝额外角色、状态或权限;student 绑定由 core 固定完成。
  2. 登录使用 Spring Security 表单认证过滤器,契约采用表单编码,复用其会话 ID 轮换和 SecurityContext 保存;成功处理器返回 JSON,不手动模拟整套登录。匿名/禁用/密码错误统一 401 文案,达到失败阈值返回 429。
  3. 成功登录快照记录账户 ID、账户认证版本、角色 ID/授权版本、认证时刻及最后有效业务活动时刻。框架存储会话,不能将密码或明文凭证放入快照。
  4. 在恢复 SecurityContext 后、执行业务授权前核查当前账户/角色版本、禁用状态与期限。失效即拒绝并作废,不能仅更新前端菜单。待改密会话只可读取本人身份、取得 CSRF、改密和退出。
  5. 绝对期限为认证时刻起满 8 小时;业务空闲期限为最后有效活动起满 30 分钟,等于边界即失效。框架 30 分钟超时用于回收,额外业务时刻检查才是 FR-006 的依据。
  6. 有效活动仅限成功且有权的资源查询/业务变更及有效本人改密流程;身份/CSRF/健康查询、失败与无权请求不续期。web 禁用后台轮询和自动资源重取;聚焦、恢复网络只做不续期身份检查。不能信任客户端上报时间或“用户已点击”来绕过期限。
  7. 退出使用框架 LogoutHandler 删除当前会话并清理 Cookie;重复退出仍返回 204。登录成功、退出或发现 CSRF 失效后重新获取 token;403 CSRF 不触发自动重放敏感写操作。
  8. 更改密码、角色或状态以同一业务事务递增认证版本;角色权限改变递增授权版本。每次请求读当前版本,使物理会话清理延迟、旧请求保存会话记录等情况不能恢复撤销权限。

同源 Cookie 生产开启 Secure/HttpOnly/SameSite=Lax,开发仅显式 local profile 可用 HTTP。API 返回 Cache-Control: no-store;web 不将密码、临时密码、会话或 CSRF token 放进持久化浏览器存储。登录/退出/注册同样受 CSRF 保护。

业务活动时刻在已核实成功、响应写出与框架会话提交之前更新;不能简单在响应已经提交后修改属性并假定一定持久化。单元与真实会话集成测试必须验证成功读取会续期、失败/身份查询不续期及并发请求不会把活动时刻回退。

设计:并发与管理保护

  • 管理写入先取得数据库治理锁,再核实当前操作者、目标角色、目标账户与版本;修改前使用当前权限快照校验完整目标集合,不能按登录时旧权限赋权。
  • 最后管理员、角色删除/分配和初始化共享该锁;只锁不同目标账户无法保护跨行计数。所有参与路径必须遵守同一入口与锁顺序。
  • 资源 version 拒绝过期编辑,返回 409。权限集合替换为原子操作,失败不提交部分集合;内置恢复许可与默认角色约束按正式后台规格执行。
  • 角色用户数在预览中为提示,提交在锁内重新计算并返回最终影响数量;不以过期页面计数决定恢复约束。
  • 重置密码先生成一次性显示值,保存框架散列并递增版本;不持久化可回显明文。响应丢失时只能再次重置。

Phase 0/1 产物

  • research.md:每个推断的决定、理由、至少两个替代方案及官方来源。
  • data-model.md:业务关系、验证规则和状态机,不含 DDL。
  • contracts/openapi.json:唯一机器可读 REST 契约。
  • contracts/access-control.md:权限目录、Refine 展示许可与恢复集合映射。
  • quickstart.md:当前文档验证与未来可执行验收场景,区分已运行和待实现。
  • tasks.md:分阶段任务与独立验证路径,不批量标记完成。
  • repository-plan.md:全新仓库规划及禁止读取旧仓库的约束。

Complexity Tracking

没有计划违反已批准范围或分层的实现,不引入例外。后端新依赖与策略适配已于 2026-10-29 随本轮确认采用,证据在 research 与 ADR-002;实际验证结果按任务逐项记录,不把批准当成测试通过。

业务期限与版本检查不是通用框架重写。已比较仅依赖框架超时、仅删除会话、使用 JWT/Redis 等更简或替代路径;它们不足以独立满足已批准行为,详见 research R3、R6。代码量控制为薄适配,并安排边界与并发测试。