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

148 lines
8.2 KiB
Markdown

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 数字人民币教学仿真后端开发规范
本文档是本项目新增模块、接口和数据表时的统一约定。目标是在业务持续扩展时保持领域边界清晰、认证安全、数据可演进。
## 运行时版本
项目运行与构建统一使用 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 的“按限界上下文分包”方式。一个顶层模块代表一个业务能力,而不是一个技术层。
```mermaid
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/` 下创建新的顶层模块目录。例如钱包、账单或课程场景应分别创建:
```text
wallet/
ledger/
course/
```
不要把新业务类直接放入 `shared`、`security`、`identity` 或根包。只有确实属于这些既有上下文的功能,才允许扩展其目录。
每个新模块默认使用以下目录结构;没有内容的目录不要提前创建:
```text
<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. 分层与依赖方向
依赖只允许由外向内:
```text
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 中散落 `String`、`BigDecimal` 和状态码。
- 聚合 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_case`Java 字段使用 `camelCase`,通过 MyBatis-Plus 显式映射差异字段。
- 新业务表必须有主键、必要索引,以及 `created_at`、`updated_at`、`created_by`、`updated_by`、`deleted` 审计字段;可继承 `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。
- 角色只允许 `TEACHER`、`STUDENT`;权限判断放在应用层或 Spring Security 配置中,不能由前端传入角色决定。
- `platformintegration` 是唯一可以处理主平台 Token、CAS Ticket 和主平台只读数据源的模块。
- 主平台连接只授予 `SELECT`;本系统 MySQL 使用主数据源,主平台只读数据源不得被初始化脚本或业务写操作复用。
## 8. 测试与提交规范
- 新领域规则写单元测试;新增接口至少写 `MockMvc` 集成测试;新增表结构需覆盖启动初始化和关键读写。
- 修复缺陷先增加可复现的失败测试,再实现修复。
- 提交前至少运行:
```powershell
mvn test -DforkCount=0 -B
mvn package -DskipTests -B
```
- 提交信息采用 `<type>: <英文简述>`,例如 `feat: add wallet transfer aggregate`、`fix: prevent duplicate issuance`、`docs: add module development guide`。
- 一个提交只做一类明确变更;不要混入格式化、无关重构或本地配置文件。
## 9. 新模块自检清单
- [ ] 已创建新的顶层模块目录,而非把业务代码放入 `shared`
- [ ] 已区分 `domain`、`application`、`infrastructure`、`interfaces` 职责。
- [ ] Controller 未直接调用 Mapper且未返回持久化实体。
- [ ] 新增数据库变化已同步到测试库和 `schema.sql`
- [ ] 接口已校验参数、统一响应,并补充 Swagger 说明。
- [ ] 未记录或返回密码、Token、验证码等敏感信息。
- [ ] 已补齐单元/集成测试并通过 Maven 验证。