You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
digital-rmb-backend/docs/DEVELOPMENT_GUIDE.md

8.2 KiB

数字人民币教学仿真后端开发规范

本文档是本项目新增模块、接口和数据表时的统一约定。目标是在业务持续扩展时保持领域边界清晰、认证安全、数据可演进。

运行时版本

项目运行与构建统一使用 JDK 8框架基线为 Spring Boot 2.7.18、Spring Security 5.7、MyBatis-Plus 3.5.17 和 Springdoc 1.8.0。新增代码不得使用 Java 9 及以上的语言特性或标准库 APIServlet 与 Bean Validation 使用 javax.* 包。

1. 架构总览

项目采用 DDD 的“按限界上下文分包”方式。一个顶层模块代表一个业务能力,而不是一个技术层。

flowchart LR
  Client[前端 / 调用方] --> API[interfaces 接口层]
  API --> App[application 应用层]
  App --> Domain[domain 领域层]
  App --> Infra[infrastructure 基础设施层]
  Infra --> DB[(本系统 MySQL)]
  PI[platformintegration 防腐层] --> Platform[(主平台 / CAS)]
  API --> Security[security 认证上下文]
  Security --> DB

当前限界上下文如下:

模块 职责 禁止承担的职责
issuance 数字人民币发行相关业务域;当前仅有领域 ID 示例 用户认证、主平台 Token 解析
identity 教师/学生身份快照、角色投影与同步 提供用户、角色 CRUD
security 本系统 JWT、登录、会话兑换、刷新令牌与退出 业务领域规则、主平台协议解析
platformintegration 主平台 Token、CAS 和主平台只读查询的防腐适配 业务数据落库、业务接口
shared 仅放跨模块通用能力:响应体、异常、审计、基础配置 具体业务实体、业务 Service

2. 新模块必须新建顶层文件夹

新增一个独立业务能力时,必须在 src/main/java/com/yau/digitalrmb/ 下创建新的顶层模块目录。例如钱包、账单或课程场景应分别创建:

wallet/
ledger/
course/

不要把新业务类直接放入 sharedsecurityidentity 或根包。只有确实属于这些既有上下文的功能,才允许扩展其目录。

每个新模块默认使用以下目录结构;没有内容的目录不要提前创建:

<module>/
├── domain/
│   ├── model/                 # 聚合、实体、值对象、枚举、领域事件
│   ├── service/               # 无法归属单个聚合的纯领域服务
│   └── repository/            # 仓储接口(端口),不含 MyBatis 实现
├── application/
│   ├── command/               # 写操作命令及处理器
│   ├── query/                 # 查询模型与查询服务
│   └── service/               # 用例编排、事务边界
├── infrastructure/
│   ├── persistence/
│   │   ├── entity/            # MyBatis-Plus 持久化实体
│   │   ├── mapper/            # Mapper 接口与 XML如需要
│   │   └── repository/        # 仓储接口的实现
│   └── client/                # 外部 HTTP、消息或文件系统适配器
└── interfaces/
    ├── rest/                  # Controller
    └── dto/                   # 请求/响应 DTO

简单只读查询可以不创建完整聚合,但 Controller 仍不得直接调用 Mapper应由 application.query 中的查询服务负责。

3. 分层与依赖方向

依赖只允许由外向内:

interfaces → application → domain
infrastructure → domain / application 定义的端口

具体规则:

  • domain 不依赖 Spring、MyBatis-Plus、Controller、数据库实体或 HTTP DTO。
  • application 负责一个用例的编排、权限检查和事务边界;不编写 SQL不返回 MyBatis 实体。
  • infrastructure 实现数据库和外部系统适配Mapper 只能被本模块的仓储实现或查询服务使用。
  • interfaces 只负责参数校验、调用应用服务、转换 DTO不得包含业务规则。
  • 跨模块访问优先通过对方暴露的应用服务、领域事件或端口;禁止直接引用对方的 Mapper/Entity。
  • shared 仅接收至少两个模块真实复用且不携带业务语义的代码。不要把“暂时不知道放哪里”的类放入 shared

4. 领域建模规则

  • 每个写模型先确定聚合根和不变量;一次事务只修改一个聚合。
  • 用值对象表达金额、账户号、申请编号、状态等有业务含义的概念,避免在 Service 中散落 StringBigDecimal 和状态码。
  • 聚合 ID 使用独立类型,例如现有的 IssuanceApplicationId;接口层和持久化层再做转换。
  • 状态流转由聚合方法表达,例如 approve()reject();不要在 Controller 或 Mapper 中直接改状态字段。
  • 需要跨聚合通知时发布 shared.domain.DomainEvent,由应用层或基础设施层处理副作用。

5. 数据库与初始化脚本规范

  • 基础表结构和内置数据维护在 src/main/resources/schema.sql,脚本必须可重复执行,建表使用 IF NOT EXISTS,内置数据使用幂等写法。
  • 新增或修改表结构时,先在测试库执行并验证,再同步更新 schema.sql;不得依赖 Flyway 或保留 flyway_schema_history
  • 表名、字段名使用 snake_caseJava 字段使用 camelCase,通过 MyBatis-Plus 显式映射差异字段。
  • 新业务表必须有主键、必要索引,以及 created_atupdated_atcreated_byupdated_bydeleted 审计字段;可继承 AuditableEntity
  • 金额使用 DECIMAL,禁止使用 float/double;时间使用 TIMESTAMP,统一以 UTC 语义处理。
  • 身份、角色和用户角色仅能由内部投影或初始化脚本写入;不得新增对外 CRUD 接口。
  • 禁止将密码、Token、验证码或敏感凭据写入业务表、日志、初始化脚本或测试快照。

6. API 与异常规范

  • REST Controller 放在 <module>.interfaces.rest,路径统一以 /api/v1/ 开头。
  • 请求 DTO 使用 javax.validation 注解Controller 参数标注 @Valid
  • 对外成功响应统一使用 ApiResponse<T>,不要自行定义不一致的响应包装格式。
  • 可预期业务错误抛出 BusinessException 并使用 ErrorCode;不要在 Controller 中 try/catch 后吞掉异常。
  • 接口响应只返回 DTO不返回 MyBatis Entity、密码哈希、刷新令牌摘要或主平台 Token。
  • 新接口需补充 Springdoc 注解与说明,确保 Swagger 可读;不在 Swagger 暴露用户、角色或用户角色管理接口。

7. 认证与权限规范

  • 所有新业务接口默认需要本系统 JWT只有登录、CAS 回调和必要健康检查可以匿名。
  • 当前用户从 Spring Security 的 Jwt/Authentication 获取,业务模块不得解析主平台 Token。
  • 角色只允许 TEACHERSTUDENT;权限判断放在应用层或 Spring Security 配置中,不能由前端传入角色决定。
  • platformintegration 是唯一可以处理主平台 Token、CAS Ticket 和主平台只读数据源的模块。
  • 主平台连接只授予 SELECT;本系统 MySQL 使用主数据源,主平台只读数据源不得被初始化脚本或业务写操作复用。

8. 测试与提交规范

  • 新领域规则写单元测试;新增接口至少写 MockMvc 集成测试;新增表结构需覆盖启动初始化和关键读写。
  • 修复缺陷先增加可复现的失败测试,再实现修复。
  • 提交前至少运行:
mvn test -DforkCount=0 -B
mvn package -DskipTests -B
  • 提交信息采用 <type>: <英文简述>,例如 feat: add wallet transfer aggregatefix: prevent duplicate issuancedocs: add module development guide
  • 一个提交只做一类明确变更;不要混入格式化、无关重构或本地配置文件。

9. 新模块自检清单

  • 已创建新的顶层模块目录,而非把业务代码放入 shared
  • 已区分 domainapplicationinfrastructureinterfaces 职责。
  • Controller 未直接调用 Mapper且未返回持久化实体。
  • 新增数据库变化已同步到测试库和 schema.sql
  • 接口已校验参数、统一响应,并补充 Swagger 说明。
  • 未记录或返回密码、Token、验证码等敏感信息。
  • 已补齐单元/集成测试并通过 Maven 验证。