@jspg-ai/coding-bb 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -0
- package/cbb/dev-standards/rules/cbb-ai-behavior.md +104 -0
- package/cbb/dev-standards/rules/cbb-coding-rule.md +50 -0
- package/cbb/dev-standards/rules/cbb-priority.md +56 -0
- package/cbb/dev-standards/skills/architecture-specs/SKILL.md +129 -0
- package/cbb/dev-standards/skills/coding-specs/SKILL.md +376 -0
- package/cbb/dev-standards/skills/coding-specs/references/concurrency.md +53 -0
- package/cbb/dev-standards/skills/coding-specs/references/config-center.md +16 -0
- package/cbb/dev-standards/skills/coding-specs/references/distributed.md +42 -0
- package/cbb/dev-standards/skills/coding-specs/references/es-coding.md +60 -0
- package/cbb/dev-standards/skills/coding-specs/references/scheduled-task.md +25 -0
- package/cbb/dev-standards/skills/coding-specs/references/security.md +11 -0
- package/cbb/dev-standards/skills/coding-specs/references/unit-testing.md +43 -0
- package/cbb/dev-standards/skills/es-design-specs/SKILL.md +104 -0
- package/cbb/dev-standards/skills/mysql-design-specs/SKILL.md +89 -0
- package/cbb/lib/install/claude-code.js +20 -0
- package/cbb/lib/install/cleanup.js +64 -0
- package/cbb/lib/install/init.js +1875 -0
- package/cbb/lib/install/qoder.js +20 -0
- package/cbb/lib/install/workspaces.js +232 -0
- package/cbb/lib/openspec/index.js +554 -0
- package/cbb/lib/superpowers/index.js +265 -0
- package/cbb/lib/utils/check-update.js +147 -0
- package/cbb/lib/utils/checkbox.js +383 -0
- package/cbb/lib/utils/gitignore.js +69 -0
- package/cbb/lib/utils/output.js +64 -0
- package/cbb/lib/utils/settings.js +119 -0
- package/cbb/lib/utils/version.js +135 -0
- package/cbb/lib/wiki/api-client.js +358 -0
- package/cbb/lib/wiki/cli.js +427 -0
- package/cbb/lib/wiki/convert.js +464 -0
- package/cbb/lib/wiki/index.js +218 -0
- package/cbb/lib/wiki/mermaid-guard.js +103 -0
- package/cbb/lib/wiki/split.js +131 -0
- package/cbb/tools/cbb-decompile-jar/SKILL.md +220 -0
- package/cbb/tools/cbb-decompile-jar/scripts/decompile.py +863 -0
- package/cbb/tools/cbb-design-to-wiki/SKILL.md +180 -0
- package/cbb/tools/cbb-mvn-guide/SKILL.md +281 -0
- package/cbb/tools/cbb-mvn-guide/scripts/mvn_jdk_manager.py +378 -0
- package/cbb/tools/cbb-mvn-guide/scripts/mvn_pom_jdk_reader.py +197 -0
- package/cbb/tools/cbb-plantuml-authoring/SKILL.md +448 -0
- package/cbb/tools/cbb-plantuml-authoring/references/drawing-templates.md +479 -0
- package/cbb/tools/cbb-wiki-ops/SKILL.md +134 -0
- package/cbb/tools/cbb-wiki-ops/scripts/check-auth.js +44 -0
- package/cbb/worktrees/_shared/scripts/find-target-worktree.js +96 -0
- package/cbb/worktrees/_shared/scripts/find-workspace-root.js +67 -0
- package/cbb/worktrees/_shared/scripts/push-core.js +136 -0
- package/cbb/worktrees/_shared/scripts/silence-popup.js +23 -0
- package/cbb/worktrees/commands/close.md +64 -0
- package/cbb/worktrees/commands/extend.md +65 -0
- package/cbb/worktrees/commands/init.md +55 -0
- package/cbb/worktrees/commands/push.md +42 -0
- package/cbb/worktrees/skills/openspec-close-worktree/SKILL.md +449 -0
- package/cbb/worktrees/skills/openspec-close-worktree/scripts/check-env.js +76 -0
- package/cbb/worktrees/skills/openspec-close-worktree/scripts/check-unarchived.js +48 -0
- package/cbb/worktrees/skills/openspec-close-worktree/scripts/delete-branches.js +136 -0
- package/cbb/worktrees/skills/openspec-close-worktree/scripts/discover-apps.js +76 -0
- package/cbb/worktrees/skills/openspec-close-worktree/scripts/find-target-worktree.js +96 -0
- package/cbb/worktrees/skills/openspec-close-worktree/scripts/find-workspace-root.js +67 -0
- package/cbb/worktrees/skills/openspec-close-worktree/scripts/remove-worktrees.js +124 -0
- package/cbb/worktrees/skills/openspec-close-worktree/scripts/safety-check.js +174 -0
- package/cbb/worktrees/skills/openspec-close-worktree/scripts/silence-popup.js +23 -0
- package/cbb/worktrees/skills/openspec-extend-worktree/SKILL.md +390 -0
- package/cbb/worktrees/skills/openspec-extend-worktree/scripts/check-env.js +95 -0
- package/cbb/worktrees/skills/openspec-extend-worktree/scripts/check-repos.js +98 -0
- package/cbb/worktrees/skills/openspec-extend-worktree/scripts/create-branches-and-worktrees.js +135 -0
- package/cbb/worktrees/skills/openspec-extend-worktree/scripts/find-target-worktree.js +96 -0
- package/cbb/worktrees/skills/openspec-extend-worktree/scripts/find-workspace-root.js +67 -0
- package/cbb/worktrees/skills/openspec-extend-worktree/scripts/install-ai.js +150 -0
- package/cbb/worktrees/skills/openspec-extend-worktree/scripts/list-available-apps.js +88 -0
- package/cbb/worktrees/skills/openspec-extend-worktree/scripts/push-core.js +136 -0
- package/cbb/worktrees/skills/openspec-extend-worktree/scripts/silence-popup.js +23 -0
- package/cbb/worktrees/skills/openspec-extend-worktree/scripts/sync-repos.js +93 -0
- package/cbb/worktrees/skills/openspec-init-worktree/SKILL.md +539 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/auto-open.js +136 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/check-env-deep.js +87 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/check-env.js +90 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/check-repos.js +171 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/create-branches.js +103 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/create-worktrees.js +154 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/find-workspace-root.js +67 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/generate-app-options.js +93 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/install-ai.js +177 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/parse-config.js +67 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/push-branches.js +101 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/push-core.js +136 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/silence-popup.js +23 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/sync-repos.js +95 -0
- package/cbb/worktrees/skills/openspec-init-worktree/scripts/update-gitignore.js +134 -0
- package/cbb/worktrees/skills/openspec-push-worktrees/SKILL.md +307 -0
- package/cbb/worktrees/skills/openspec-push-worktrees/scripts/commit-worktrees.js +269 -0
- package/cbb/worktrees/skills/openspec-push-worktrees/scripts/find-target-worktree.js +96 -0
- package/cbb/worktrees/skills/openspec-push-worktrees/scripts/find-workspace-root.js +67 -0
- package/cbb/worktrees/skills/openspec-push-worktrees/scripts/push-core.js +136 -0
- package/cbb/worktrees/skills/openspec-push-worktrees/scripts/push-worktrees.js +159 -0
- package/cbb/worktrees/skills/openspec-push-worktrees/scripts/silence-popup.js +23 -0
- package/config/cbb.yaml +6 -0
- package/config/config.sample.json +16 -0
- package/config/openspec/config.yaml +28 -0
- package/config/openspec/schemas/spec-driven/schema.yaml +247 -0
- package/config/openspec/schemas/spec-driven/templates/design.md +475 -0
- package/config/openspec/schemas/spec-driven/templates/proposal.md +58 -0
- package/config/openspec/schemas/spec-driven/templates/spec.md +8 -0
- package/config/openspec/schemas/spec-driven/templates/tasks.md +9 -0
- package/config/workspaces.json +15 -0
- package/openspec/.version +6 -0
- package/openspec/commands/apply.md +182 -0
- package/openspec/commands/archive.md +223 -0
- package/openspec/commands/bulk-archive.md +334 -0
- package/openspec/commands/continue.md +112 -0
- package/openspec/commands/explore.md +206 -0
- package/openspec/commands/ff.md +111 -0
- package/openspec/commands/new.md +70 -0
- package/openspec/commands/onboard.md +555 -0
- package/openspec/commands/propose.md +157 -0
- package/openspec/commands/sync.md +256 -0
- package/openspec/commands/update.md +85 -0
- package/openspec/commands/verify.md +169 -0
- package/openspec/skills/openspec-apply-change/SKILL.md +187 -0
- package/openspec/skills/openspec-archive-change/SKILL.md +181 -0
- package/openspec/skills/openspec-bulk-archive-change/SKILL.md +338 -0
- package/openspec/skills/openspec-continue-change/SKILL.md +117 -0
- package/openspec/skills/openspec-explore/SKILL.md +342 -0
- package/openspec/skills/openspec-ff-change/SKILL.md +116 -0
- package/openspec/skills/openspec-new-change/SKILL.md +76 -0
- package/openspec/skills/openspec-onboard/SKILL.md +560 -0
- package/openspec/skills/openspec-propose/SKILL.md +162 -0
- package/openspec/skills/openspec-sync-specs/SKILL.md +261 -0
- package/openspec/skills/openspec-update-change/SKILL.md +90 -0
- package/openspec/skills/openspec-verify-change/SKILL.md +174 -0
- package/package.json +46 -0
- package/superpowers/.version +6 -0
- package/superpowers/skills/brainstorming/SKILL.md +250 -0
- package/superpowers/skills/brainstorming/scripts/frame-template.html +213 -0
- package/superpowers/skills/brainstorming/scripts/helper.js +167 -0
- package/superpowers/skills/brainstorming/scripts/server.cjs +723 -0
- package/superpowers/skills/brainstorming/scripts/start-server.sh +209 -0
- package/superpowers/skills/brainstorming/scripts/stop-server.sh +120 -0
- package/superpowers/skills/brainstorming/spec-document-reviewer-prompt.md +49 -0
- package/superpowers/skills/brainstorming/visual-companion.md +299 -0
- package/superpowers/skills/dispatching-parallel-agents/SKILL.md +167 -0
- package/superpowers/skills/executing-plans/SKILL.md +64 -0
- package/superpowers/skills/finishing-a-development-branch/SKILL.md +225 -0
- package/superpowers/skills/receiving-code-review/SKILL.md +205 -0
- package/superpowers/skills/requesting-code-review/SKILL.md +95 -0
- package/superpowers/skills/requesting-code-review/code-reviewer.md +181 -0
- package/superpowers/skills/subagent-driven-development/SKILL.md +568 -0
- package/superpowers/skills/subagent-driven-development/implementer-prompt.md +154 -0
- package/superpowers/skills/subagent-driven-development/re-review-prompt.md +115 -0
- package/superpowers/skills/subagent-driven-development/scripts/review-package +46 -0
- package/superpowers/skills/subagent-driven-development/scripts/sdd-workspace +40 -0
- package/superpowers/skills/subagent-driven-development/scripts/task-brief +41 -0
- package/superpowers/skills/subagent-driven-development/task-reviewer-prompt.md +207 -0
- package/superpowers/skills/systematic-debugging/CREATION-LOG.md +119 -0
- package/superpowers/skills/systematic-debugging/SKILL.md +283 -0
- package/superpowers/skills/systematic-debugging/condition-based-waiting-example.ts +158 -0
- package/superpowers/skills/systematic-debugging/condition-based-waiting.md +115 -0
- package/superpowers/skills/systematic-debugging/defense-in-depth.md +122 -0
- package/superpowers/skills/systematic-debugging/find-polluter.sh +72 -0
- package/superpowers/skills/systematic-debugging/root-cause-tracing.md +169 -0
- package/superpowers/skills/systematic-debugging/test-academic.md +14 -0
- package/superpowers/skills/systematic-debugging/test-pressure-1.md +58 -0
- package/superpowers/skills/systematic-debugging/test-pressure-2.md +68 -0
- package/superpowers/skills/systematic-debugging/test-pressure-3.md +69 -0
- package/superpowers/skills/test-driven-development/SKILL.md +320 -0
- package/superpowers/skills/test-driven-development/writing-good-tests.md +198 -0
- package/superpowers/skills/using-git-worktrees/SKILL.md +167 -0
- package/superpowers/skills/using-superpowers/SKILL.md +63 -0
- package/superpowers/skills/using-superpowers/references/antigravity-tools.md +23 -0
- package/superpowers/skills/using-superpowers/references/codex-tools.md +108 -0
- package/superpowers/skills/using-superpowers/references/gemini-tools.md +63 -0
- package/superpowers/skills/using-superpowers/references/hermes-tools.md +56 -0
- package/superpowers/skills/using-superpowers/references/pi-tools.md +16 -0
- package/superpowers/skills/verification-before-completion/SKILL.md +120 -0
- package/superpowers/skills/writing-plans/SKILL.md +171 -0
- package/superpowers/skills/writing-plans/plan-document-reviewer-prompt.md +49 -0
- package/superpowers/skills/writing-skills/SKILL.md +679 -0
- package/superpowers/skills/writing-skills/anthropic-best-practices.md +1150 -0
- package/superpowers/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/superpowers/skills/writing-skills/graphviz-conventions.dot +172 -0
- package/superpowers/skills/writing-skills/persuasion-principles.md +187 -0
- package/superpowers/skills/writing-skills/render-graphs.js +169 -0
- package/superpowers/skills/writing-skills/testing-skills-with-subagents.md +384 -0
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: coding-specs
|
|
3
|
+
description: "Java 后端编码规范。方案设计、编码实现、Code Review 三个阶段均须参照——涵盖 OpenSpec propose/apply/verify、Superpowers 头脑风暴/writing-plans/executing-plans/requesting-code-review/receiving-code-review、编写技术方案或详细设计、直接编码、直接代码审查。内容包括 API 设计(REST/RPC)、模型分层与转换(DTO/Entity/PO)、异常处理与错误码、日志规范、MySQL 编码与事务、二方三方调用、安全红线,以及并发控制、消息与缓存一致性、幂等设计、ES 查询、定时任务、单元测试等进阶规范。仅限 Java 后端场景,不适用于前端、Python 或纯文档编辑。"
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# 编码规范
|
|
7
|
+
|
|
8
|
+
提供 Java 后端开发的完整规范指南。
|
|
9
|
+
|
|
10
|
+
核心编码规范(API、模型、代码风格、错误处理、日志、性能、安全红线)在本文件中。各领域的进阶规范按需加载,参见文末路由表。
|
|
11
|
+
|
|
12
|
+
## 规范内容
|
|
13
|
+
|
|
14
|
+
### API 设计规范
|
|
15
|
+
|
|
16
|
+
#### 响应结构
|
|
17
|
+
|
|
18
|
+
所有 REST API 返回统一响应结构 `Result<T>`:
|
|
19
|
+
|
|
20
|
+
```java
|
|
21
|
+
Result.success(data) // 业务成功,HTTP 200
|
|
22
|
+
Result.fail(errorCode, msg) // 业务失败,HTTP 200
|
|
23
|
+
Result.fail("SYSTEM_ERROR", "系统繁忙") // 系统异常,HTTP 200
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
#### 分页
|
|
27
|
+
|
|
28
|
+
- 使用 `Result<PageView<T>>` 统一分页结构,`PageView` 来自 commons-api
|
|
29
|
+
- page 从 0 开始,页大小变量为 `size`,默认 size=20,最大 100
|
|
30
|
+
|
|
31
|
+
#### 接口设计
|
|
32
|
+
|
|
33
|
+
- 1 个 API 接口对应 1 个功能,不出现一对多或多对一
|
|
34
|
+
- 同一组 API 接口命名一致,同一概念不混用不同名称(如 fee 和 amount)
|
|
35
|
+
- 接口命名基于目标,不包含策略与细节:
|
|
36
|
+
|
|
37
|
+
```java
|
|
38
|
+
// 正例
|
|
39
|
+
Result<T> queryNewestGuaranteePackage(QueryGuaranteePackageRequest request);
|
|
40
|
+
|
|
41
|
+
// 反例
|
|
42
|
+
Result<T> queryNewestGuaranteePackageContainAllStatus(QueryGuaranteePackageRequest request);
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
- API 方法名应和具体暴露协议无关:
|
|
46
|
+
|
|
47
|
+
```java
|
|
48
|
+
// 反例
|
|
49
|
+
getCargoRPC(Long id)
|
|
50
|
+
getCargoRest(Long id)
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
- REST 和 API 禁止直接抛异常,统一拦截封装成错误码
|
|
54
|
+
|
|
55
|
+
#### 参数规范
|
|
56
|
+
|
|
57
|
+
- 参数超过 3 个使用包装类型封装,不允许无业务含义的 Map 作为入参
|
|
58
|
+
- 参数和返回值使用包装类型,不能使用原生类型
|
|
59
|
+
- 必填字段使用 Validation-api 校验:
|
|
60
|
+
|
|
61
|
+
```java
|
|
62
|
+
public interface UserFacade {
|
|
63
|
+
Result<String> save(@Valid UserRequest user);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@Data
|
|
67
|
+
public class UserRequest implements Serializable {
|
|
68
|
+
@NotEmpty(message = "姓名不能为空")
|
|
69
|
+
private String name;
|
|
70
|
+
|
|
71
|
+
@Min(18)
|
|
72
|
+
private Integer age;
|
|
73
|
+
}
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
- 常识类属性校验规则:
|
|
77
|
+
|
|
78
|
+
| 字段类型 | 校验规则 |
|
|
79
|
+
|---------|----------|
|
|
80
|
+
| 金额 | 非负数 |
|
|
81
|
+
| 数量 | 非负数 |
|
|
82
|
+
| 车长 | 非负数,有最大值 |
|
|
83
|
+
| 里程 | 非负数 |
|
|
84
|
+
| 经纬度 | 纬度 -90~90,经度 -180~180 |
|
|
85
|
+
| 邮箱 | 格式校验 |
|
|
86
|
+
| 手机号 | 格式校验 |
|
|
87
|
+
|
|
88
|
+
#### 返回值
|
|
89
|
+
|
|
90
|
+
- 禁止返回 null,使用 YmmResult 或 Result 统一包装
|
|
91
|
+
- 返回集合时不返回 null,返回空集合
|
|
92
|
+
|
|
93
|
+
#### 错误码设计
|
|
94
|
+
|
|
95
|
+
- 格式:`模块前缀_数字`(如 `ORDER_40001`、`CARGO_50002`)
|
|
96
|
+
- 每个模块维护独立的编号段,避免跨模块冲突
|
|
97
|
+
- 错误码统一在枚举类或常量类中定义,禁止在业务代码中硬编码字符串
|
|
98
|
+
|
|
99
|
+
```java
|
|
100
|
+
// 正例:枚举类集中管理
|
|
101
|
+
public enum OrderErrorCode {
|
|
102
|
+
ORDER_NOT_FOUND("ORDER_40001", "订单不存在"),
|
|
103
|
+
ORDER_STATUS_INVALID("ORDER_40002", "订单状态不允许此操作");
|
|
104
|
+
|
|
105
|
+
private final String code;
|
|
106
|
+
private final String message;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
// 反例:硬编码
|
|
110
|
+
Result.fail("ORDER_40001", "订单不存在");
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
#### 接口管理
|
|
114
|
+
|
|
115
|
+
- REST 和 API 接口统一接入 FTAPI,支持自动上报、自动更新
|
|
116
|
+
- C 端批量接口单次返回数据量 <= 200
|
|
117
|
+
|
|
118
|
+
#### 命名规则
|
|
119
|
+
|
|
120
|
+
方法名使用动词+名词格式:
|
|
121
|
+
|
|
122
|
+
| 动词 | 含义 |
|
|
123
|
+
|------|------|
|
|
124
|
+
| create | 创建、新建 |
|
|
125
|
+
| update | 修改 |
|
|
126
|
+
| get | 获取单个对象 |
|
|
127
|
+
| query | 获取多个对象 |
|
|
128
|
+
| delete | 删除 |
|
|
129
|
+
|
|
130
|
+
查询接口入参是单个类型(非主键 ID)时使用 `ByXxx` 后缀。复杂查询使用 `QueryCondition` 封装。
|
|
131
|
+
|
|
132
|
+
### 错误处理规范
|
|
133
|
+
|
|
134
|
+
#### 异常处理
|
|
135
|
+
|
|
136
|
+
- try-catch 范围尽可能小,不嵌套 try-catch
|
|
137
|
+
- 后端内部业务代码不能声明 `Throwable`,避免吞掉虚拟机 Error
|
|
138
|
+
- 尽可能对异常分类处理,稳定代码不放入 try 块
|
|
139
|
+
|
|
140
|
+
#### 禁止事项
|
|
141
|
+
|
|
142
|
+
- 不用异常处理代替逻辑校验(异常处理效率远低于条件判断)
|
|
143
|
+
- 事务场景不能吞掉异常,避免事务回滚机制失效
|
|
144
|
+
- finally 块中禁止使用 return(会覆盖 try 块中的 return)
|
|
145
|
+
|
|
146
|
+
### 模型设计规范
|
|
147
|
+
|
|
148
|
+
#### 字段命名一致性
|
|
149
|
+
|
|
150
|
+
相同语义字段在不同表中的命名和类型必须一致(主键与外键可不同)。
|
|
151
|
+
|
|
152
|
+
#### 金额字段
|
|
153
|
+
|
|
154
|
+
| 场景 | 类型 | 精度 |
|
|
155
|
+
|------|------|------|
|
|
156
|
+
| 交易业务 | long(分为单位) | 整数分 |
|
|
157
|
+
| 金融类应用 | decimal | 确保小数位不丢失精度 |
|
|
158
|
+
|
|
159
|
+
#### 模型字段类型
|
|
160
|
+
|
|
161
|
+
对外交互模型(DTO、Entity、VO、DO、Request、Response)的字段:
|
|
162
|
+
- 不能使用基础类型(boolean、int、long、byte、char、short、float、double)
|
|
163
|
+
- 不能给字段设置默认值
|
|
164
|
+
- 防止 NULL 值被覆盖
|
|
165
|
+
|
|
166
|
+
#### 枚举
|
|
167
|
+
|
|
168
|
+
- API 返回值中不允许使用枚举类型,使用 Integer 并添加 `@see` 注释:
|
|
169
|
+
|
|
170
|
+
```java
|
|
171
|
+
/**
|
|
172
|
+
* 货源状态:初始化、待上架、已上架、已下架
|
|
173
|
+
* @see CargoStatusEnum
|
|
174
|
+
*/
|
|
175
|
+
private Integer cargoStatus;
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
#### 模型设计
|
|
179
|
+
|
|
180
|
+
- 复杂业务场景建立核心模型 + 扩展模型体系,扩展字段不过度侵入核心模型
|
|
181
|
+
- 非极端高性能场景不建议冗余字段;有数据快照需求时可以冗余
|
|
182
|
+
- 冗余字段选择:不是频繁修改的字段、不是唯一索引的字段、不是 varchar 超长或 text 字段
|
|
183
|
+
- 配置类复杂结构数据建议独立字段存储,无须符合第一范式
|
|
184
|
+
- 模型分层嵌套不超过 3 层,超过 3 层在上层提供简易获取方法
|
|
185
|
+
|
|
186
|
+
#### 模型分层与转换
|
|
187
|
+
|
|
188
|
+
各层模型职责:
|
|
189
|
+
|
|
190
|
+
| 模型 | 所在模块 | 职责 |
|
|
191
|
+
|------|---------|------|
|
|
192
|
+
| Request / Response | xxx-api | RPC/REST 接口入参出参 |
|
|
193
|
+
| DTO | xxx-api | 服务间传输对象 |
|
|
194
|
+
| Entity / DO | xxx-service | 业务领域模型 |
|
|
195
|
+
| PO | xxx-service | 持久化对象(对应数据库表) |
|
|
196
|
+
|
|
197
|
+
转换规则:
|
|
198
|
+
- 使用 MapStruct 进行对象映射,禁止手写大量 get/set 转换
|
|
199
|
+
- 跨层必须转换,不能将 PO 直接暴露给 API 层,也不能将 Request 直接传到 DAO 层
|
|
200
|
+
- 同层内字段结构相同时可以共用模型,但跨层必须用独立类型
|
|
201
|
+
|
|
202
|
+
```java
|
|
203
|
+
@Mapper(componentModel = "spring")
|
|
204
|
+
public interface OrderConverter {
|
|
205
|
+
OrderDTO toDTO(OrderEntity entity);
|
|
206
|
+
OrderEntity toEntity(CreateOrderRequest request);
|
|
207
|
+
List<OrderDTO> toDTOList(List<OrderEntity> entities);
|
|
208
|
+
}
|
|
209
|
+
```
|
|
210
|
+
|
|
211
|
+
### 代码风格规范
|
|
212
|
+
|
|
213
|
+
#### 命名规范
|
|
214
|
+
|
|
215
|
+
- 工程内接口和实现命名统一配对:`IxxxService` + `xxxService` 或 `xxxService` + `xxxServiceImpl`
|
|
216
|
+
- 禁止望文不知义的缩写(反例:`AbsClass`)
|
|
217
|
+
|
|
218
|
+
#### 领域术语
|
|
219
|
+
|
|
220
|
+
**用户域:**
|
|
221
|
+
|
|
222
|
+
| 中文 | 英文 |
|
|
223
|
+
|------|------|
|
|
224
|
+
| 账户 | account |
|
|
225
|
+
| 货主 | shipper |
|
|
226
|
+
| 司机 | driver |
|
|
227
|
+
| 手机号 | mobile |
|
|
228
|
+
| 车辆 | vehicle |
|
|
229
|
+
| 车队 | fleet |
|
|
230
|
+
|
|
231
|
+
**货源域:**
|
|
232
|
+
|
|
233
|
+
| 中文 | 英文 |
|
|
234
|
+
|------|------|
|
|
235
|
+
| 货源 | cargo |
|
|
236
|
+
| 草稿货源 | draftCargo |
|
|
237
|
+
| 上架/下架 | putOn / putOff |
|
|
238
|
+
| 父货源 | parentCargo |
|
|
239
|
+
| 一口价 | buyout |
|
|
240
|
+
| 车型/车长 | vehicleType / vehicleLength |
|
|
241
|
+
| 备注 | remark |
|
|
242
|
+
|
|
243
|
+
**订单域:**
|
|
244
|
+
|
|
245
|
+
| 中文 | 英文 |
|
|
246
|
+
|------|------|
|
|
247
|
+
| 订单/运单 | order / waybill |
|
|
248
|
+
| 装货/卸货 | load / unload |
|
|
249
|
+
| 协议 | contract |
|
|
250
|
+
| 回单 | receipt |
|
|
251
|
+
| 履约凭证 | proof |
|
|
252
|
+
|
|
253
|
+
**费用支付域:**
|
|
254
|
+
|
|
255
|
+
| 中文 | 英文 |
|
|
256
|
+
|------|------|
|
|
257
|
+
| 支付/退款 | pay / refund |
|
|
258
|
+
| 结算/代扣 | settle / deduct |
|
|
259
|
+
| 应付/应收 | payable / receivable |
|
|
260
|
+
| 实收/实付 | received / paid |
|
|
261
|
+
| 运费/佣金 | freight / commission |
|
|
262
|
+
| 发票 | invoice |
|
|
263
|
+
|
|
264
|
+
### 日志规范
|
|
265
|
+
|
|
266
|
+
#### 框架选择
|
|
267
|
+
|
|
268
|
+
使用 SLF4J + Log4j2,禁止直接使用 Log4j 或 Logback API。
|
|
269
|
+
|
|
270
|
+
#### 日志占位符
|
|
271
|
+
|
|
272
|
+
使用 `{}` 占位符,禁止字符串拼接。
|
|
273
|
+
|
|
274
|
+
#### 日志级别
|
|
275
|
+
|
|
276
|
+
- trace/debug 级别日志必须先判断级别
|
|
277
|
+
- 异常日志使用 `logger.error("desc {}", context, e)`,禁止 `e.printStackTrace()`
|
|
278
|
+
|
|
279
|
+
#### 日志输出时机
|
|
280
|
+
|
|
281
|
+
- REST/RPC 调用无需自行打印出入参数,微服务已自动打印
|
|
282
|
+
- 读链路非必要不打日志
|
|
283
|
+
- 写链路方法需要打印出入参数
|
|
284
|
+
|
|
285
|
+
### 性能优化规范
|
|
286
|
+
|
|
287
|
+
#### 二方、三方调用管理
|
|
288
|
+
|
|
289
|
+
- 二方、三方调用必须通过防腐层(Repo),面向失败编程,考虑网络抖动、服务劣化等异常
|
|
290
|
+
- 所有二方、三方调用必须明确设置超时时间
|
|
291
|
+
- 三方调用发生错误时,对错误响应编码分类打点,必须打印日志
|
|
292
|
+
|
|
293
|
+
#### IO 优化
|
|
294
|
+
|
|
295
|
+
- 禁止在循环内执行非必要 IO 操作
|
|
296
|
+
- 可以批量调用的不循环调用
|
|
297
|
+
- 业务代码中禁止使用 DELETE/TRUNCATE/DROP 操作数据库,统一使用逻辑删除(deleted 字段)
|
|
298
|
+
|
|
299
|
+
### MySQL 编码规范
|
|
300
|
+
|
|
301
|
+
#### SQL 编写
|
|
302
|
+
|
|
303
|
+
- 禁止在循环中执行 SQL
|
|
304
|
+
- 禁止 `SELECT *`,明确列出字段
|
|
305
|
+
- 多表关联时列名加表名/表别名限定
|
|
306
|
+
- 使用 `count(*)` 统计行数
|
|
307
|
+
- `WHERE` 条件避免在索引字段上使用函数和隐式类型转换
|
|
308
|
+
- 分页查询必须有索引覆盖排序字段
|
|
309
|
+
- 大表深度分页(偏移量 > 1000)使用游标分页或子查询优化
|
|
310
|
+
- 单次查询数据量不超过 1000 条
|
|
311
|
+
|
|
312
|
+
#### 事务控制
|
|
313
|
+
|
|
314
|
+
- 事务必须在 Service 层控制,禁止在 DAO 层
|
|
315
|
+
- 事务尽可能短小,禁止在事务中调用 RPC 或外部服务;如需调用,先提交事务再调用
|
|
316
|
+
- 默认读从库,延时敏感场景主动设置读主库
|
|
317
|
+
|
|
318
|
+
#### 删除操作
|
|
319
|
+
|
|
320
|
+
- 应用程序使用逻辑删除(deleted 字段),禁止在业务代码中使用物理删除
|
|
321
|
+
|
|
322
|
+
### 安全红线规范
|
|
323
|
+
|
|
324
|
+
#### SQL 注入防护
|
|
325
|
+
|
|
326
|
+
- 必须使用 `#{}` 占位符,禁止 `${}` 拼接用户输入(详见 `/mysql-design-specs`)
|
|
327
|
+
- 排序字段、表名等无法使用占位符的场景,必须通过白名单校验
|
|
328
|
+
|
|
329
|
+
#### 敏感数据处理
|
|
330
|
+
|
|
331
|
+
- 密码、密钥等凭据禁止明文存储,使用 Thaad 加密
|
|
332
|
+
- 手机号、身份证号等 PII 字段在日志中脱敏打印(如 `138****1234`)
|
|
333
|
+
- 禁止在 URL 参数中传递敏感信息(token、密码等),使用 Header 或 POST body
|
|
334
|
+
- 禁止将敏感信息写入异常消息或返回给前端
|
|
335
|
+
|
|
336
|
+
## 进阶规范
|
|
337
|
+
|
|
338
|
+
根据当前任务场景,按需读取对应的进阶规范文件:
|
|
339
|
+
|
|
340
|
+
| 场景 | 规范文件 |
|
|
341
|
+
|------|---------|
|
|
342
|
+
| 多线程、线程池、锁、ThreadLocal | [references/concurrency.md](references/concurrency.md) |
|
|
343
|
+
| 消息一致性、缓存一致性、事务、幂等 | [references/distributed.md](references/distributed.md) |
|
|
344
|
+
| 输入输出转义、文件上传校验、风控 | [references/security.md](references/security.md) |
|
|
345
|
+
| 编写或审查单元测试 | [references/unit-testing.md](references/unit-testing.md) |
|
|
346
|
+
| Lion 配置读取、注解使用 | [references/config-center.md](references/config-center.md) |
|
|
347
|
+
| 定时任务设计、数据备份、分片 | [references/scheduled-task.md](references/scheduled-task.md) |
|
|
348
|
+
| ES 增删改查、分页、bulk 操作 | [references/es-coding.md](references/es-coding.md) |
|
|
349
|
+
|
|
350
|
+
## 检查清单
|
|
351
|
+
|
|
352
|
+
根据当前任务场景,只检查对应分组的项。不需要每次全量检查。
|
|
353
|
+
|
|
354
|
+
**写接口 / 定义模型时检查:**
|
|
355
|
+
- [ ] API 是否使用统一响应结构(Result<T>)
|
|
356
|
+
- [ ] 分页参数是否合理(page 从 0 开始,size 默认 20 最大 100)
|
|
357
|
+
- [ ] 接口命名是否符合动词+名词格式,与协议无关
|
|
358
|
+
- [ ] 参数是否使用包装类型封装,必填字段是否有 Validation 校验
|
|
359
|
+
- [ ] 错误码是否在枚举类中集中定义,格式是否为 模块前缀_数字
|
|
360
|
+
- [ ] 模型字段是否使用包装类型,金额字段类型是否正确(交易用 long 分,金融用 decimal)
|
|
361
|
+
- [ ] 跨层模型是否使用 MapStruct 转换,PO 是否暴露到 API 层
|
|
362
|
+
- [ ] 领域术语是否使用规范英文(cargo/order/freight 等)
|
|
363
|
+
|
|
364
|
+
**写业务逻辑时检查:**
|
|
365
|
+
- [ ] 异常处理是否分类处理,try-catch 范围是否最小
|
|
366
|
+
- [ ] 日志是否使用 SLF4J + {} 占位符,写链路是否打印出入参
|
|
367
|
+
- [ ] 二方三方调用是否通过防腐层、是否设置超时
|
|
368
|
+
- [ ] 敏感数据是否脱敏,SQL 是否使用 #{} 占位符
|
|
369
|
+
|
|
370
|
+
**涉及数据库操作时检查:**
|
|
371
|
+
- [ ] SQL 是否禁止 SELECT * 和循环执行,事务是否在 Service 层控制
|
|
372
|
+
|
|
373
|
+
**涉及并发/分布式场景时检查:**
|
|
374
|
+
- [ ] 并发控制是否合理(锁策略、线程池参数、ThreadLocal 清理)
|
|
375
|
+
- [ ] 幂等性是否保证(唯一约束、MQ 消费幂等)
|
|
376
|
+
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# 并发控制规范
|
|
2
|
+
|
|
3
|
+
多线程、线程池、锁、ThreadLocal 等并发场景的编码规范。
|
|
4
|
+
|
|
5
|
+
## 共享资源识别
|
|
6
|
+
|
|
7
|
+
多线程并发场景关注:单例对象、静态对象、共享内存、计数器、文件/数据库操作、线程池、缓存、网络资源、全局状态。
|
|
8
|
+
|
|
9
|
+
## 锁策略选择
|
|
10
|
+
|
|
11
|
+
| 场景 | 策略 |
|
|
12
|
+
|------|------|
|
|
13
|
+
| 高并发写、数据竞争激烈 | 悲观锁 |
|
|
14
|
+
| 读多写少 | 乐观锁 |
|
|
15
|
+
|
|
16
|
+
## 死锁预防
|
|
17
|
+
|
|
18
|
+
- 批量加锁严格控制顺序
|
|
19
|
+
- MySQL 事务内批量更新严格控制记录执行顺序
|
|
20
|
+
- 分布式锁必须设置过期时间
|
|
21
|
+
- 悲观锁必须使用可重入锁
|
|
22
|
+
|
|
23
|
+
## 线程池
|
|
24
|
+
|
|
25
|
+
创建线程池必须明确指定:核心线程数、最大线程数、等待队列长度、拒绝策略。
|
|
26
|
+
|
|
27
|
+
线程命名格式:`业务含义-` 前缀
|
|
28
|
+
|
|
29
|
+
```java
|
|
30
|
+
threadPoolTaskExecutor.setThreadNamePrefix("asyncMetricThread-");
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
**队列选择:**
|
|
34
|
+
- 稳定流量:同步队列或较大核心线程数
|
|
35
|
+
- 高低峰不均:阻塞队列,长度为线程数 3~5 倍
|
|
36
|
+
- 禁止使用无界队列
|
|
37
|
+
|
|
38
|
+
## 分布式锁
|
|
39
|
+
|
|
40
|
+
使用 `ironman-lock`,支持 Redis(CP)和 Zookeeper(AP)实现。
|
|
41
|
+
|
|
42
|
+
## 原子变量
|
|
43
|
+
|
|
44
|
+
优先使用 AtomicXxx,避免 volatile(volatile 只保证可见性不保证原子性)。
|
|
45
|
+
|
|
46
|
+
## 双重检查锁
|
|
47
|
+
|
|
48
|
+
延迟初始化必须使用 volatile + 临时变量确保对象完整构建后再赋值。
|
|
49
|
+
|
|
50
|
+
## ThreadLocal
|
|
51
|
+
|
|
52
|
+
- 能通过参数传递就不要通过 ThreadLocal
|
|
53
|
+
- 必须使用 ThreadLocal 时,使用完毕后在 finally 中 remove
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# 配置中心规范
|
|
2
|
+
|
|
3
|
+
Lion 配置读取、注解使用等配置中心场景的编码规范。
|
|
4
|
+
|
|
5
|
+
## 基本规则
|
|
6
|
+
|
|
7
|
+
- 配置值大小不超过 600KB
|
|
8
|
+
- Lion 配置对象全局唯一且只读,写操作必须先深拷贝
|
|
9
|
+
- Lion 配置的类型必须和代码声明类型一致,避免反序列化问题
|
|
10
|
+
- 固定结构的配置优先使用 JSON,不使用通用 String
|
|
11
|
+
|
|
12
|
+
## 注解使用
|
|
13
|
+
|
|
14
|
+
- Lion 注解注入的属性不应该设置为 `static`,不能使用 `final` 修饰
|
|
15
|
+
- `@Value` 注解不感知实时变更,只获取第一次的配置值
|
|
16
|
+
- BeanPostProcessor 之前的阶段,不能使用 Lion 注解,应使用 `ConfigCache.getInstance().getProperty()` 获取(注意此方式也不感知实时变更)
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# 分布式规范
|
|
2
|
+
|
|
3
|
+
消息一致性、缓存一致性、事务、幂等等分布式场景的编码规范。
|
|
4
|
+
|
|
5
|
+
## 消息一致性
|
|
6
|
+
|
|
7
|
+
**最终一致性消息:**
|
|
8
|
+
- Producer 必须有补偿策略,确保消息不丢失
|
|
9
|
+
- 领域事件发送:先持久化事件 → 发送 → 成功后更新状态 → 失败用 Job 补偿
|
|
10
|
+
|
|
11
|
+
**强一致性消息:**
|
|
12
|
+
- 必须使用 IronMan 的事务消息能力
|
|
13
|
+
|
|
14
|
+
## 缓存一致性
|
|
15
|
+
|
|
16
|
+
**读时更新缓存(高并发读场景):**
|
|
17
|
+
- 写链路使用延迟双删:删除缓存 → 更新数据库 → 延迟删除缓存
|
|
18
|
+
- 延迟时间与读链路 RT 相关
|
|
19
|
+
|
|
20
|
+
**写时更新缓存:**
|
|
21
|
+
- 使用最新数据写入,避免 ABA 问题
|
|
22
|
+
- 缓存写入失败需要补偿
|
|
23
|
+
|
|
24
|
+
## 事务
|
|
25
|
+
|
|
26
|
+
- 同一数据库多张表的写操作必须使用数据库事务
|
|
27
|
+
|
|
28
|
+
## 幂等
|
|
29
|
+
|
|
30
|
+
**资源创建幂等:**
|
|
31
|
+
- 必须定义唯一标识字段,相同请求只做一次处理,返回结果一致
|
|
32
|
+
|
|
33
|
+
**数据库唯一约束:**
|
|
34
|
+
- 使用数据库唯一性约束防止重复插入
|
|
35
|
+
- 逻辑删除场景,唯一索引需添加 `deleted_id` 字段,格式:`(A, B, deleted_id)`
|
|
36
|
+
|
|
37
|
+
**MQ 消费幂等:**
|
|
38
|
+
- Consumer 必须支持幂等,先检查是否已处理,使用消息 ID 或业务唯一键判断
|
|
39
|
+
|
|
40
|
+
## 线程安全
|
|
41
|
+
|
|
42
|
+
线上核心业务流程禁止使用 `Thread.sleep()`。
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
# ES 查询规范
|
|
2
|
+
|
|
3
|
+
- from/size 分页最大支持 10000 条,超过使用 `search_after`
|
|
4
|
+
- 禁止用 scroll 代替普通查询,scroll 仅用于数据导出
|
|
5
|
+
- 查询必须设置 timeout
|
|
6
|
+
- 精确匹配使用 filter(不计算评分,可利用缓存)
|
|
7
|
+
- 全文搜索使用 query(计算相关性评分)
|
|
8
|
+
|
|
9
|
+
## Filter vs Query
|
|
10
|
+
|
|
11
|
+
精确匹配用 filter:
|
|
12
|
+
|
|
13
|
+
```json
|
|
14
|
+
{
|
|
15
|
+
"query": {
|
|
16
|
+
"bool": {
|
|
17
|
+
"filter": [
|
|
18
|
+
{ "term": { "cargo_status": 1 } },
|
|
19
|
+
{ "range": { "create_time": { "gte": "2026-01-01", "lte": "2026-03-31" } } }
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
},
|
|
23
|
+
"timeout": "3s"
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
全文搜索用 query + filter 组合:
|
|
28
|
+
|
|
29
|
+
```json
|
|
30
|
+
{
|
|
31
|
+
"query": {
|
|
32
|
+
"bool": {
|
|
33
|
+
"must": [
|
|
34
|
+
{ "match": { "company_name": "Acme Logistics" } }
|
|
35
|
+
],
|
|
36
|
+
"filter": [
|
|
37
|
+
{ "term": { "cargo_status": 1 } }
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"timeout": "3s"
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Bulk 批量操作
|
|
46
|
+
|
|
47
|
+
使用 bulk 批量写入,bulk size 在 5~15MB 之间:
|
|
48
|
+
|
|
49
|
+
```json
|
|
50
|
+
{"index": {"_index": "cargo_info", "_id": "1001"}}
|
|
51
|
+
{"id": 1001, "order_no": "ORD202601001", "cargo_status": 1}
|
|
52
|
+
{"update": {"_index": "cargo_info", "_id": "1002"}}
|
|
53
|
+
{"doc": {"cargo_status": 2}}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
批量导入场景可临时调大 `refresh_interval` 提升写入性能。
|
|
57
|
+
|
|
58
|
+
## 连接管理
|
|
59
|
+
|
|
60
|
+
应用程序退出时必须调用 `restClient.close()` 关闭连接。
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# 定时任务规范
|
|
2
|
+
|
|
3
|
+
定时任务设计、数据备份、分片等场景的编码规范。
|
|
4
|
+
|
|
5
|
+
## 数据安全
|
|
6
|
+
|
|
7
|
+
- 执行刷数任务前必须记录原始数据,支持出问题时恢复
|
|
8
|
+
- 备份方案可选:备份表、增量数据分层、记录日志
|
|
9
|
+
|
|
10
|
+
## 任务设计
|
|
11
|
+
|
|
12
|
+
- 任务进度必须可观察、可持久化
|
|
13
|
+
- 任务中断后重新执行,已处理过的数据可跳过,支持从断点继续
|
|
14
|
+
- 无顺序依赖的任务,单条数据失败不阻塞整个任务,记录失败数据,支持失败部分重新处理
|
|
15
|
+
- 定时任务必须幂等,多次执行不会产生重复数据或操作,使用唯一标识或状态检查控制
|
|
16
|
+
- 多个任务的触发时间应分布在不同时段,平衡系统负载
|
|
17
|
+
|
|
18
|
+
## 数据量控制
|
|
19
|
+
|
|
20
|
+
- 任务处理数据量 > 10 万时,必须支持分片,考虑内存限制、CPU/IO 资源、实时性要求、并行处理能力
|
|
21
|
+
- 每批查询数据量 <= 1000,分批方式可选:分页、ID 范围、时间范围、消息队列
|
|
22
|
+
|
|
23
|
+
## 异常告警
|
|
24
|
+
|
|
25
|
+
任务处理失败或超时必须监控和告警,及时修复数据。
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# 单元测试规范
|
|
2
|
+
|
|
3
|
+
编写和审查单元测试时的编码规范。
|
|
4
|
+
|
|
5
|
+
## 基本原则
|
|
6
|
+
|
|
7
|
+
- 每个测试必须独立运行,测试之间不能有依赖关系
|
|
8
|
+
- 测试方法名清晰描述测试目的或行为,示例:`shouldThrowNotFoundException()`
|
|
9
|
+
- 每个测试必须包含断言,只有打印输出无法验证通过
|
|
10
|
+
- 一个单测只测一个功能,尽可能小而快
|
|
11
|
+
|
|
12
|
+
## 测试结构
|
|
13
|
+
|
|
14
|
+
遵循 Arrange-Act-Assert 模式:
|
|
15
|
+
|
|
16
|
+
```java
|
|
17
|
+
@Test
|
|
18
|
+
public void shouldReturnOrderWhenOrderExists() {
|
|
19
|
+
// Arrange
|
|
20
|
+
Order order = new Order();
|
|
21
|
+
order.setId(1L);
|
|
22
|
+
when(orderMapper.selectById(1L)).thenReturn(order);
|
|
23
|
+
|
|
24
|
+
// Act
|
|
25
|
+
Result<Order> result = orderService.getOrder(1L);
|
|
26
|
+
|
|
27
|
+
// Assert
|
|
28
|
+
assertTrue(result.isSuccess());
|
|
29
|
+
assertEquals(1L, result.getData().getId());
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Mock 使用
|
|
34
|
+
|
|
35
|
+
- 使用 JUnit + Mockito,外部资源(RPC、数据库、Redis、MQ)通过 Mock 隔离
|
|
36
|
+
- 只 Mock 外部依赖,不 Mock 被测方法所在类的内部方法
|
|
37
|
+
- Mock 返回值要覆盖正常、异常、边界场景
|
|
38
|
+
|
|
39
|
+
## 测试范围
|
|
40
|
+
|
|
41
|
+
- Service 层核心业务逻辑必须有单测覆盖
|
|
42
|
+
- 简单的 CRUD 和纯委托调用不需要单测
|
|
43
|
+
- 重点关注:分支逻辑、异常路径、边界值、幂等逻辑
|