ai-engineering-init 1.5.0 → 1.7.0
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/.claude/agents/code-reviewer.md +3 -130
- package/.claude/hooks/skill-forced-eval.js +2 -0
- package/.claude/hooks/stop.js +24 -1
- package/.claude/skills/codex-code-review/SKILL.md +327 -0
- package/.claude/skills/leniu-report-customization/SKILL.md +82 -2
- package/.claude/skills/leniu-report-standard-customization/SKILL.md +65 -2
- package/.claude/skills/loki-log-query/SKILL.md +400 -0
- package/.claude/skills/mysql-debug/SKILL.md +58 -22
- package/.claude/skills/skill-creator/LICENSE.txt +202 -0
- package/.claude/skills/skill-creator/SKILL.md +479 -0
- package/.claude/skills/skill-creator/agents/analyzer.md +274 -0
- package/.claude/skills/skill-creator/agents/comparator.md +202 -0
- package/.claude/skills/skill-creator/agents/grader.md +223 -0
- package/.claude/skills/skill-creator/assets/eval_review.html +146 -0
- package/.claude/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/.claude/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/.claude/skills/skill-creator/references/schemas.md +430 -0
- package/.claude/skills/skill-creator/scripts/__init__.py +0 -0
- package/.claude/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/.claude/skills/skill-creator/scripts/generate_report.py +326 -0
- package/.claude/skills/skill-creator/scripts/improve_description.py +248 -0
- package/.claude/skills/skill-creator/scripts/package_skill.py +136 -0
- package/.claude/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/.claude/skills/skill-creator/scripts/run_eval.py +310 -0
- package/.claude/skills/skill-creator/scripts/run_loop.py +332 -0
- package/.claude/skills/skill-creator/scripts/utils.py +47 -0
- package/.claude/skills/sync-back-merge/SKILL.md +66 -0
- package/.claude/skills/yunxiao-task-management/SKILL.md +489 -0
- package/.codex/skills/leniu-report-customization/SKILL.md +82 -2
- package/.codex/skills/leniu-report-standard-customization/SKILL.md +65 -2
- package/.codex/skills/loki-log-query/SKILL.md +400 -0
- package/.codex/skills/loki-log-query/environments.json +45 -0
- package/.codex/skills/mysql-debug/SKILL.md +58 -22
- package/.codex/skills/skill-creator/LICENSE.txt +202 -0
- package/.codex/skills/skill-creator/SKILL.md +479 -0
- package/.codex/skills/skill-creator/agents/analyzer.md +274 -0
- package/.codex/skills/skill-creator/agents/comparator.md +202 -0
- package/.codex/skills/skill-creator/agents/grader.md +223 -0
- package/.codex/skills/skill-creator/assets/eval_review.html +146 -0
- package/.codex/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/.codex/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/.codex/skills/skill-creator/references/schemas.md +430 -0
- package/.codex/skills/skill-creator/scripts/__init__.py +0 -0
- package/.codex/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/.codex/skills/skill-creator/scripts/generate_report.py +326 -0
- package/.codex/skills/skill-creator/scripts/improve_description.py +248 -0
- package/.codex/skills/skill-creator/scripts/package_skill.py +136 -0
- package/.codex/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/.codex/skills/skill-creator/scripts/run_eval.py +310 -0
- package/.codex/skills/skill-creator/scripts/run_loop.py +332 -0
- package/.codex/skills/skill-creator/scripts/utils.py +47 -0
- package/.codex/skills/sync-back-merge/SKILL.md +66 -0
- package/.codex/skills/yunxiao-task-management/SKILL.md +489 -0
- package/.cursor/hooks/stop.js +23 -1
- package/.cursor/skills/leniu-report-customization/SKILL.md +82 -2
- package/.cursor/skills/leniu-report-standard-customization/SKILL.md +65 -2
- package/.cursor/skills/loki-log-query/SKILL.md +400 -0
- package/.cursor/skills/loki-log-query/environments.json +45 -0
- package/.cursor/skills/mysql-debug/SKILL.md +58 -22
- package/.cursor/skills/skill-creator/LICENSE.txt +202 -0
- package/.cursor/skills/skill-creator/SKILL.md +479 -0
- package/.cursor/skills/skill-creator/agents/analyzer.md +274 -0
- package/.cursor/skills/skill-creator/agents/comparator.md +202 -0
- package/.cursor/skills/skill-creator/agents/grader.md +223 -0
- package/.cursor/skills/skill-creator/assets/eval_review.html +146 -0
- package/.cursor/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/.cursor/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/.cursor/skills/skill-creator/references/schemas.md +430 -0
- package/.cursor/skills/skill-creator/scripts/__init__.py +0 -0
- package/.cursor/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/.cursor/skills/skill-creator/scripts/generate_report.py +326 -0
- package/.cursor/skills/skill-creator/scripts/improve_description.py +248 -0
- package/.cursor/skills/skill-creator/scripts/package_skill.py +136 -0
- package/.cursor/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/.cursor/skills/skill-creator/scripts/run_eval.py +310 -0
- package/.cursor/skills/skill-creator/scripts/run_loop.py +332 -0
- package/.cursor/skills/skill-creator/scripts/utils.py +47 -0
- package/.cursor/skills/sync-back-merge/SKILL.md +66 -0
- package/.cursor/skills/yunxiao-task-management/SKILL.md +489 -0
- package/README.md +20 -236
- package/bin/index.js +1040 -28
- package/package.json +1 -1
- package/src/platform-map.json +4 -0
- package/src/skills/codex-code-review/SKILL.md +261 -69
- package/src/skills/leniu-report-customization/SKILL.md +82 -2
- package/src/skills/leniu-report-standard-customization/SKILL.md +65 -2
- package/src/skills/loki-log-query/SKILL.md +400 -0
- package/src/skills/loki-log-query/environments.json +45 -0
- package/src/skills/mysql-debug/SKILL.md +58 -22
- package/src/skills/skill-creator/LICENSE.txt +202 -0
- package/src/skills/skill-creator/SKILL.md +479 -0
- package/src/skills/skill-creator/agents/analyzer.md +274 -0
- package/src/skills/skill-creator/agents/comparator.md +202 -0
- package/src/skills/skill-creator/agents/grader.md +223 -0
- package/src/skills/skill-creator/assets/eval_review.html +146 -0
- package/src/skills/skill-creator/eval-viewer/generate_review.py +471 -0
- package/src/skills/skill-creator/eval-viewer/viewer.html +1325 -0
- package/src/skills/skill-creator/references/schemas.md +430 -0
- package/src/skills/skill-creator/scripts/__init__.py +0 -0
- package/src/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
- package/src/skills/skill-creator/scripts/generate_report.py +326 -0
- package/src/skills/skill-creator/scripts/improve_description.py +248 -0
- package/src/skills/skill-creator/scripts/package_skill.py +136 -0
- package/src/skills/skill-creator/scripts/quick_validate.py +103 -0
- package/src/skills/skill-creator/scripts/run_eval.py +310 -0
- package/src/skills/skill-creator/scripts/run_loop.py +332 -0
- package/src/skills/skill-creator/scripts/utils.py +47 -0
- package/src/skills/sync-back-merge/SKILL.md +66 -0
- package/src/skills/yunxiao-task-management/SKILL.md +489 -0
package/package.json
CHANGED
package/src/platform-map.json
CHANGED
|
@@ -1,32 +1,30 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: codex-code-review
|
|
3
3
|
description: |
|
|
4
|
-
|
|
4
|
+
代码审查工作流。分两阶段:先执行本地规范检查(Grep 即时完成)+ 代码逻辑审查(Read 逐文件),再可选调用 Codex CLI 深度审查。
|
|
5
5
|
|
|
6
6
|
触发场景:
|
|
7
7
|
- /dev 或 /crud 命令完成代码生成后
|
|
8
8
|
- Bug 修复完成后
|
|
9
|
-
- 用户说"审查代码"、"review"、"代码审查"、"
|
|
9
|
+
- 用户说"审查代码"、"review"、"代码审查"、"检查代码"
|
|
10
10
|
- 用户说"检查一下刚写的代码"
|
|
11
|
+
- Stop Hook 提示后用户输入"review"
|
|
11
12
|
|
|
12
|
-
|
|
13
|
+
触发词:代码审查、review、审查代码、检查代码、code review、代码质量、codex审查、codex review
|
|
13
14
|
---
|
|
14
15
|
|
|
15
|
-
#
|
|
16
|
+
# 代码审查工作流
|
|
16
17
|
|
|
17
|
-
>
|
|
18
|
-
|
|
19
|
-
## 工作流
|
|
18
|
+
> 两阶段审查:**本地检查**(规范 + 逻辑) + **Codex 深度审查**(可选)。
|
|
20
19
|
|
|
21
|
-
|
|
20
|
+
## Phase 1: 收集变更范围
|
|
22
21
|
|
|
23
22
|
```bash
|
|
24
|
-
# 获取当前未提交的变更文件
|
|
25
23
|
git diff --name-only HEAD
|
|
26
24
|
git diff --cached --name-only
|
|
27
25
|
```
|
|
28
26
|
|
|
29
|
-
|
|
27
|
+
如果没有变更文件,提示"没有检测到代码变更"并终止。
|
|
30
28
|
|
|
31
29
|
将变更文件按类型分组:
|
|
32
30
|
- **Java 文件**:Controller / Business / Service / Mapper / Entity / VO / DTO
|
|
@@ -34,12 +32,216 @@ git diff --cached --name-only
|
|
|
34
32
|
- **SQL 文件**:建表/变更脚本
|
|
35
33
|
- **其他**:配置文件等
|
|
36
34
|
|
|
37
|
-
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## Phase 2: 本地检查(必做)
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
分两步执行:**Step A** 用 Grep 批量扫描规范问题(秒级),**Step B** 用 Read 逐文件审查代码逻辑。
|
|
40
40
|
|
|
41
|
+
### Step A: 项目规范扫描(Grep 批量检查)
|
|
42
|
+
|
|
43
|
+
#### 🔴 A1. 包名规范
|
|
41
44
|
```bash
|
|
42
|
-
|
|
45
|
+
Grep pattern: "package org\.dromara\." path: [目标目录] glob: "*.java"
|
|
46
|
+
```
|
|
47
|
+
- ❌ `package org.dromara.xxx` → ✅ `package net.xnzn.core.xxx`
|
|
48
|
+
|
|
49
|
+
#### 🔴 A2. 禁止 RuoYi 工具类
|
|
50
|
+
```bash
|
|
51
|
+
Grep pattern: "MapstructUtils" path: [目标目录] glob: "*.java"
|
|
52
|
+
Grep pattern: "ServiceException" path: [目标目录] glob: "*.java"
|
|
53
|
+
Grep pattern: "import javax\.validation" path: [目标目录] glob: "*.java"
|
|
54
|
+
```
|
|
55
|
+
- ❌ `MapstructUtils` → ✅ `BeanUtil.copyProperties()`
|
|
56
|
+
- ❌ `ServiceException` → ✅ `LeException`
|
|
57
|
+
- ❌ `javax.validation.*` → ✅ `jakarta.validation.*`(JDK 21)
|
|
58
|
+
|
|
59
|
+
#### 🔴 A3. 审计字段名称
|
|
60
|
+
```bash
|
|
61
|
+
Grep pattern: "private.*createBy|private.*updateBy|private.*createTime|private.*updateTime" path: [目标目录] glob: "*.java"
|
|
62
|
+
```
|
|
63
|
+
- ❌ `createBy/updateBy/createTime/updateTime` → ✅ `crby/upby/crtime/uptime`
|
|
64
|
+
|
|
65
|
+
#### 🔴 A4. del_flag 值语义
|
|
66
|
+
```bash
|
|
67
|
+
Grep pattern: "delFlag.*=.*0|del_flag.*=.*0" path: [目标目录] glob: "*.java"
|
|
68
|
+
```
|
|
69
|
+
- ❌ `delFlag = 0`(RuoYi 正常值) → ✅ `delFlag = 2`(leniu 正常值,1=删除)
|
|
70
|
+
|
|
71
|
+
#### 🔴 A5. Entity 不含 tenant_id
|
|
72
|
+
```bash
|
|
73
|
+
Grep pattern: "tenantId|tenant_id" path: [目标目录] glob: "*.java"
|
|
74
|
+
```
|
|
75
|
+
- ❌ 双库物理隔离,无需 `tenant_id` 字段
|
|
76
|
+
|
|
77
|
+
#### 🔴 A6. 禁止 Map 传递业务数据
|
|
78
|
+
```bash
|
|
79
|
+
Grep pattern: "Map<String,\s*Object>" path: [目标目录] glob: "*.java"
|
|
80
|
+
```
|
|
81
|
+
- ❌ `Map<String, Object>` → ✅ 使用 VO/DTO 类
|
|
82
|
+
|
|
83
|
+
#### 🟡 A7. 事务注解缺少 rollbackFor
|
|
84
|
+
```bash
|
|
85
|
+
Grep pattern: "@Transactional\b" path: [目标目录] glob: "*.java"
|
|
86
|
+
# 对命中文件二次检查:是否缺少 rollbackFor
|
|
87
|
+
Grep pattern: "@Transactional\((?!.*rollbackFor)" path: [命中文件]
|
|
88
|
+
```
|
|
89
|
+
- ❌ `@Transactional` → ✅ `@Transactional(rollbackFor = Exception.class)`
|
|
90
|
+
|
|
91
|
+
#### 🟡 A8. 请求体封装
|
|
92
|
+
```bash
|
|
93
|
+
Grep pattern: "@RequestBody [^L]" path: [目标目录] glob: "*Controller.java"
|
|
94
|
+
```
|
|
95
|
+
- 建议 POST 请求使用 `@RequestBody LeRequest<T>` 封装
|
|
96
|
+
|
|
97
|
+
#### 🟡 A9. 金额类型错误
|
|
98
|
+
```bash
|
|
99
|
+
Grep pattern: "Double|Float|double|float" path: [目标目录] glob: "*.java"
|
|
100
|
+
# 在命中行中检查是否涉及金额字段(amount/price/money/fee/cost)
|
|
101
|
+
```
|
|
102
|
+
- ❌ `Double/Float` 处理金额 → ✅ `Long`(分)或 `BigDecimal`
|
|
103
|
+
|
|
104
|
+
#### 🟡 A10. BigDecimal 比较错误
|
|
105
|
+
```bash
|
|
106
|
+
Grep pattern: "BigDecimal.*==|==.*BigDecimal" path: [目标目录] glob: "*.java"
|
|
107
|
+
```
|
|
108
|
+
- ❌ `bigDecimal1 == bigDecimal2` → ✅ `bigDecimal1.compareTo(bigDecimal2) == 0`
|
|
109
|
+
|
|
110
|
+
#### 🟡 A11. SELECT * 查询
|
|
111
|
+
```bash
|
|
112
|
+
Grep pattern: "SELECT \*|select \*" path: [目标目录] glob: "*.xml"
|
|
113
|
+
```
|
|
114
|
+
- ❌ `SELECT *` → ✅ 明确列出需要的字段
|
|
115
|
+
|
|
116
|
+
#### 🟡 A12. SQL 注入风险
|
|
117
|
+
```bash
|
|
118
|
+
Grep pattern: '\$\{' path: [目标目录] glob: "*.xml"
|
|
119
|
+
```
|
|
120
|
+
- ❌ `${}` 拼接参数 → ✅ `#{}` 参数化查询(ORDER BY 等特殊场景除外)
|
|
121
|
+
|
|
122
|
+
#### 🟡 A13. 国际化异常
|
|
123
|
+
```bash
|
|
124
|
+
Grep pattern: 'new LeException\("[^"]*[\u4e00-\u9fa5]' path: [目标目录] glob: "*.java"
|
|
125
|
+
```
|
|
126
|
+
- 建议使用 `I18n.getMessage()` 替代硬编码中文
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
### Step B: 代码逻辑审查(Read 逐文件检查)
|
|
131
|
+
|
|
132
|
+
对每个变更的 Java 文件执行 Read,按以下清单逐项审查。
|
|
133
|
+
|
|
134
|
+
#### Java 必检项(所有 Java 文件)
|
|
135
|
+
|
|
136
|
+
| # | 检查项 | 检查要点 | 严重级 |
|
|
137
|
+
|---|--------|---------|--------|
|
|
138
|
+
| B1 | **空指针风险** | `selectOne`/`getOne`/`selectById` 返回值是否有 null 判断;Optional 是否正确处理 | 🔴 |
|
|
139
|
+
| B2 | **参数校验** | 入参是否校验非空和合法性(`@NotNull`/`@NotEmpty`/`Objects.requireNonNull`/手动 if 判断) | 🔴 |
|
|
140
|
+
| B3 | **并发安全** | 查询+新增/查询+更新的组合操作是否有竞态条件;是否需要分布式锁 | 🔴 |
|
|
141
|
+
| B4 | **事务边界** | 多表写操作是否加了 `@Transactional(rollbackFor = Exception.class)` | 🔴 |
|
|
142
|
+
| B5 | **资源关闭** | Stream/IO流/数据库连接是否用 try-with-resources 或 finally 关闭 | 🔴 |
|
|
143
|
+
| B6 | **集合并发修改** | `forEach` 内是否有 remove/add 操作;应使用 `Iterator` 或 `removeIf` | 🔴 |
|
|
144
|
+
| B7 | **分页泄漏** | `PageMethod.startPage()` 是否紧贴查询语句,中间不能有其他 SQL 查询 | 🔴 |
|
|
145
|
+
|
|
146
|
+
#### Java 安全项
|
|
147
|
+
|
|
148
|
+
| # | 检查项 | 检查要点 | 严重级 |
|
|
149
|
+
|---|--------|---------|--------|
|
|
150
|
+
| B8 | **租户隔离(仅定时任务)** | 定时任务中是否使用 `Executors.doInTenant()`/`doInAllTenant()` 切换到商户库;普通接口默认在商户库,无需额外处理 | 🔴 |
|
|
151
|
+
| B9 | **SQL 注入** | 动态 SQL 是否使用参数化查询;拼接 SQL 是否转义 | 🔴 |
|
|
152
|
+
| B10 | **越权访问** | 删除/修改操作是否校验数据归属(检查 where 条件是否包含归属字段) | 🔴 |
|
|
153
|
+
| B11 | **敏感信息** | 日志中是否打印了密码、token、身份证、银行卡等敏感信息 | 🔴 |
|
|
154
|
+
| B12 | **批量操作限制** | 批量删除/更新是否限制了最大数量,防止误操作全表 | 🟡 |
|
|
155
|
+
|
|
156
|
+
#### Java 跨模块调用项
|
|
157
|
+
|
|
158
|
+
| # | 检查项 | 检查要点 | 严重级 |
|
|
159
|
+
|---|--------|---------|--------|
|
|
160
|
+
| B13 | **返回值兜底** | 返回 `List`/`Map` 时是否有空集合兜底(`Collections.emptyList()`),避免调用方 NPE | 🟡 |
|
|
161
|
+
| B14 | **集合参数防御** | 集合入参(`List`/`Set`)是否判空,空集合的 `IN()` 会导致 SQL 异常 | 🔴 |
|
|
162
|
+
| B15 | **异常透传** | 是否吞掉异常不抛出(空 catch 块);跨模块调用需要明确的异常传递 | 🔴 |
|
|
163
|
+
| B16 | **日志追踪** | 关键操作或异常分支是否有日志(`log.info`/`log.error`),便于跨模块问题排查 | 🟡 |
|
|
164
|
+
|
|
165
|
+
#### Java 代码规范项
|
|
166
|
+
|
|
167
|
+
| # | 检查项 | 检查要点 | 严重级 |
|
|
168
|
+
|---|--------|---------|--------|
|
|
169
|
+
| B17 | **魔法值** | 是否存在未定义的常量(状态码 1/2/3 必须用枚举,字符串必须定义常量) | 🟡 |
|
|
170
|
+
| B18 | **方法长度** | 方法是否过长(>50 行),需要拆分为子方法 | 🔵 |
|
|
171
|
+
| B19 | **注释完整性** | 公共 API(Controller/Business 方法)是否有 JavaDoc 注释 | 🔵 |
|
|
172
|
+
| B20 | **空 catch 块** | catch 块是否为空或仅打印日志而不处理/不抛出 | 🟡 |
|
|
173
|
+
| B21 | **过时 API** | 是否使用了 `@Deprecated` 的方法或类 | 🔵 |
|
|
174
|
+
| B22 | **返回值一致性** | Controller 层是否统一返回 `LeResponse<T>`,不能裸返回 | 🟡 |
|
|
175
|
+
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
#### MyBatis XML 检查(仅 XML 文件)
|
|
179
|
+
|
|
180
|
+
| # | 检查项 | 检查要点 | 严重级 |
|
|
181
|
+
|---|--------|---------|--------|
|
|
182
|
+
| X1 | **SQL 注入** | 使用 `${}` 而非 `#{}` 进行参数拼接(ORDER BY 等场景需白名单校验) | 🔴 |
|
|
183
|
+
| X2 | **IN 查询防护** | IN 查询是否用 `<foreach>` 且考虑集合为空的情况(空 IN 会 SQL 异常) | 🔴 |
|
|
184
|
+
| X3 | **动态 SQL 语法** | `<if>`/`<where>`/`<choose>` 标签使用是否正确,是否会产生多余的 AND/OR | 🟡 |
|
|
185
|
+
| X4 | **SELECT *** | 是否使用 `SELECT *`,应明确列出需要的字段 | 🟡 |
|
|
186
|
+
| X5 | **缺少 WHERE** | UPDATE/DELETE 是否缺少 WHERE 条件(全表操作风险) | 🔴 |
|
|
187
|
+
| X6 | **索引失效** | WHERE 条件是否对索引字段使用了函数(`DATE(crtime)`)或隐式类型转换 | 🟡 |
|
|
188
|
+
| X7 | **LIKE 前模糊** | `LIKE '%xxx%'` 或 `LIKE CONCAT('%', #{}, '%')` 前模糊导致全表扫描 | 🟡 |
|
|
189
|
+
| X8 | **大表无分页** | 大表查询是否遗漏分页,可能造成 OOM | 🟡 |
|
|
190
|
+
| X9 | **namespace 匹配** | namespace 是否与 Mapper 接口全限定名完全匹配 | 🔴 |
|
|
191
|
+
| X10 | **resultMap 映射** | 是否正确定义 resultMap,字段名和属性名是否对应 | 🟡 |
|
|
192
|
+
|
|
193
|
+
---
|
|
194
|
+
|
|
195
|
+
### 本地检查结果展示
|
|
196
|
+
|
|
197
|
+
```
|
|
198
|
+
# 代码审查报告
|
|
199
|
+
|
|
200
|
+
审查范围: [变更文件列表]
|
|
201
|
+
|
|
202
|
+
## 🔴 严重问题(X 项)
|
|
203
|
+
1. [B1 空指针风险]
|
|
204
|
+
文件: OrderServiceImpl.java:42
|
|
205
|
+
问题: selectById 返回值未做 null 判断
|
|
206
|
+
修复: if (ObjectUtil.isNull(entity)) throw new LeException("数据不存在");
|
|
207
|
+
|
|
208
|
+
2. [A2 禁止 RuoYi 工具类]
|
|
209
|
+
文件: UserServiceImpl.java:15
|
|
210
|
+
问题: 使用了 MapstructUtils
|
|
211
|
+
修复: 替换为 BeanUtil.copyProperties()
|
|
212
|
+
|
|
213
|
+
## 🟡 警告问题(X 项)
|
|
214
|
+
...
|
|
215
|
+
|
|
216
|
+
## 🔵 建议(X 项)
|
|
217
|
+
...
|
|
218
|
+
|
|
219
|
+
## ✅ 通过项
|
|
220
|
+
- [x] A1 包名规范 (net.xnzn.core.*)
|
|
221
|
+
- [x] A3 审计字段正确 (crby/crtime/upby/uptime)
|
|
222
|
+
- [x] A4 del_flag 语义正确 (2=正常)
|
|
223
|
+
- [x] B8 租户隔离正确
|
|
224
|
+
...
|
|
225
|
+
|
|
226
|
+
结论: ✅ 通过 / ⚠️ 需修复 X 项 / ❌ 不通过
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
如果全部通过 → 展示"本地检查通过",询问是否需要 Codex 深度审查。
|
|
230
|
+
如果有问题 → 先修复严重问题,修复后再询问是否需要 Codex 深度审查。
|
|
231
|
+
|
|
232
|
+
---
|
|
233
|
+
|
|
234
|
+
## Phase 3: Codex 深度审查(可选)
|
|
235
|
+
|
|
236
|
+
> 依赖 `collaborating-with-codex` skill 的 `codex_bridge.py` 脚本。
|
|
237
|
+
> Codex 擅长发现本地规则难以覆盖的**逻辑 Bug、复杂并发问题、架构缺陷**。
|
|
238
|
+
|
|
239
|
+
Phase 2 完成后询问用户:"是否需要 Codex 深度审查?"
|
|
240
|
+
- 用户同意 → 执行以下流程
|
|
241
|
+
- 用户拒绝 → 跳到 Phase 5
|
|
242
|
+
|
|
243
|
+
```bash
|
|
244
|
+
python3 .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
43
245
|
--cd . \
|
|
44
246
|
--sandbox read-only \
|
|
45
247
|
--PROMPT "Review the following changed files for code quality issues:
|
|
@@ -47,25 +249,34 @@ python .claude/skills/collaborating-with-codex/scripts/codex_bridge.py \
|
|
|
47
249
|
FILES TO REVIEW:
|
|
48
250
|
{变更文件列表,含相对路径}
|
|
49
251
|
|
|
50
|
-
REVIEW
|
|
51
|
-
1.
|
|
52
|
-
2. Security:
|
|
53
|
-
3. Architecture:
|
|
54
|
-
4.
|
|
55
|
-
5.
|
|
252
|
+
REVIEW FOCUS (beyond basic lint):
|
|
253
|
+
1. Logic bugs: race conditions, off-by-one, incorrect state transitions, edge cases
|
|
254
|
+
2. Security: privilege escalation, data leakage across tenants, missing auth checks
|
|
255
|
+
3. Architecture: Controller calling Mapper directly, Business layer bypassed, circular dependencies
|
|
256
|
+
4. Performance: N+1 queries, missing pagination on large tables, unnecessary DB calls in loops
|
|
257
|
+
5. Concurrency: check-then-act without locking, shared mutable state, CompletableFuture error handling
|
|
258
|
+
|
|
259
|
+
PROJECT CONTEXT:
|
|
260
|
+
- Package: net.xnzn.core.* (NOT org.dromara.*)
|
|
261
|
+
- 4-layer: Controller → Business → Service → Mapper
|
|
262
|
+
- Dual-database: tenant DB is default (by MERCHANT-ID header); only scheduled tasks need Executors.doInTenant()/doInAllTenant() to switch; Executors.doInSystem() for system DB access
|
|
263
|
+
- Audit fields: crby/crtime/upby/uptime
|
|
264
|
+
- del_flag: 1=deleted, 2=normal
|
|
265
|
+
- Exception: LeException (NOT ServiceException)
|
|
266
|
+
- Object copy: BeanUtil.copyProperties() (NOT MapstructUtils)
|
|
267
|
+
- Amount: stored as Long (fen/cents), NOT Double/Float
|
|
268
|
+
- Pagination: PageMethod.startPage() must be immediately before query
|
|
56
269
|
|
|
57
270
|
OUTPUT FORMAT:
|
|
58
|
-
For each issue
|
|
271
|
+
For each issue:
|
|
59
272
|
- [SEVERITY] CRITICAL / WARNING / SUGGESTION
|
|
60
273
|
- [FILE] filepath:line_number
|
|
61
|
-
- [ISSUE]
|
|
274
|
+
- [ISSUE] Description
|
|
62
275
|
- [FIX] Recommended fix
|
|
63
276
|
|
|
64
|
-
If no issues
|
|
277
|
+
If no issues: ALL CLEAR
|
|
65
278
|
|
|
66
|
-
IMPORTANT
|
|
67
|
-
- All review comments MUST be in Chinese
|
|
68
|
-
- File paths and code snippets remain in English"
|
|
279
|
+
IMPORTANT: All comments in Chinese, code/paths in English."
|
|
69
280
|
```
|
|
70
281
|
|
|
71
282
|
**关键约束**:
|
|
@@ -73,63 +284,44 @@ IMPORTANT LANGUAGE RULES:
|
|
|
73
284
|
- 变更文件过多时(>10 个),按模块分批审查
|
|
74
285
|
- 使用 `run_in_background` 避免阻塞
|
|
75
286
|
|
|
76
|
-
### Phase 3: 展示审查结果
|
|
77
|
-
|
|
78
|
-
解析 Codex 返回的 JSON,提取 `agent_messages`,按严重程度分组展示:
|
|
79
|
-
|
|
80
|
-
```
|
|
81
|
-
## Codex 审查结果
|
|
82
|
-
|
|
83
|
-
### 🔴 严重问题 (CRITICAL)
|
|
84
|
-
- `OrderInfoService.java:42` — 未做空值检查,可能 NPE
|
|
85
|
-
建议:添加 ObjectUtil.isNull() 判断
|
|
86
|
-
|
|
87
|
-
### 🟡 警告 (WARNING)
|
|
88
|
-
- `OrderWebController.java:15` — 缺少 @RequiresAuthentication 注解
|
|
89
|
-
建议:添加认证注解
|
|
90
|
-
|
|
91
|
-
### 🔵 建议 (SUGGESTION)
|
|
92
|
-
- `OrderDTO.java:8` — 字段命名可优化
|
|
93
|
-
建议:使用更具描述性的名称
|
|
94
|
-
|
|
95
287
|
---
|
|
96
|
-
是否需要修复以上问题?
|
|
97
|
-
```
|
|
98
|
-
|
|
99
|
-
如果结果为 `ALL CLEAR`,展示"审查通过,未发现问题"并终止。
|
|
100
288
|
|
|
101
|
-
|
|
289
|
+
## Phase 4: 用户确认后修复
|
|
102
290
|
|
|
103
|
-
|
|
104
|
-
- **全部修复**:"修复所有问题" → 逐个修复所有
|
|
105
|
-
- **选择性修复**:"只修复严重问题" → 仅修复
|
|
291
|
+
合并 Phase 2 和 Phase 3 的所有问题,等待用户确认:
|
|
292
|
+
- **全部修复**:"修复所有问题" → 逐个修复所有 🔴 + 🟡
|
|
293
|
+
- **选择性修复**:"只修复严重问题" → 仅修复 🔴
|
|
106
294
|
- **跳过**:"不需要修复" → 终止
|
|
107
295
|
|
|
108
296
|
修复时:
|
|
109
297
|
1. 按文件逐个修复,使用 Edit 工具
|
|
110
298
|
2. 每修复一个文件,简要说明改动
|
|
111
|
-
3.
|
|
299
|
+
3. 🔵 建议级别默认跳过,除非用户明确要求
|
|
112
300
|
4. 修复完成后运行 `git diff` 展示所有变更
|
|
113
301
|
|
|
114
|
-
|
|
302
|
+
---
|
|
303
|
+
|
|
304
|
+
## Phase 5: 最终确认
|
|
115
305
|
|
|
116
306
|
修复完成后询问:"是否需要再次审查确认?"
|
|
117
307
|
- 如果用户同意 → 回到 Phase 2 重新审查
|
|
118
|
-
- 如果用户拒绝 →
|
|
119
|
-
|
|
120
|
-
## 审查重点(leniu 项目特有)
|
|
121
|
-
|
|
122
|
-
Codex PROMPT 中追加项目特有检查项:
|
|
308
|
+
- 如果用户拒绝 → 输出最终结论并终止
|
|
123
309
|
|
|
124
310
|
```
|
|
125
|
-
|
|
126
|
-
- Package must be net.xnzn.core.* (NOT org.dromara.*)
|
|
127
|
-
- Audit fields: crby/crtime/upby/uptime (NOT createBy/createTime)
|
|
128
|
-
- del_flag: 1=deleted, 2=normal (NOT 0=normal)
|
|
129
|
-
- Use LeException (NOT ServiceException)
|
|
130
|
-
- Use BeanUtil.copyProperties() (NOT MapstructUtils)
|
|
131
|
-
- Use jakarta.validation.* (NOT javax.validation.*)
|
|
132
|
-
- No tenant_id field in Entity (dual-database physical isolation)
|
|
133
|
-
- Architecture: Controller → Business → Service → Mapper (4-layer)
|
|
134
|
-
- No Map for business data transfer (use VO/DTO)
|
|
311
|
+
结论: ✅ 通过 / ⚠️ 需修复 / ❌ 不通过
|
|
135
312
|
```
|
|
313
|
+
|
|
314
|
+
---
|
|
315
|
+
|
|
316
|
+
## 前端审查(如涉及前端文件变更)
|
|
317
|
+
|
|
318
|
+
前端项目路径:`/Users/xujiajun/Developer/frontProj/web`
|
|
319
|
+
|
|
320
|
+
| # | 检查项 | 检查要点 |
|
|
321
|
+
|---|--------|---------|
|
|
322
|
+
| F1 | 响应码 | 成功码是 `10000`(不是 200) |
|
|
323
|
+
| F2 | Token | `Admin-Token`(localStorage) |
|
|
324
|
+
| F3 | 租户头 | `MERCHANT-ID`(请求头) |
|
|
325
|
+
| F4 | 金额显示 | 后端返回分,前端用 `money()` 转元 |
|
|
326
|
+
| F5 | 权限指令 | 按钮权限使用 `v-hasPerm` |
|
|
327
|
+
| F6 | 加密 | 敏感字段使用 SM4 加密 |
|
|
@@ -291,7 +291,83 @@ GROUP BY d.wallet_id
|
|
|
291
291
|
|
|
292
292
|
---
|
|
293
293
|
|
|
294
|
-
##
|
|
294
|
+
## 九、MySQL only_full_group_by 规范(必须遵守)
|
|
295
|
+
|
|
296
|
+
> 生产环境 MySQL 开启了 `sql_mode=only_full_group_by`,所有报表 SQL 必须满足此规则,否则报 `BadSqlGrammarException`。
|
|
297
|
+
|
|
298
|
+
### 核心规则
|
|
299
|
+
|
|
300
|
+
**SELECT 中所有非聚合字段,必须出现在 GROUP BY 中,且表达式必须完全一致。**
|
|
301
|
+
|
|
302
|
+
### 常见错误:GROUP BY 表达式与 SELECT 不一致
|
|
303
|
+
|
|
304
|
+
```sql
|
|
305
|
+
-- ❌ 错误:SELECT 用 DATE_FORMAT,GROUP BY 用 DATE
|
|
306
|
+
SELECT
|
|
307
|
+
DATE_FORMAT(atr.trade_time, '%Y-%m-%d') AS statisticDate,
|
|
308
|
+
SUM(atr.amount) AS totalAmount
|
|
309
|
+
FROM acc_trade atr
|
|
310
|
+
GROUP BY DATE(atr.trade_time) -- ❌ 表达式不同,触发 only_full_group_by 报错
|
|
311
|
+
ORDER BY DATE(atr.trade_time) ASC
|
|
312
|
+
|
|
313
|
+
-- ✅ 正确:GROUP BY 与 SELECT 使用完全相同的表达式
|
|
314
|
+
SELECT
|
|
315
|
+
DATE_FORMAT(atr.trade_time, '%Y-%m-%d') AS statisticDate,
|
|
316
|
+
SUM(atr.amount) AS totalAmount
|
|
317
|
+
FROM acc_trade atr
|
|
318
|
+
GROUP BY DATE_FORMAT(atr.trade_time, '%Y-%m-%d') -- ✅ 与 SELECT 一致
|
|
319
|
+
ORDER BY DATE_FORMAT(atr.trade_time, '%Y-%m-%d') ASC
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
### 常见错误:SELECT 包含非聚合字段未加入 GROUP BY
|
|
323
|
+
|
|
324
|
+
```sql
|
|
325
|
+
-- ❌ 错误:canteen_name 未在 GROUP BY 中
|
|
326
|
+
SELECT
|
|
327
|
+
DATE(pay_time) AS orderDate,
|
|
328
|
+
canteen_name, -- ❌ 非聚合字段,未在 GROUP BY
|
|
329
|
+
SUM(real_amount) AS netAmount
|
|
330
|
+
FROM report_order_info
|
|
331
|
+
GROUP BY DATE(pay_time), canteen_id
|
|
332
|
+
|
|
333
|
+
-- ✅ 正确:所有非聚合字段都加入 GROUP BY
|
|
334
|
+
SELECT
|
|
335
|
+
DATE(pay_time) AS orderDate,
|
|
336
|
+
canteen_name,
|
|
337
|
+
SUM(real_amount) AS netAmount
|
|
338
|
+
FROM report_order_info
|
|
339
|
+
GROUP BY DATE(pay_time), canteen_id, canteen_name -- ✅ 包含 canteen_name
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### fix SQL 中的正确写法
|
|
343
|
+
|
|
344
|
+
```xml
|
|
345
|
+
<insert id="initFix">
|
|
346
|
+
INSERT INTO report_sum_xxx (id, statistic_date, canteen_id, canteen_name,
|
|
347
|
+
order_count, consume_amount, net_amount)
|
|
348
|
+
SELECT
|
|
349
|
+
#{id},
|
|
350
|
+
DATE(pay_time), -- SELECT 用 DATE(pay_time)
|
|
351
|
+
canteen_id,
|
|
352
|
+
canteen_name,
|
|
353
|
+
COUNT(*),
|
|
354
|
+
SUM(CASE WHEN consume_type = 1 THEN real_amount ELSE 0 END),
|
|
355
|
+
SUM(real_amount)
|
|
356
|
+
FROM report_order_info
|
|
357
|
+
WHERE pay_time BETWEEN #{startTime} AND #{endTime}
|
|
358
|
+
GROUP BY DATE(pay_time), canteen_id, canteen_name -- ✅ 与 SELECT 完全一致
|
|
359
|
+
</insert>
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
### 开发检查项
|
|
363
|
+
|
|
364
|
+
- [ ] SELECT 每个非聚合字段,在 GROUP BY 中都有对应
|
|
365
|
+
- [ ] GROUP BY 的表达式与 SELECT 中的**完全一致**(`DATE_FORMAT(x, 'Y-m-d')` ≠ `DATE(x)`)
|
|
366
|
+
- [ ] ORDER BY 也使用相同表达式(保持一致)
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## 十、开发检查清单
|
|
295
371
|
|
|
296
372
|
### 建表
|
|
297
373
|
- [ ] 分组维度字段 + 金额汇总字段 + 审计字段(crby/crtime/upby/uptime/del_flag),无 tenant_id
|
|
@@ -308,9 +384,13 @@ GROUP BY d.wallet_id
|
|
|
308
384
|
### 查询接口
|
|
309
385
|
- [ ] 分页 + 合计行(PageVO + TotalVO)+ 三并行 CompletableFuture
|
|
310
386
|
|
|
387
|
+
### SQL 合规(only_full_group_by)
|
|
388
|
+
- [ ] SELECT 非聚合字段全部在 GROUP BY 中
|
|
389
|
+
- [ ] GROUP BY 表达式与 SELECT 完全一致
|
|
390
|
+
|
|
311
391
|
---
|
|
312
392
|
|
|
313
|
-
##
|
|
393
|
+
## 十一、关键代码位置
|
|
314
394
|
|
|
315
395
|
| 类型 | 路径 |
|
|
316
396
|
|------|------|
|
|
@@ -286,7 +286,69 @@ public ReportBaseTotalVO<XxxVO> pageSummary(XxxParam param) {
|
|
|
286
286
|
|
|
287
287
|
---
|
|
288
288
|
|
|
289
|
-
##
|
|
289
|
+
## 九、MySQL only_full_group_by 规范(必须遵守)
|
|
290
|
+
|
|
291
|
+
> MySQL 默认开启 `sql_mode=ONLY_FULL_GROUP_BY`,SELECT 中所有非聚合列必须出现在 GROUP BY 中,且 GROUP BY 表达式必须与 SELECT 表达式**完全一致**。
|
|
292
|
+
|
|
293
|
+
### 核心规则
|
|
294
|
+
|
|
295
|
+
**SELECT 的表达式 == GROUP BY 的表达式**(字符级别完全一致)
|
|
296
|
+
|
|
297
|
+
### ❌ 错误示例(GROUP BY 与 SELECT 不一致)
|
|
298
|
+
|
|
299
|
+
```xml
|
|
300
|
+
<!-- 报错:Expression #1 of SELECT list is not in GROUP BY clause -->
|
|
301
|
+
SELECT
|
|
302
|
+
DATE_FORMAT(roi.consume_time, '%Y-%m-%d') AS statisticDate,
|
|
303
|
+
SUM(roi.real_amount) AS totalAmount
|
|
304
|
+
FROM report_order_info roi
|
|
305
|
+
GROUP BY DATE(roi.consume_time) <!-- ❌ DATE() ≠ DATE_FORMAT(..., '%Y-%m-%d') -->
|
|
306
|
+
ORDER BY DATE(roi.consume_time)
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### ✅ 正确示例(GROUP BY 与 SELECT 完全一致)
|
|
310
|
+
|
|
311
|
+
```xml
|
|
312
|
+
SELECT
|
|
313
|
+
DATE_FORMAT(roi.consume_time, '%Y-%m-%d') AS statisticDate,
|
|
314
|
+
SUM(roi.real_amount) AS totalAmount
|
|
315
|
+
FROM report_order_info roi
|
|
316
|
+
GROUP BY DATE_FORMAT(roi.consume_time, '%Y-%m-%d') <!-- ✅ 与 SELECT 完全一致 -->
|
|
317
|
+
ORDER BY DATE_FORMAT(roi.consume_time, '%Y-%m-%d') <!-- ✅ ORDER BY 也保持一致 -->
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
### ❌ 错误示例(SELECT 含非聚合列未加入 GROUP BY)
|
|
321
|
+
|
|
322
|
+
```xml
|
|
323
|
+
SELECT
|
|
324
|
+
roi.canteen_id,
|
|
325
|
+
roi.canteen_name, <!-- ❌ 非聚合列未在 GROUP BY 中 -->
|
|
326
|
+
SUM(roi.real_amount) AS totalAmount
|
|
327
|
+
FROM report_order_info roi
|
|
328
|
+
GROUP BY roi.canteen_id
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### ✅ 正确示例(所有非聚合列都在 GROUP BY 中)
|
|
332
|
+
|
|
333
|
+
```xml
|
|
334
|
+
SELECT
|
|
335
|
+
roi.canteen_id,
|
|
336
|
+
roi.canteen_name,
|
|
337
|
+
SUM(roi.real_amount) AS totalAmount
|
|
338
|
+
FROM report_order_info roi
|
|
339
|
+
GROUP BY roi.canteen_id, roi.canteen_name <!-- ✅ 所有非聚合列都在 GROUP BY -->
|
|
340
|
+
```
|
|
341
|
+
|
|
342
|
+
### 检查清单
|
|
343
|
+
|
|
344
|
+
- [ ] SELECT 中按日期分组时使用 `DATE_FORMAT(col, '%Y-%m-%d')`,**不要用 `DATE()`**
|
|
345
|
+
- [ ] GROUP BY 表达式与 SELECT 中对应列**逐字相同**(复制粘贴而非重写)
|
|
346
|
+
- [ ] ORDER BY 中同样使用与 GROUP BY 一致的表达式
|
|
347
|
+
- [ ] SELECT 中所有非聚合列(无 SUM/COUNT/AVG/MAX/MIN 包裹)都出现在 GROUP BY 中
|
|
348
|
+
|
|
349
|
+
---
|
|
350
|
+
|
|
351
|
+
## 十、开发检查清单
|
|
290
352
|
|
|
291
353
|
### 建表
|
|
292
354
|
- [ ] 分组维度 + 金额汇总 + 审计字段(crby/crtime/upby/uptime/del_flag),无 tenant_id
|
|
@@ -302,10 +364,11 @@ public ReportBaseTotalVO<XxxVO> pageSummary(XxxParam param) {
|
|
|
302
364
|
|
|
303
365
|
### 查询
|
|
304
366
|
- [ ] ReportBaseTotalVO + CompletableFuture 并行 + MgrUserAuthPO 权限
|
|
367
|
+
- [ ] GROUP BY / ORDER BY 表达式与 SELECT 完全一致(only_full_group_by)
|
|
305
368
|
|
|
306
369
|
---
|
|
307
370
|
|
|
308
|
-
##
|
|
371
|
+
## 十一、关键代码位置
|
|
309
372
|
|
|
310
373
|
> 路径前缀均为 `core-report/.../statistics/`
|
|
311
374
|
|