@deepstorm/cli 0.10.2 → 0.11.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 +8 -8
- package/dist/build-registry.js +11 -5
- package/dist/cli.js +1256 -634
- package/dist/mcp/code-hosting/github.json +14 -1
- package/dist/mcp/docs-reference/context7.json +1 -10
- package/dist/mcp-skills/deepstorm-mcp-feishu-wiki-read/SKILL.md +8 -5
- package/dist/mcp-skills/deepstorm-mcp-feishu-wiki-write/SKILL.md +10 -8
- package/dist/mcp-skills/deepstorm-mcp-figma-read/SKILL.md +21 -20
- package/dist/mcp-skills/deepstorm-mcp-github-read/SKILL.md +17 -17
- package/dist/mcp-skills/deepstorm-mcp-github-write/SKILL.md +20 -20
- package/dist/mcp-skills/deepstorm-mcp-jira-read/SKILL.md +8 -8
- package/dist/mcp-skills/deepstorm-mcp-jira-write/SKILL.md +13 -12
- package/dist/mcp-skills/deepstorm-mcp-playwright-read/SKILL.md +10 -10
- package/dist/registry.json +10 -0
- package/dist/skills/atoll-ops/SKILL.md +4 -0
- package/dist/skills/reef-commit/SKILL.md +9 -5
- package/dist/skills/reef-commit/scripts/branch-check.mjs +5 -11
- package/dist/skills/reef-commit/scripts/check-openspec-status.mjs +6 -12
- package/dist/skills/reef-commit/scripts/collect-git-context.mjs +13 -11
- package/dist/skills/reef-gen-backend/variants/java/steps.md +7 -7
- package/dist/skills/reef-gen-backend/variants/nodejs/steps.md +7 -7
- package/dist/skills/reef-gen-backend/variants/python/steps.md +7 -7
- package/dist/skills/reef-gen-frontend/variants/angular/steps.md +5 -5
- package/dist/skills/reef-gen-frontend/variants/react/steps.md +6 -6
- package/dist/skills/reef-gen-frontend/variants/vue/steps.md +6 -6
- package/dist/skills/reef-harden/EXAMPLES.md +12 -10
- package/dist/skills/reef-harden/SKILL.md +6 -0
- package/dist/skills/reef-harden/scripts/find-change-dir.mjs +13 -13
- package/dist/skills/reef-pr/SKILL.md +7 -0
- package/dist/skills/reef-pr/scripts/create-pr.mjs +31 -29
- package/dist/skills/reef-scope/SKILL.md +6 -6
- package/dist/skills/reef-start/references/jira-start-subagent.md +7 -7
- package/dist/skills/reef-start/references/risk-routing-card.md +28 -25
- package/dist/skills/reef-start/references/stage-4-implementation.md +33 -21
- package/dist/skills/reef-start/references/superpowers-gate.md +9 -9
- package/dist/skills/reef-style-backend/fragments/java/ai/spring-ai/examples/structured-output.md +2 -2
- package/dist/skills/reef-style-backend/fragments/java/ai/spring-ai/quick-reference.md +11 -0
- package/dist/skills/reef-style-backend/fragments/java/api-spec/jackson-polymorphism.md +36 -40
- package/dist/skills/reef-style-backend/fragments/java/api-spec/quick-reference.md +11 -10
- package/dist/skills/reef-style-backend/fragments/java/db-migration/liquibase/examples/database-migration.md +7 -7
- package/dist/skills/reef-style-backend/fragments/java/dependency-management/quick-reference.md +24 -21
- package/dist/skills/reef-style-backend/fragments/java/exception-handling/examples/error-code-enum.md +7 -7
- package/dist/skills/reef-style-backend/fragments/java/exception-handling/quick-reference.md +10 -8
- package/dist/skills/reef-style-backend/fragments/java/framework/spring-boot/examples/dto-mapper.md +2 -2
- package/dist/skills/reef-style-backend/fragments/java/framework/spring-boot/examples/service-entity.md +5 -5
- package/dist/skills/reef-style-backend/fragments/java/framework/spring-boot/examples/testing.md +1 -0
- package/dist/skills/reef-style-backend/fragments/java/framework/spring-boot/quick-reference.md +12 -12
- package/dist/skills/reef-style-backend/fragments/java/orm/hibernate/quick-reference.md +13 -12
- package/dist/skills/reef-style-backend/fragments/java/security-redlines/quick-reference.md +11 -9
- package/dist/skills/reef-style-backend/fragments/java/test/data-jpa-test/quick-reference.md +7 -7
- package/dist/skills/reef-style-backend/fragments/java/test/junit5/quick-reference.md +6 -6
- package/dist/skills/reef-style-backend/fragments/java/test/spring-mvc-test/quick-reference.md +8 -8
- package/dist/skills/reef-style-backend/fragments/java/test/spring-service-test/quick-reference.md +8 -7
- package/dist/skills/reef-style-backend/fragments/nodejs/eslint-config.json +1 -4
- package/dist/skills/reef-style-backend/fragments/nodejs/nestjs-structure.md +9 -9
- package/dist/skills/reef-style-backend/fragments/python/alembic-migration/quick-reference.md +2 -1
- package/dist/skills/reef-style-backend/fragments/python/api-spec/quick-reference.md +10 -10
- package/dist/skills/reef-style-backend/fragments/python/dependency-management/quick-reference.md +24 -22
- package/dist/skills/reef-style-backend/fragments/python/exception-handling/quick-reference.md +10 -9
- package/dist/skills/reef-style-backend/fragments/python/fastapi-quick-reference/quick-reference.md +3 -0
- package/dist/skills/reef-style-backend/fragments/python/langchain/quick-reference.md +10 -7
- package/dist/skills/reef-style-backend/fragments/python/pytest-testing/quick-reference.md +2 -0
- package/dist/skills/reef-style-backend/fragments/python/ruff-mypy-toolchain/quick-reference.md +2 -0
- package/dist/skills/reef-style-backend/fragments/python/security-redlines/quick-reference.md +11 -9
- package/dist/skills/reef-style-backend/fragments/python/sqlalchemy-orm/quick-reference.md +3 -0
- package/dist/skills/reef-style-backend/variants/java/examples/code-wrapping.md +3 -4
- package/dist/skills/reef-style-backend/variants/java/quick-reference.md +31 -29
- package/dist/skills/reef-style-backend/variants/nodejs/examples/module-example.md +2 -8
- package/dist/skills/reef-style-backend/variants/nodejs/quick-reference.md +35 -36
- package/dist/skills/reef-style-backend/variants/python/quick-reference.md +32 -31
- package/dist/skills/reef-style-frontend/fragments/css/tailwind/quick-reference.md +9 -7
- package/dist/skills/reef-style-frontend/fragments/test/vitest/examples/testing.md +9 -4
- package/dist/skills/reef-style-frontend/fragments/test/vitest/quick-reference.md +4 -4
- package/dist/skills/reef-style-frontend/fragments/test/vitest-react/examples/testing.md +135 -140
- package/dist/skills/reef-style-frontend/fragments/test/vitest-react/quick-reference.md +32 -32
- package/dist/skills/reef-style-frontend/fragments/test/vitest-vue/examples/testing.md +161 -162
- package/dist/skills/reef-style-frontend/fragments/test/vitest-vue/quick-reference.md +42 -42
- package/dist/skills/reef-style-frontend/fragments/ts-config/strict/quick-reference.md +16 -10
- package/dist/skills/reef-style-frontend/fragments/ui-lib/antd/examples/ui-components.md +72 -87
- package/dist/skills/reef-style-frontend/fragments/ui-lib/antd/quick-reference.md +14 -10
- package/dist/skills/reef-style-frontend/fragments/ui-lib/antd-vue/examples/ui-components.md +93 -111
- package/dist/skills/reef-style-frontend/fragments/ui-lib/antd-vue/quick-reference.md +29 -33
- package/dist/skills/reef-style-frontend/fragments/ui-lib/primeng/examples/ui-components.md +14 -23
- package/dist/skills/reef-style-frontend/variants/angular/examples/code-wrapping.md +15 -17
- package/dist/skills/reef-style-frontend/variants/angular/examples/component-types-pipes.md +22 -5
- package/dist/skills/reef-style-frontend/variants/angular/examples/entity-types.md +52 -22
- package/dist/skills/reef-style-frontend/variants/angular/examples/forms-layer.md +17 -20
- package/dist/skills/reef-style-frontend/variants/angular/examples/service-routing.md +8 -11
- package/dist/skills/reef-style-frontend/variants/angular/quick-reference.md +27 -27
- package/dist/skills/reef-style-frontend/variants/react/examples/code-wrapping.md +14 -27
- package/dist/skills/reef-style-frontend/variants/react/examples/component-types-pipes.md +45 -52
- package/dist/skills/reef-style-frontend/variants/react/examples/entity-types.md +44 -44
- package/dist/skills/reef-style-frontend/variants/react/examples/forms-layer.md +56 -85
- package/dist/skills/reef-style-frontend/variants/react/examples/service-routing.md +114 -88
- package/dist/skills/reef-style-frontend/variants/react/quick-reference.md +48 -42
- package/dist/skills/reef-style-frontend/variants/vue/examples/code-wrapping.md +24 -43
- package/dist/skills/reef-style-frontend/variants/vue/examples/component-types-pipes.md +48 -49
- package/dist/skills/reef-style-frontend/variants/vue/examples/entity-types.md +45 -45
- package/dist/skills/reef-style-frontend/variants/vue/examples/forms-layer.md +64 -68
- package/dist/skills/reef-style-frontend/variants/vue/examples/service-routing.md +85 -84
- package/dist/skills/reef-style-frontend/variants/vue/quick-reference.md +46 -51
- package/dist/skills/reef-testcase/SKILL.md +19 -19
- package/dist/skills/reef-testcase/references/coverage-dimensions.md +8 -0
- package/dist/skills/reef-testcase/references/test-case-template.md +16 -16
- package/dist/skills/sweep-explore/SKILL.md +824 -0
- package/dist/skills/sweep-explore/references/explore-flow-template.md +61 -0
- package/dist/skills/sweep-init/SKILL.md +4 -0
- package/dist/skills/sweep-init/scripts/flow-selector.mjs +6 -11
- package/dist/skills/sweep-init/scripts/init-project.mjs +68 -51
- package/dist/skills/sweep-plan/references/test-flow-template.md +12 -6
- package/dist/skills/sweep-record/SKILL.md +358 -0
- package/dist/skills/sweep-run/SKILL.md +59 -50
- package/dist/skills/sweep-run/scripts/env-manager.mjs +4 -5
- package/dist/skills/sweep-run/scripts/flow-parser.mjs +7 -6
- package/dist/skills/sweep-run/scripts/flow-selector.mjs +4 -15
- package/dist/skills/sweep-run/scripts/generate-report.mjs +1 -2
- package/dist/skills/sweep-run/scripts/mcp-manager.mjs +107 -14
- package/dist/skills/sweep-run/scripts/spec-compiler.mjs +19 -9
- package/dist/skills/tide-discuss/references/checklists.md +32 -32
- package/dist/skills/tide-discuss/references/data-format.md +85 -77
- package/dist/skills/tide-discuss/references/prd-template.md +21 -19
- package/dist/skills/tide-discuss/references/publish-flow.md +30 -11
- package/dist/skills/tide-discuss/references/role-prompts.md +5 -5
- package/package.json +5 -3
|
@@ -53,6 +53,7 @@ PLAN_FILE="docs/superpowers/plans/$(date +%Y-%m-%d)-$CHANGE.md"
|
|
|
53
53
|
适用于:新增业务逻辑、Bug 修复、权限/安全变更、资金/幂等性变更、状态机/并发逻辑
|
|
54
54
|
|
|
55
55
|
**🔴 RED — 先写测试**
|
|
56
|
+
|
|
56
57
|
- 先确认 code-style 已加载:检查 `reef:reef-style-backend` 或 `reef:reef-style-frontend` 是否已通过 Skill tool 加载,未加载则先加载
|
|
57
58
|
- 根据 spec 的 Scenario 编写单元测试
|
|
58
59
|
- 运行测试,确认失败(红)
|
|
@@ -60,12 +61,14 @@ PLAN_FILE="docs/superpowers/plans/$(date +%Y-%m-%d)-$CHANGE.md"
|
|
|
60
61
|
- **不写实现代码**
|
|
61
62
|
|
|
62
63
|
**🟢 GREEN — 最小实现**
|
|
64
|
+
|
|
63
65
|
- 只写让当前测试通过的最小代码量
|
|
64
66
|
- 不提前实现未测试的功能
|
|
65
67
|
- 运行测试,确认全绿
|
|
66
68
|
- 如果感觉"这段代码还没写完",那是正常的 — 下一个 task 会覆盖
|
|
67
69
|
|
|
68
70
|
**🔵 REFACTOR — 保持测试通过的前提下重构**
|
|
71
|
+
|
|
69
72
|
- 清理重复代码、提取函数、重命名
|
|
70
73
|
- 保持测试运行通过
|
|
71
74
|
- 不改变行为
|
|
@@ -97,13 +100,13 @@ Step 3: Test 验证
|
|
|
97
100
|
|
|
98
101
|
根据项目技术栈自动选择对应命令。无法推断时询问用户,并将结果写入 task 笔记复用。
|
|
99
102
|
|
|
100
|
-
| 框架
|
|
101
|
-
|
|
102
|
-
| Java Spring Boot
|
|
103
|
-
| Python FastAPI
|
|
104
|
-
| Node.js / TypeScript | `npm run build` 或 `pnpm build`
|
|
105
|
-
| Go
|
|
106
|
-
| 无法推断
|
|
103
|
+
| 框架 | Build | Lint | Test |
|
|
104
|
+
| -------------------- | -------------------------------------------------------- | ---------------------------------------- | ---------------------------------------------------- |
|
|
105
|
+
| Java Spring Boot | `mvn compile` | `mvn checkstyle:check` 或 `mvn validate` | `mvn test` |
|
|
106
|
+
| Python FastAPI | `pip install -e .` dry-run 或 `poetry install --dry-run` | `ruff check .` 或 `pylint` | `pytest` |
|
|
107
|
+
| Node.js / TypeScript | `npm run build` 或 `pnpm build` | `npm run lint` 或 `pnpm lint` | `npm test` 或 `pnpm test -- --related`(仅关联用例) |
|
|
108
|
+
| Go | `go build ./...` | `golint` 或 `go vet` | `go test ./...` |
|
|
109
|
+
| 无法推断 | 询问用户当前可用的验证命令 | 同左 | 同左 |
|
|
107
110
|
|
|
108
111
|
### 完成一个 task 后
|
|
109
112
|
|
|
@@ -161,7 +164,15 @@ VERIFY_REPORT="openspec/changes/$CHANGE/verify-report.json"
|
|
|
161
164
|
"tasks": { "total": 17, "passed": 17 },
|
|
162
165
|
"build": { "command": "npm run build", "exitCode": 0, "passed": true, "duration": 8 },
|
|
163
166
|
"lint": { "command": "npm run lint", "exitCode": 0, "passed": true },
|
|
164
|
-
"tests": {
|
|
167
|
+
"tests": {
|
|
168
|
+
"command": "npm test",
|
|
169
|
+
"exitCode": 0,
|
|
170
|
+
"passed": true,
|
|
171
|
+
"total": 42,
|
|
172
|
+
"passed": 42,
|
|
173
|
+
"failed": 0,
|
|
174
|
+
"duration": 15
|
|
175
|
+
},
|
|
165
176
|
"acCoverage": { "total": 5, "covered": 4, "uncovered": ["AC-5: ..."] },
|
|
166
177
|
"review": { "findings": 3, "blockers": 0, "warnings": 2, "suggestions": 1, "reportPath": "..." },
|
|
167
178
|
"summary": "PASSED"
|
|
@@ -169,20 +180,21 @@ VERIFY_REPORT="openspec/changes/$CHANGE/verify-report.json"
|
|
|
169
180
|
```
|
|
170
181
|
|
|
171
182
|
**摘要字段取值:**
|
|
183
|
+
|
|
172
184
|
- `PASSED` — 所有检查通过
|
|
173
185
|
- `PASSED with warnings` — 有 warning 但无 blocker
|
|
174
186
|
- `FAILED` — 存在 blocker 或测试失败
|
|
175
187
|
|
|
176
188
|
**汇总逻辑:**
|
|
177
189
|
|
|
178
|
-
| 数据来源
|
|
179
|
-
|
|
180
|
-
| tasks.md
|
|
181
|
-
| 后置验证 build
|
|
182
|
-
| 后置验证 lint
|
|
183
|
-
| 后置验证 test
|
|
190
|
+
| 数据来源 | 对应字段 | 说明 |
|
|
191
|
+
| --------------- | ------------ | ----------------------------- |
|
|
192
|
+
| tasks.md | `tasks` | 已完成的 task 数 / 总 task 数 |
|
|
193
|
+
| 后置验证 build | `build` | build 命令、退出码、耗时 |
|
|
194
|
+
| 后置验证 lint | `lint` | lint 命令、退出码 |
|
|
195
|
+
| 后置验证 test | `tests` | 测试命令、总数/通过/失败 |
|
|
184
196
|
| AC-to-test 回溯 | `acCoverage` | AC 覆盖总数/已覆盖/未覆盖列表 |
|
|
185
|
-
| code-audit 结果 | `review`
|
|
197
|
+
| code-audit 结果 | `review` | findings 统计 + 报告路径 |
|
|
186
198
|
|
|
187
199
|
写入后向用户摘要报告关键数据,用户确认后再进入分支结束处理。
|
|
188
200
|
|
|
@@ -190,9 +202,9 @@ VERIFY_REPORT="openspec/changes/$CHANGE/verify-report.json"
|
|
|
190
202
|
|
|
191
203
|
询问用户:**创建提交 / 创建 PR / 保留分支 / 丢弃分支**
|
|
192
204
|
|
|
193
|
-
| 操作
|
|
194
|
-
|
|
195
|
-
| 创建提交 | 中文 message + Issue URL(Path A 有则加,Path B 可选)+ PRD 链接(如有),verify-report.json 随 change 目录归档
|
|
196
|
-
| 创建 PR
|
|
197
|
-
| 保留分支 | 报告分支名和变更位置
|
|
198
|
-
| 丢弃分支 | 用户确认后删除
|
|
205
|
+
| 操作 | 说明 |
|
|
206
|
+
| -------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
207
|
+
| 创建提交 | 中文 message + Issue URL(Path A 有则加,Path B 可选)+ PRD 链接(如有),verify-report.json 随 change 目录归档 |
|
|
208
|
+
| 创建 PR | `git push -u origin "$CHANGE"` → `gh pr create`,verify-report.json 随 change 目录移入 `openspec/changes/archive/` |
|
|
209
|
+
| 保留分支 | 报告分支名和变更位置 |
|
|
210
|
+
| 丢弃分支 | 用户确认后删除 |
|
|
@@ -68,12 +68,12 @@
|
|
|
68
68
|
|
|
69
69
|
> 以下每一个想法都是一个危险信号。**任何一个出现 → 立即停止 → 回到本步骤执行 superpowers 检查。**
|
|
70
70
|
|
|
71
|
-
| 想法
|
|
72
|
-
|
|
73
|
-
| "tasks + plan 都完成了,直接实现吧"
|
|
74
|
-
| "tasks 完成了,直接进入实现吧"
|
|
75
|
-
| "这个变更很简单,不需要检查"
|
|
76
|
-
| "我知道 TDD 是什么,不用加载技能"
|
|
77
|
-
| "先搞快点,后面再补测试"
|
|
78
|
-
| "子代理一次性写代码效率高,TDD 太慢" | TDD 铁律优先于效率。质量不可妥协。
|
|
79
|
-
| "已经改了代码,回头补测试也一样"
|
|
71
|
+
| 想法 | 现实 |
|
|
72
|
+
| ------------------------------------ | -------------------------------------------------------------------------------------------- |
|
|
73
|
+
| "tasks + plan 都完成了,直接实现吧" | ❌ 必须先走完 3.8 语言规范 → 3.9 用户确认 → Superpowers 门禁。plan 生成 ≠ 可以跳过后续步骤。 |
|
|
74
|
+
| "tasks 完成了,直接进入实现吧" | ❌ 必须先检查 superpowers。顺序不可颠倒。 |
|
|
75
|
+
| "这个变更很简单,不需要检查" | 只要有 1% 的可能性适用,就**必须**检查。 |
|
|
76
|
+
| "我知道 TDD 是什么,不用加载技能" | 技能会更新。加载当前版本才有效。 |
|
|
77
|
+
| "先搞快点,后面再补测试" | 补 = 不补。不可协商的纪律。 |
|
|
78
|
+
| "子代理一次性写代码效率高,TDD 太慢" | TDD 铁律优先于效率。质量不可妥协。 |
|
|
79
|
+
| "已经改了代码,回头补测试也一样" | 测试-after 和 TDD 不等价。测试-after 验证的是"代码做了什么",不是"代码应该做什么"。 |
|
package/dist/skills/reef-style-backend/fragments/java/ai/spring-ai/examples/structured-output.md
CHANGED
|
@@ -16,7 +16,7 @@ log.info("城市: {}, 温度: {}{}", weather.city(), weather.temperature(), weat
|
|
|
16
16
|
|
|
17
17
|
## 嵌套结构
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
````java
|
|
20
20
|
public record CodeReviewResult(
|
|
21
21
|
String file,
|
|
22
22
|
List<Issue> issues,
|
|
@@ -44,7 +44,7 @@ CodeReviewResult result = chatClient.prompt()
|
|
|
44
44
|
""")
|
|
45
45
|
.call()
|
|
46
46
|
.entity(CodeReviewResult.class);
|
|
47
|
-
|
|
47
|
+
````
|
|
48
48
|
|
|
49
49
|
## 列表输出
|
|
50
50
|
|
|
@@ -7,6 +7,7 @@ Spring AI 是 Spring 生态中的 AI 集成框架,提供统一的 API 来调
|
|
|
7
7
|
## 核心概念
|
|
8
8
|
|
|
9
9
|
### ChatClient
|
|
10
|
+
|
|
10
11
|
Spring AI 的中央 API,用于与大语言模型交互。
|
|
11
12
|
|
|
12
13
|
```java
|
|
@@ -17,6 +18,7 @@ ChatClient chatClient(ChatClient.Builder builder) {
|
|
|
17
18
|
```
|
|
18
19
|
|
|
19
20
|
**最佳实践:**
|
|
21
|
+
|
|
20
22
|
- `ChatClient` 声明为 `@Bean` 并注入使用,不直接创建实例
|
|
21
23
|
- `defaultSystem()` 设置默认系统提示词
|
|
22
24
|
- `builder.clone()` 创建独立的客户端实例(需要不同配置时)
|
|
@@ -33,6 +35,7 @@ public List<Order> getOrders(@ToolParam(description = "用户 ID") String userId
|
|
|
33
35
|
```
|
|
34
36
|
|
|
35
37
|
**最佳实践:**
|
|
38
|
+
|
|
36
39
|
- 每个 `@Tool` 方法加 `description` 描述,帮助模型选择正确的工具
|
|
37
40
|
- `@ToolParam` 的 `description` 帮助模型理解参数含义
|
|
38
41
|
- 工具方法放在 `@Service` 类中,统一管理
|
|
@@ -51,6 +54,7 @@ ChatClientResponse response = chatClient.prompt()
|
|
|
51
54
|
```
|
|
52
55
|
|
|
53
56
|
**常见 Advisor:**
|
|
57
|
+
|
|
54
58
|
- `QuestionAnswerAdvisor` — RAG 支持
|
|
55
59
|
- `MessageChatMemoryAdvisor` — 对话记忆
|
|
56
60
|
- `LoggingAdvisor` — 日志记录
|
|
@@ -80,6 +84,7 @@ public class DocumentService {
|
|
|
80
84
|
```
|
|
81
85
|
|
|
82
86
|
**最佳实践:**
|
|
87
|
+
|
|
83
88
|
- VectorStore 通过 Spring DI 注入,不同实现(PGVector、Redis、Chroma)切换只需改配置
|
|
84
89
|
- 文档入库时保留 metadata(来源、更新时间、权限)
|
|
85
90
|
|
|
@@ -97,6 +102,7 @@ WeatherResponse weather = chatClient.prompt()
|
|
|
97
102
|
```
|
|
98
103
|
|
|
99
104
|
**最佳实践:**
|
|
105
|
+
|
|
100
106
|
- 使用 `record` 而非 class 定义输出结构
|
|
101
107
|
- 字段类型明确,避免 `String` 滥用
|
|
102
108
|
|
|
@@ -114,6 +120,7 @@ spring:
|
|
|
114
120
|
```
|
|
115
121
|
|
|
116
122
|
**最佳实践:**
|
|
123
|
+
|
|
117
124
|
- API Key 始终通过 `${}` 环境变量引用,不硬编码
|
|
118
125
|
- 敏感配置放在 `.env` 文件中,不提交到 Git
|
|
119
126
|
|
|
@@ -136,6 +143,7 @@ spring:
|
|
|
136
143
|
```
|
|
137
144
|
|
|
138
145
|
**可用模型:**
|
|
146
|
+
|
|
139
147
|
- `deepseek-chat` — 通用对话模型,适用于日常问答、代码生成、内容创作
|
|
140
148
|
- `deepseek-reasoner` — 推理模型,适用于复杂推理、数学问题、逻辑分析(通过 API 调用,Spring AI Starter 暂未直接封装)
|
|
141
149
|
|
|
@@ -174,6 +182,7 @@ implementation 'org.springframework.ai:spring-ai-starter-model-deepseek'
|
|
|
174
182
|
```
|
|
175
183
|
|
|
176
184
|
或 Maven:
|
|
185
|
+
|
|
177
186
|
```xml
|
|
178
187
|
<dependency>
|
|
179
188
|
<groupId>org.springframework.ai</groupId>
|
|
@@ -191,6 +200,7 @@ implementation 'org.springframework.ai:spring-ai-pgvector-store-spring-boot-star
|
|
|
191
200
|
```
|
|
192
201
|
|
|
193
202
|
或 Maven:
|
|
203
|
+
|
|
194
204
|
```xml
|
|
195
205
|
<dependency>
|
|
196
206
|
<groupId>org.springframework.ai</groupId>
|
|
@@ -211,6 +221,7 @@ try {
|
|
|
211
221
|
```
|
|
212
222
|
|
|
213
223
|
**注意事项:**
|
|
224
|
+
|
|
214
225
|
- AI 调用可能失败或超时,必须有降级逻辑
|
|
215
226
|
- 记录 AI 调用的输入和输出,便于调试和审计
|
|
216
227
|
|
|
@@ -77,6 +77,7 @@ public class LineChartView extends ChartView {
|
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
> **💡 Import 说明:**
|
|
80
|
+
>
|
|
80
81
|
> - `@JsonTypeInfo`、`@JsonSubTypes`、`@JsonInclude` 来自 `com.fasterxml.jackson.annotation.*`
|
|
81
82
|
> - `@JsonInclude(Include.NON_NULL)` 需导入 `com.fasterxml.jackson.annotation.JsonInclude.Include`
|
|
82
83
|
> - 或在注解中写全路径 `@JsonInclude(JsonInclude.Include.NON_NULL)`,无需额外 import
|
|
@@ -127,63 +128,58 @@ export type ChartView = MetricCardView | LineChartView | BarChartView | PieChart
|
|
|
127
128
|
```typescript
|
|
128
129
|
export interface MetricAnswer {
|
|
129
130
|
// ...
|
|
130
|
-
chartView: ChartView | null;
|
|
131
|
+
chartView: ChartView | null; // ✅ 联合类型自动窄化
|
|
131
132
|
}
|
|
132
133
|
```
|
|
133
134
|
|
|
134
135
|
**步骤 3:模板中使用 @switch**
|
|
135
136
|
|
|
136
137
|
```html
|
|
137
|
-
@if (answer.chartView) {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
@case ('LineChartView') {
|
|
143
|
-
<app-line-chart [chartData]="answer.chartData" />
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
}
|
|
138
|
+
@if (answer.chartView) { @switch (answer.chartView.type) { @case ('MetricCardView') {
|
|
139
|
+
<app-metric-card [answer]="answer" />
|
|
140
|
+
} @case ('LineChartView') {
|
|
141
|
+
<app-line-chart [chartData]="answer.chartData" />
|
|
142
|
+
} } }
|
|
147
143
|
```
|
|
148
144
|
|
|
149
145
|
## 三、最佳实践
|
|
150
146
|
|
|
151
|
-
| 要点
|
|
152
|
-
|
|
153
|
-
| `property = "type"` | discriminator 字段名使用 `"type"`(简短、通用),而非 `"chartType"`
|
|
154
|
-
| 前后端 value 一致
|
|
155
|
-
| Checkstyle 兼容
|
|
156
|
-
| 共享 DTO
|
|
157
|
-
| 判空安全
|
|
158
|
-
| 不删除旧 DTO 层
|
|
159
|
-
| 删除前确认引用
|
|
147
|
+
| 要点 | 说明 |
|
|
148
|
+
| ------------------- | -------------------------------------------------------------------------------------------------------- |
|
|
149
|
+
| `property = "type"` | discriminator 字段名使用 `"type"`(简短、通用),而非 `"chartType"` |
|
|
150
|
+
| 前后端 value 一致 | `@JsonSubTypes.Type(name = "MetricCardView")` 与 TS `type: 'MetricCardView'` 的值必须一致 |
|
|
151
|
+
| Checkstyle 兼容 | Jackson 字段名与 getter 名可以不同:`@JsonProperty("xAxisName") private String categoryAxisLabel` |
|
|
152
|
+
| 共享 DTO | 子类共享的嵌套类型(如 `ChartDataPoint`)定义为独立 `record` 或类 |
|
|
153
|
+
| 判空安全 | 模板中 `@if (answer.chartView)` 保护空值(如错误响应时 chartView 为 null) |
|
|
154
|
+
| 不删除旧 DTO 层 | `ChartData`、`gridResults`、`singleResults` 等依然存在,chartView 是新增的视图抽象,并非替代所有响应字段 |
|
|
155
|
+
| 删除前确认引用 | 删除旧枚举前 MUST 搜索全项目 Java + TypeScript 引用,确认 0 引用后方可删除 |
|
|
160
156
|
|
|
161
157
|
## 四、效果对比
|
|
162
158
|
|
|
163
|
-
| 维度
|
|
164
|
-
|
|
165
|
-
| 新增图表类型 | 枚举 + switch + 前端分支
|
|
166
|
-
| JSON 结构
|
|
167
|
-
| TS 类型安全
|
|
168
|
-
| 后端字段数
|
|
159
|
+
| 维度 | 旧模式(Enum) | 新模式(Polymorphism) |
|
|
160
|
+
| ------------ | ----------------------------------- | ------------------------------------------------ |
|
|
161
|
+
| 新增图表类型 | 枚举 + switch + 前端分支 | 新建子类 + 注册 `@JsonSubTypes` + TS 类型 |
|
|
162
|
+
| JSON 结构 | `{"chartType": "METRIC_CARD", ...}` | `{"chartView": {"type": "MetricCardView", ...}}` |
|
|
163
|
+
| TS 类型安全 | 手动维护 | 自动通过 discriminated union 窄化 |
|
|
164
|
+
| 后端字段数 | chartType + 具体数据各自校验 | chartView 自包含 |
|
|
169
165
|
|
|
170
166
|
## 五、设计决策说明
|
|
171
167
|
|
|
172
168
|
### 5.1 `property` 选择 `"type"` 而非 `"chartType"`
|
|
173
169
|
|
|
174
|
-
| 候选
|
|
175
|
-
|
|
176
|
-
| `"type"`
|
|
177
|
-
| `"chartType"` | 业务含义明确,但限制了基类的可复用性。未来其他多态场景(如 `DataSourceConnector`)需要不同字段名 | ❌
|
|
178
|
-
| `"kind"`
|
|
170
|
+
| 候选 | 理由 | 结论 |
|
|
171
|
+
| ------------- | ------------------------------------------------------------------------------------------------ | ---- |
|
|
172
|
+
| `"type"` | 简短通用,多态基类职责就是描述"是什么类型",与低代码项目 (`DatasetDto`) 一致 | ✅ |
|
|
173
|
+
| `"chartType"` | 业务含义明确,但限制了基类的可复用性。未来其他多态场景(如 `DataSourceConnector`)需要不同字段名 | ❌ |
|
|
174
|
+
| `"kind"` | Jackson 社区惯例使用 `"type"`,不应引入不必要的差异 | ❌ |
|
|
179
175
|
|
|
180
176
|
### 5.2 discriminator 策略使用 `SIMPLE_NAME`
|
|
181
177
|
|
|
182
|
-
| 候选
|
|
183
|
-
|
|
184
|
-
| `SIMPLE_NAME` | 子类简名自描述,无需额外常量文件
|
|
185
|
-
| `CLASS_NAME`
|
|
186
|
-
| `CUSTOM`
|
|
178
|
+
| 候选 | 理由 | 结论 |
|
|
179
|
+
| ------------- | --------------------------------------- | ---- |
|
|
180
|
+
| `SIMPLE_NAME` | 子类简名自描述,无需额外常量文件 | ✅ |
|
|
181
|
+
| `CLASS_NAME` | 全限定名过长,JSON 中不可读且暴露包结构 | ❌ |
|
|
182
|
+
| `CUSTOM` | 需要 `@JsonTypeIdResolver`,增加复杂度 | ❌ |
|
|
187
183
|
|
|
188
184
|
### 5.3 使用 `@JsonSubTypes` 而非自定义序列化器
|
|
189
185
|
|
|
@@ -195,10 +191,10 @@ TypeScript union type + `type` literal 可直接利用 `@switch` 的类型窄化
|
|
|
195
191
|
|
|
196
192
|
### 5.5 Checkstyle 冲突:`@JsonProperty` 解耦而非禁用规则
|
|
197
193
|
|
|
198
|
-
| 候选
|
|
199
|
-
|
|
200
|
-
| `@JsonProperty("xAxisName") private String categoryAxisLabel` | 字段名合规,getter 合规,JSON 输出保留 `xAxisName` | ✅
|
|
201
|
-
| 禁用 Checkstyle `ParameterNameCheck`
|
|
194
|
+
| 候选 | 理由 | 结论 |
|
|
195
|
+
| ------------------------------------------------------------- | -------------------------------------------------- | ---- |
|
|
196
|
+
| `@JsonProperty("xAxisName") private String categoryAxisLabel` | 字段名合规,getter 合规,JSON 输出保留 `xAxisName` | ✅ |
|
|
197
|
+
| 禁用 Checkstyle `ParameterNameCheck` | 全局禁用降低代码规范性 | ❌ |
|
|
202
198
|
|
|
203
199
|
### 5.6 DTO 对象保持 record
|
|
204
200
|
|
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
## 速查
|
|
4
4
|
|
|
5
|
-
| 场景
|
|
6
|
-
|
|
|
7
|
-
| 资源路径
|
|
8
|
-
| 自定义动作 | AIP-136 冒号语法:`@PostMapping("/{id}:publish")`
|
|
9
|
-
| 查询参数
|
|
10
|
-
| 统一响应体 | `ApiResponse<T>` / `PageResponse<T>` / `ErrorResponse`
|
|
11
|
-
| 版本策略
|
|
12
|
-
| 错误响应
|
|
13
|
-
| 分页
|
|
14
|
-
| OpenAPI
|
|
5
|
+
| 场景 | 决策 |
|
|
6
|
+
| ---------- | ------------------------------------------------------------------------------------------ |
|
|
7
|
+
| 资源路径 | 英文复数 kebab-case:`/api/v1/user-roles`,不是 `/api/v1/userRoles` 或 `/api/v1/user_role` |
|
|
8
|
+
| 自定义动作 | AIP-136 冒号语法:`@PostMapping("/{id}:publish")` |
|
|
9
|
+
| 查询参数 | `?status=active&page=0&size=20&sort=name,asc` |
|
|
10
|
+
| 统一响应体 | `ApiResponse<T>` / `PageResponse<T>` / `ErrorResponse` |
|
|
11
|
+
| 版本策略 | URL path 前缀 `/api/v1/`;非破坏性变更不升级,破坏性变更 +1 |
|
|
12
|
+
| 错误响应 | AIP-193 兼容 `ErrorResponse`:`{ "code": "USER_001", "message": "...", "detail": {} }` |
|
|
13
|
+
| 分页 | Spring `Pageable` → `PageResponse` |
|
|
14
|
+
| OpenAPI | `@Operation(summary = "...")` + `@ApiResponse` + `@Tag(name = "users")` |
|
|
15
15
|
|
|
16
16
|
## 核心规范
|
|
17
17
|
|
|
@@ -113,6 +113,7 @@ public class UserController {
|
|
|
113
113
|
```
|
|
114
114
|
|
|
115
115
|
**规范:**
|
|
116
|
+
|
|
116
117
|
- 每个 Controller 类加 `@Tag(name = "...", description = "...")`
|
|
117
118
|
- 每个接口方法加 `@Operation(summary = "...")`
|
|
118
119
|
- 非 200 响应(400/403/404)加 `@ApiResponse(responseCode = "4XX", description = "...")`
|
|
@@ -10,13 +10,13 @@
|
|
|
10
10
|
|
|
11
11
|
主 changelog 定义了数据库类型变量以支持多数据库(H2 开发/测试,MySQL/PG/MSSQL 生产):
|
|
12
12
|
|
|
13
|
-
| 变量
|
|
14
|
-
|
|
15
|
-
| `${boolean.type}`
|
|
16
|
-
| `${string.type}(255)`
|
|
17
|
-
| `${date.time.type}`
|
|
18
|
-
| `${clob.type}`
|
|
19
|
-
| `${enum.ordinal.type}` | 枚举序号类型
|
|
13
|
+
| 变量 | 用途 |
|
|
14
|
+
| ---------------------- | --------------------------------------- |
|
|
15
|
+
| `${boolean.type}` | 布尔类型 |
|
|
16
|
+
| `${string.type}(255)` | 字符串 VARCHAR/NVARCHAR |
|
|
17
|
+
| `${date.time.type}` | 日期时间 TIMESTAMP/DATETIME/DATETIME2 |
|
|
18
|
+
| `${clob.type}` | 大文本 CLOB/LONGTEXT/TEXT/NVARCHAR(MAX) |
|
|
19
|
+
| `${enum.ordinal.type}` | 枚举序号类型 |
|
|
20
20
|
|
|
21
21
|
枚举类型在不同数据库中处理方式不同:H2/MySQL 用 `ENUM(...)` 原生枚举,PG/MSSQL 用 `${string.type}(255)`。枚举属性命名规则:`${<module>.<enum-name>.type}`。
|
|
22
22
|
|
package/dist/skills/reef-style-backend/fragments/java/dependency-management/quick-reference.md
CHANGED
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
## 速查
|
|
4
4
|
|
|
5
|
-
| 场景
|
|
6
|
-
|
|
|
7
|
-
| 声明依赖
|
|
8
|
-
| 版本声明
|
|
5
|
+
| 场景 | 决策 |
|
|
6
|
+
| ---------- | ---------------------------------------------------------- |
|
|
7
|
+
| 声明依赖 | 全部在 `gradle/libs.versions.toml` 的 `[libraries]` 中声明 |
|
|
8
|
+
| 版本声明 | 全部在 `gradle/libs.versions.toml` 的 `[versions]` 中声明 |
|
|
9
9
|
| 引入新依赖 | 先查 version catalog 是否已有,无则按模块 + 版本号格式添加 |
|
|
10
|
-
| 临时排除
|
|
11
|
-
| 版本升级
|
|
12
|
-
| CVE 检查
|
|
13
|
-
| 许可限制
|
|
10
|
+
| 临时排除 | 在 catalog 中使用 `exclude` 而非 `build.gradle.kts` 中排除 |
|
|
11
|
+
| 版本升级 | 同步升级相关依赖(如 Liquibase + Spring Boot 一起升级) |
|
|
12
|
+
| CVE 检查 | 配合 Dependabot / Renovate + Gradle Versions Plugin |
|
|
13
|
+
| 许可限制 | 禁止引入 AGPL / 需商业许可的依赖 |
|
|
14
14
|
|
|
15
15
|
## 核心规范
|
|
16
16
|
|
|
@@ -39,6 +39,7 @@ spring-boot = { id = "org.springframework.boot", version.ref = "spring-boot" }
|
|
|
39
39
|
```
|
|
40
40
|
|
|
41
41
|
**规范:**
|
|
42
|
+
|
|
42
43
|
- 所有依赖的**版本号**必须声明在 `[versions]` 中,不得在 `[libraries]` 中使用 `version = "1.0.0"` 字面量
|
|
43
44
|
- `[libraries]` 中使用 `version.ref` 引用版本
|
|
44
45
|
- 同一生态的依赖使用同一个版本变量(如所有 Spring Boot starter 共享 `spring-boot` 版本)
|
|
@@ -66,13 +67,13 @@ dependencies {
|
|
|
66
67
|
|
|
67
68
|
升级一个依赖时,检查同一生态链的其他依赖是否需要同步升级:
|
|
68
69
|
|
|
69
|
-
| 升级场景
|
|
70
|
-
|
|
71
|
-
| Spring Boot 升级
|
|
72
|
-
| Liquibase 升级
|
|
73
|
-
| MapStruct 升级
|
|
74
|
-
| Hibernate 升级
|
|
75
|
-
| Testcontainers 升级 | 验证与 JUnit 5 兼容性
|
|
70
|
+
| 升级场景 | 需同步升级的关联依赖 |
|
|
71
|
+
| ------------------- | -------------------------------------------------------- |
|
|
72
|
+
| Spring Boot 升级 | Spring Cloud、spring-dependency-management、相关 starter |
|
|
73
|
+
| Liquibase 升级 | 验证与 Spring Boot 版本兼容性 |
|
|
74
|
+
| MapStruct 升级 | mapstruct-processor 必须保持同一版本 |
|
|
75
|
+
| Hibernate 升级 | Spring Boot 提供的 Hibernate 版本(随 Boot 版本) |
|
|
76
|
+
| Testcontainers 升级 | 验证与 JUnit 5 兼容性 |
|
|
76
77
|
|
|
77
78
|
### Gradle Versions Plugin
|
|
78
79
|
|
|
@@ -93,6 +94,7 @@ plugins {
|
|
|
93
94
|
```
|
|
94
95
|
|
|
95
96
|
**规范:**
|
|
97
|
+
|
|
96
98
|
- 每个 Major 版本升级前先在本地验证兼容性
|
|
97
99
|
- 升级依赖必须作为独立 PR/commit,附 changelog 摘要
|
|
98
100
|
- Minor/Patch 升级可随功能 PR 一起提交
|
|
@@ -105,15 +107,16 @@ plugins {
|
|
|
105
107
|
```
|
|
106
108
|
|
|
107
109
|
**规范:**
|
|
110
|
+
|
|
108
111
|
- Dependabot 或 Renovate 的 CVE PR 在 7 天内处理
|
|
109
112
|
- 紧急 CVE(CVSS >= 7.0):1 天内升级并验证
|
|
110
113
|
- 无法立即升级时,记录在安全看板中,加 `@SuppressWarnings("CVE-XXXX")` 并附缓解说明
|
|
111
114
|
|
|
112
115
|
### 禁止使用的依赖
|
|
113
116
|
|
|
114
|
-
| 依赖
|
|
115
|
-
|
|
116
|
-
| Apache Commons Lang 2 | 有已知 CVE,已被 lang3 取代 | `org.apache.commons:commons-lang3`
|
|
117
|
-
| Log4j 1.x
|
|
118
|
-
| Guava 旧版 < 30.0
|
|
119
|
-
| Joda-Time
|
|
117
|
+
| 依赖 | 禁止原因 | 替代方案 |
|
|
118
|
+
| --------------------- | --------------------------- | ------------------------------------------ |
|
|
119
|
+
| Apache Commons Lang 2 | 有已知 CVE,已被 lang3 取代 | `org.apache.commons:commons-lang3` |
|
|
120
|
+
| Log4j 1.x | EOL,有已知 CVE | Spring Boot 内置 Logback 或 Log4j 2 |
|
|
121
|
+
| Guava 旧版 < 30.0 | 已知 CVE | 最低 32.x |
|
|
122
|
+
| Joda-Time | 已被 java.time 取代 | `java.time.*` / `ThreeTen-Extra`(如需要) |
|
package/dist/skills/reef-style-backend/fragments/java/exception-handling/examples/error-code-enum.md
CHANGED
|
@@ -76,13 +76,13 @@ public enum ErrorCode {
|
|
|
76
76
|
|
|
77
77
|
## 异常 + 错误码对照表
|
|
78
78
|
|
|
79
|
-
| 异常类
|
|
80
|
-
|
|
81
|
-
| `ResourceNotFoundException`
|
|
82
|
-
| `AlreadyExistsException`
|
|
83
|
-
| `InvalidArgumentException`
|
|
84
|
-
| `PermissionDeniedException`
|
|
85
|
-
| `FailedPreconditionException` | 400
|
|
79
|
+
| 异常类 | HTTP | 错误码示例 | 典型场景 |
|
|
80
|
+
| ----------------------------- | ---- | ----------- | -------------- |
|
|
81
|
+
| `ResourceNotFoundException` | 404 | `USER_100` | 用户不存在 |
|
|
82
|
+
| `AlreadyExistsException` | 409 | `USER_001` | 用户名重复 |
|
|
83
|
+
| `InvalidArgumentException` | 400 | `ORDER_001` | 金额无效 |
|
|
84
|
+
| `PermissionDeniedException` | 403 | `AUTH_201` | 无权操作 |
|
|
85
|
+
| `FailedPreconditionException` | 400 | `ORDER_101` | 订单状态不允许 |
|
|
86
86
|
|
|
87
87
|
## 映射逻辑
|
|
88
88
|
|
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
## 速查
|
|
4
4
|
|
|
5
|
-
| 场景
|
|
6
|
-
|
|
|
7
|
-
| 业务异常
|
|
8
|
-
| 全局捕获
|
|
9
|
-
| 错误响应
|
|
10
|
-
| 错误码
|
|
11
|
-
| 参数校验失败 | `MethodArgumentNotValidException` → `InvalidArgumentException` 统一处理
|
|
12
|
-
| 未知异常
|
|
5
|
+
| 场景 | 决策 |
|
|
6
|
+
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
7
|
+
| 业务异常 | 继承 `BusinessException` → 按场景选子类:`ResourceNotFoundException` / `AlreadyExistsException` / `InvalidArgumentException` / `PermissionDeniedException` / `FailedPreconditionException` |
|
|
8
|
+
| 全局捕获 | `@RestControllerAdvice` + `GlobalExceptionHandler` |
|
|
9
|
+
| 错误响应 | `ErrorResponse(code, message, detail)` — AIP-193 兼容 |
|
|
10
|
+
| 错误码 | `{MODULE}_{NNN}` 枚举:`ErrorCode` enum 统一管理 |
|
|
11
|
+
| 参数校验失败 | `MethodArgumentNotValidException` → `InvalidArgumentException` 统一处理 |
|
|
12
|
+
| 未知异常 | 兜底 500 — `GENERIC_001`,记录完整堆栈 |
|
|
13
13
|
|
|
14
14
|
## 核心规范
|
|
15
15
|
|
|
@@ -63,6 +63,7 @@ public class ResourceNotFoundException extends BusinessException {
|
|
|
63
63
|
```
|
|
64
64
|
|
|
65
65
|
**规范:**
|
|
66
|
+
|
|
66
67
|
- 业务异常**必须**继承 `BusinessException`,不得直接抛 `RuntimeException` 或 `ResponseStatusException`
|
|
67
68
|
- 每个构造函数传入 `ErrorCode` 枚举值,而非硬编码字符串
|
|
68
69
|
- 可选的 `detail` map 携带上下文信息(如资源 ID、字段名)用于调试
|
|
@@ -149,6 +150,7 @@ public class GlobalExceptionHandler {
|
|
|
149
150
|
```
|
|
150
151
|
|
|
151
152
|
**规范:**
|
|
153
|
+
|
|
152
154
|
- 不要在每个 Controller 中写 try-catch
|
|
153
155
|
- 不要吞异常后返回 null 或空集合
|
|
154
156
|
- 兜底 handler 必须 `log.error` 记录完整堆栈
|
package/dist/skills/reef-style-backend/fragments/java/framework/spring-boot/examples/dto-mapper.md
CHANGED
|
@@ -105,8 +105,8 @@ public interface DataObjectFieldMapper {
|
|
|
105
105
|
|
|
106
106
|
### 命名约定
|
|
107
107
|
|
|
108
|
-
| 方法名
|
|
109
|
-
|
|
108
|
+
| 方法名 | 用途 |
|
|
109
|
+
| ---------------------- | ------------------ |
|
|
110
110
|
| `mapToSummary(entity)` | 精简 DTO(列表用) |
|
|
111
111
|
| `mapToDetails(entity)` | 完整 DTO(详情用) |
|
|
112
112
|
|
|
@@ -52,12 +52,12 @@ public interface FormRepository extends JpaRepository<Form, Long> {
|
|
|
52
52
|
|
|
53
53
|
## 3. 实体
|
|
54
54
|
|
|
55
|
-
| 场景
|
|
56
|
-
|
|
57
|
-
| 普通多租户,可变
|
|
58
|
-
| 多租户 + 审计字段
|
|
55
|
+
| 场景 | 基类 |
|
|
56
|
+
| --------------------- | --------------------------------------- |
|
|
57
|
+
| 普通多租户,可变 | `AbstractTenantAwareEntity` |
|
|
58
|
+
| 多租户 + 审计字段 | `AbstractTenantAwareAuditable` |
|
|
59
59
|
| 多租户,不可变 + 审计 | `AbstractTenantAwareImmutableAuditable` |
|
|
60
|
-
| 非租户实体(极少)
|
|
60
|
+
| 非租户实体(极少) | `AbstractEntity` 或 `AbstractAuditable` |
|
|
61
61
|
|
|
62
62
|
```java
|
|
63
63
|
@Entity
|