ai-engineering-init 1.6.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.
Files changed (108) hide show
  1. package/.claude/agents/code-reviewer.md +3 -130
  2. package/.claude/hooks/skill-forced-eval.js +2 -0
  3. package/.claude/hooks/stop.js +24 -1
  4. package/.claude/skills/codex-code-review/SKILL.md +327 -0
  5. package/.claude/skills/leniu-report-customization/SKILL.md +82 -2
  6. package/.claude/skills/leniu-report-standard-customization/SKILL.md +65 -2
  7. package/.claude/skills/loki-log-query/SKILL.md +400 -0
  8. package/.claude/skills/mysql-debug/SKILL.md +58 -22
  9. package/.claude/skills/skill-creator/LICENSE.txt +202 -0
  10. package/.claude/skills/skill-creator/SKILL.md +479 -0
  11. package/.claude/skills/skill-creator/agents/analyzer.md +274 -0
  12. package/.claude/skills/skill-creator/agents/comparator.md +202 -0
  13. package/.claude/skills/skill-creator/agents/grader.md +223 -0
  14. package/.claude/skills/skill-creator/assets/eval_review.html +146 -0
  15. package/.claude/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  16. package/.claude/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  17. package/.claude/skills/skill-creator/references/schemas.md +430 -0
  18. package/.claude/skills/skill-creator/scripts/__init__.py +0 -0
  19. package/.claude/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  20. package/.claude/skills/skill-creator/scripts/generate_report.py +326 -0
  21. package/.claude/skills/skill-creator/scripts/improve_description.py +248 -0
  22. package/.claude/skills/skill-creator/scripts/package_skill.py +136 -0
  23. package/.claude/skills/skill-creator/scripts/quick_validate.py +103 -0
  24. package/.claude/skills/skill-creator/scripts/run_eval.py +310 -0
  25. package/.claude/skills/skill-creator/scripts/run_loop.py +332 -0
  26. package/.claude/skills/skill-creator/scripts/utils.py +47 -0
  27. package/.claude/skills/sync-back-merge/SKILL.md +66 -0
  28. package/.claude/skills/yunxiao-task-management/SKILL.md +489 -0
  29. package/.codex/skills/leniu-report-customization/SKILL.md +82 -2
  30. package/.codex/skills/leniu-report-standard-customization/SKILL.md +65 -2
  31. package/.codex/skills/loki-log-query/SKILL.md +400 -0
  32. package/.codex/skills/loki-log-query/environments.json +45 -0
  33. package/.codex/skills/mysql-debug/SKILL.md +58 -22
  34. package/.codex/skills/skill-creator/LICENSE.txt +202 -0
  35. package/.codex/skills/skill-creator/SKILL.md +479 -0
  36. package/.codex/skills/skill-creator/agents/analyzer.md +274 -0
  37. package/.codex/skills/skill-creator/agents/comparator.md +202 -0
  38. package/.codex/skills/skill-creator/agents/grader.md +223 -0
  39. package/.codex/skills/skill-creator/assets/eval_review.html +146 -0
  40. package/.codex/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  41. package/.codex/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  42. package/.codex/skills/skill-creator/references/schemas.md +430 -0
  43. package/.codex/skills/skill-creator/scripts/__init__.py +0 -0
  44. package/.codex/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  45. package/.codex/skills/skill-creator/scripts/generate_report.py +326 -0
  46. package/.codex/skills/skill-creator/scripts/improve_description.py +248 -0
  47. package/.codex/skills/skill-creator/scripts/package_skill.py +136 -0
  48. package/.codex/skills/skill-creator/scripts/quick_validate.py +103 -0
  49. package/.codex/skills/skill-creator/scripts/run_eval.py +310 -0
  50. package/.codex/skills/skill-creator/scripts/run_loop.py +332 -0
  51. package/.codex/skills/skill-creator/scripts/utils.py +47 -0
  52. package/.codex/skills/sync-back-merge/SKILL.md +66 -0
  53. package/.codex/skills/yunxiao-task-management/SKILL.md +489 -0
  54. package/.cursor/hooks/stop.js +23 -1
  55. package/.cursor/skills/leniu-report-customization/SKILL.md +82 -2
  56. package/.cursor/skills/leniu-report-standard-customization/SKILL.md +65 -2
  57. package/.cursor/skills/loki-log-query/SKILL.md +400 -0
  58. package/.cursor/skills/loki-log-query/environments.json +45 -0
  59. package/.cursor/skills/mysql-debug/SKILL.md +58 -22
  60. package/.cursor/skills/skill-creator/LICENSE.txt +202 -0
  61. package/.cursor/skills/skill-creator/SKILL.md +479 -0
  62. package/.cursor/skills/skill-creator/agents/analyzer.md +274 -0
  63. package/.cursor/skills/skill-creator/agents/comparator.md +202 -0
  64. package/.cursor/skills/skill-creator/agents/grader.md +223 -0
  65. package/.cursor/skills/skill-creator/assets/eval_review.html +146 -0
  66. package/.cursor/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  67. package/.cursor/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  68. package/.cursor/skills/skill-creator/references/schemas.md +430 -0
  69. package/.cursor/skills/skill-creator/scripts/__init__.py +0 -0
  70. package/.cursor/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  71. package/.cursor/skills/skill-creator/scripts/generate_report.py +326 -0
  72. package/.cursor/skills/skill-creator/scripts/improve_description.py +248 -0
  73. package/.cursor/skills/skill-creator/scripts/package_skill.py +136 -0
  74. package/.cursor/skills/skill-creator/scripts/quick_validate.py +103 -0
  75. package/.cursor/skills/skill-creator/scripts/run_eval.py +310 -0
  76. package/.cursor/skills/skill-creator/scripts/run_loop.py +332 -0
  77. package/.cursor/skills/skill-creator/scripts/utils.py +47 -0
  78. package/.cursor/skills/sync-back-merge/SKILL.md +66 -0
  79. package/.cursor/skills/yunxiao-task-management/SKILL.md +489 -0
  80. package/bin/index.js +606 -24
  81. package/package.json +1 -1
  82. package/src/platform-map.json +4 -0
  83. package/src/skills/codex-code-review/SKILL.md +261 -69
  84. package/src/skills/leniu-report-customization/SKILL.md +82 -2
  85. package/src/skills/leniu-report-standard-customization/SKILL.md +65 -2
  86. package/src/skills/loki-log-query/SKILL.md +400 -0
  87. package/src/skills/loki-log-query/environments.json +45 -0
  88. package/src/skills/mysql-debug/SKILL.md +58 -22
  89. package/src/skills/skill-creator/LICENSE.txt +202 -0
  90. package/src/skills/skill-creator/SKILL.md +479 -0
  91. package/src/skills/skill-creator/agents/analyzer.md +274 -0
  92. package/src/skills/skill-creator/agents/comparator.md +202 -0
  93. package/src/skills/skill-creator/agents/grader.md +223 -0
  94. package/src/skills/skill-creator/assets/eval_review.html +146 -0
  95. package/src/skills/skill-creator/eval-viewer/generate_review.py +471 -0
  96. package/src/skills/skill-creator/eval-viewer/viewer.html +1325 -0
  97. package/src/skills/skill-creator/references/schemas.md +430 -0
  98. package/src/skills/skill-creator/scripts/__init__.py +0 -0
  99. package/src/skills/skill-creator/scripts/aggregate_benchmark.py +401 -0
  100. package/src/skills/skill-creator/scripts/generate_report.py +326 -0
  101. package/src/skills/skill-creator/scripts/improve_description.py +248 -0
  102. package/src/skills/skill-creator/scripts/package_skill.py +136 -0
  103. package/src/skills/skill-creator/scripts/quick_validate.py +103 -0
  104. package/src/skills/skill-creator/scripts/run_eval.py +310 -0
  105. package/src/skills/skill-creator/scripts/run_loop.py +332 -0
  106. package/src/skills/skill-creator/scripts/utils.py +47 -0
  107. package/src/skills/sync-back-merge/SKILL.md +66 -0
  108. package/src/skills/yunxiao-task-management/SKILL.md +489 -0
@@ -5,135 +5,8 @@ model: sonnet
5
5
  tools: Read, Grep, Glob
6
6
  ---
7
7
 
8
- 你是 leniu-tengyun-core(云食堂)的代码审查助手,负责在代码生成或修改后自动检查是否符合项目规范。
8
+ 你是 leniu-tengyun-core(云食堂)的代码审查助手。
9
9
 
10
- **核心架构**:四层架构(Controller → Business → Service → Mapper),包名 `net.xnzn.core.*`,JDK 21,双库物理隔离(无 tenant_id 字段)。
11
-
12
- ---
13
-
14
- ## 触发场景
15
-
16
- 1. `/dev` 或 `/crud` 命令完成后
17
- 2. 用户说"审查代码"、"检查代码"、"review"
18
-
19
- ---
20
-
21
- ## 后端审查清单
22
-
23
- ### 🔴 严重问题(必须修复)
24
-
25
- #### 1. 包名规范
26
- ```bash
27
- Grep pattern: "package org\.dromara\." path: [目标目录] # ❌ 必须为 0 个
28
- Grep pattern: "package net\.xnzn\." path: [目标目录] # ✅ 应有结果
29
- ```
30
- - ❌ `package org.dromara.xxx`
31
- - ✅ `package net.xnzn.core.xxx`
32
-
33
- #### 2. 禁止使用 RuoYi 工具类
34
- ```bash
35
- Grep pattern: "MapstructUtils" path: [目标目录] glob: "*.java"
36
- Grep pattern: "ServiceException" path: [目标目录] glob: "*.java"
37
- Grep pattern: "import javax\.validation" path: [目标目录] glob: "*.java"
38
- ```
39
- - ❌ `MapstructUtils.convert()` → ✅ `BeanUtil.copyProperties()`
40
- - ❌ `throw new ServiceException()` → ✅ `throw new LeException()`
41
- - ❌ `javax.validation.*` → ✅ `jakarta.validation.*`(JDK 21)
42
-
43
- #### 3. 审计字段名称
44
- ```bash
45
- Grep pattern: "private.*createBy\|private.*updateBy\|private.*createTime\|private.*updateTime" path: [目标目录] glob: "*.java"
46
- ```
47
- - ❌ `createBy / updateBy / createTime / updateTime`
48
- - ✅ `crby / upby / crtime / uptime`
49
-
50
- #### 4. del_flag 值语义
51
- ```bash
52
- Grep pattern: "delFlag.*=.*0\|del_flag.*=.*0" path: [目标目录] glob: "*.java"
53
- ```
54
- - ❌ `delFlag = 0`(RuoYi 的正常值)
55
- - ✅ `delFlag = 2`(leniu 的正常值,1=删除)
56
-
57
- #### 5. Entity 不含 tenant_id
58
- ```bash
59
- Grep pattern: "tenantId\|tenant_id" path: [目标目录] glob: "*.java"
60
- ```
61
- - ❌ Entity 中有 `tenantId` 字段(双库物理隔离,无需此字段)
62
-
63
- #### 6. 禁止 Map 传递业务数据
64
- ```bash
65
- Grep pattern: "Map<String,\s*Object>" path: [目标目录] glob: "*.java"
66
- ```
67
- - ❌ 返回 `Map<String, Object>` → ✅ 使用 VO 类
68
-
69
- ### 🟡 警告问题(建议修复)
70
-
71
- #### 7. 请求体封装
72
- ```bash
73
- Grep pattern: "@RequestBody [^L]" path: [目标目录] glob: "*Controller.java"
74
- ```
75
- - 建议所有 POST 请求使用 `@RequestBody LeRequest<T>` 封装
76
-
77
- #### 8. 依赖注入
78
- ```bash
79
- Grep pattern: "@Autowired" path: [目标目录] glob: "*.java"
80
- ```
81
- - 跨模块循环依赖时使用 `@Autowired @Lazy`
10
+ **审查流程**:请读取 `.claude/skills/codex-code-review/SKILL.md` 获取完整的审查清单和工作流,然后按照其中的 Phase 2(本地规范检查)执行审查。
82
11
 
83
- #### 9. 事务注解
84
- ```bash
85
- Grep pattern: "@Transactional" path: [目标目录] glob: "*Service*.java"
86
- ```
87
- - 写操作应使用 `@Transactional(rollbackFor = Exception.class)`
88
-
89
- #### 10. 国际化异常
90
- ```bash
91
- Grep pattern: 'new LeException\("[^"]*[\u4e00-\u9fa5]' path: [目标目录] glob: "*.java"
92
- ```
93
- - 建议使用 `I18n.getMessage()` 替代硬编码中文
94
-
95
- ---
96
-
97
- ## 前端审查(如涉及)
98
-
99
- 前端项目路径:`/Users/xujiajun/Developer/frontProj/web`
100
-
101
- ### 🔴 严重问题
102
-
103
- ```bash
104
- # 检查是否正确处理响应码
105
- Grep pattern: "\.code\s*==\s*200\|\.code\s*===\s*200" path: [前端目录] # ❌ 应为 10000
106
- Grep pattern: "Admin-Token" path: [前端目录] glob: "*.js" # Token key 验证
107
- ```
108
- - 成功码:`10000`(不是 200)
109
- - Token:`Admin-Token`(localStorage)
110
- - 租户:`MERCHANT-ID`(请求头)
111
- - 金额:后端返回分,前端用 `money()` 转元显示
112
-
113
- ---
114
-
115
- ## 审查报告格式
116
-
117
- ```
118
- # 代码审查报告
119
-
120
- 审查范围: [文件/模块]
121
-
122
- ## 严重问题(X 项)
123
- 1. [问题类型]
124
- 文件: path/to/file.java:行号
125
- 问题: 描述
126
- 修复: 代码示例
127
-
128
- ## 警告问题(X 项)
129
- ...
130
-
131
- ## 通过项
132
- - [x] 包名规范 (net.xnzn.core.*)
133
- - [x] 使用 LeException
134
- - [x] 审计字段正确 (crby/crtime/upby/uptime)
135
- - [x] del_flag 语义正确 (2=正常)
136
- ...
137
-
138
- 结论: ✅ 通过 / ⚠️ 需修复 / ❌ 不通过
139
- ```
12
+ **核心架构**:四层架构(Controller → Business → Service → Mapper),包名 `net.xnzn.core.*`,JDK 21,双库物理隔离(无 tenant_id 字段)。
@@ -86,6 +86,7 @@ const instructions = `## 强制技能激活流程(必须执行)
86
86
  - brainstorm: 头脑风暴/创意/方案设计
87
87
  - collaborating-with-codex: Codex协作/多模型/算法分析
88
88
  - collaborating-with-gemini: Gemini协作/前端原型/UI设计
89
+ - codex-code-review: 代码审查/review/代码检查/code review/审查代码/检查代码/代码质量
89
90
  - workflow-engine: 工作流/审批流/Flowable/流程
90
91
  - test-development: 测试/单元测试/@Test/JUnit5/Mockito
91
92
  - json-serialization: JSON/序列化/反序列化/JsonUtils/日期格式/BigDecimal/精度/类型转换
@@ -122,6 +123,7 @@ const instructions = `## 强制技能激活流程(必须执行)
122
123
  - leniu-data-permission: 多租户/数据权限/@UseSystem/Executors.doInTenant/readInSystem/TenantContextHolder/MERCHANT-ID/双库隔离/数据源切换
123
124
  - leniu-redis-cache: Redis/缓存/RedisUtil/分布式锁/RLock/getLock/setNx/ZSet/限流/缓存击穿
124
125
  - leniu-security-guard: 安全认证/SQL注入防护/XSS防护/数据脱敏/SM4加密/接口安全/限流
126
+ - loki-log-query: 查日志/traceId/链路追踪/Loki/日志查询/线上日志/生产日志/错误日志/异常堆栈/日志排查
125
127
  - leniu-mealtime: 餐次/mealtime/mealtimeType/早餐/午餐/晚餐/下午茶/夜宵/AllocMealtimeTypeEnum
126
128
  - leniu-marketing-price-rule-customizer: 营销计费/计价规则/RulePriceHandler/RulePriceEnum/折扣规则/满减规则/限额规则/补贴规则
127
129
  - leniu-marketing-recharge-rule-customizer: 营销充值/充值规则/RuleRechargeHandler/RuleRechargeEnum/满赠规则/充值赠送/管理费规则
@@ -1,11 +1,12 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
3
  * Stop Hook - Claude 回答结束时触发
4
- * 功能: nul 文件清理 + 智能完成通知(音效/系统通知/TTS)
4
+ * 功能: nul 文件清理 + 代码审查提示 + 智能完成通知(音效/系统通知/TTS)
5
5
  */
6
6
 
7
7
  const fs = require('fs');
8
8
  const path = require('path');
9
+ const { execSync } = require('child_process');
9
10
 
10
11
  // 清理可能误创建的 nul 文件(Windows 下 > nul 可能创建该文件)
11
12
  const findAndDeleteNul = (dir, depth = 0) => {
@@ -27,6 +28,28 @@ const findAndDeleteNul = (dir, depth = 0) => {
27
28
  };
28
29
  findAndDeleteNul(process.cwd());
29
30
 
31
+ // 代码审查提示:检测是否有未提交的代码变更
32
+ try {
33
+ const cwd = process.cwd();
34
+ const diff = execSync('git diff --name-only HEAD 2>/dev/null || true', { cwd, encoding: 'utf8' }).trim();
35
+ const staged = execSync('git diff --cached --name-only 2>/dev/null || true', { cwd, encoding: 'utf8' }).trim();
36
+ const allChanged = [diff, staged].filter(Boolean).join('\n');
37
+
38
+ if (allChanged) {
39
+ // 检查是否有业务代码变更(Java/XML/SQL/Vue/JS 等)
40
+ const codeExtensions = /\.(java|xml|sql|vue|js|ts|jsx|tsx|py|go|rs|kt)$/i;
41
+ const changedFiles = allChanged.split('\n').filter(f => codeExtensions.test(f));
42
+
43
+ if (changedFiles.length > 0) {
44
+ console.error(`\n💡 检测到 ${changedFiles.length} 个代码文件变更,建议执行代码审查:`);
45
+ console.error(` → 输入 "review" 或 "审查代码" 使用 code-reviewer 进行规范检查`);
46
+ console.error(` → 输入 "codex review" 调用 Codex 进行深度代码审查\n`);
47
+ }
48
+ }
49
+ } catch {
50
+ // git 不可用或非 git 仓库,静默跳过
51
+ }
52
+
30
53
  // 执行智能通知
31
54
  require('./lib/notify.js').run(process.cwd())
32
55
  .then(() => process.exit(0))
@@ -0,0 +1,327 @@
1
+ ---
2
+ name: codex-code-review
3
+ description: |
4
+ 代码审查工作流。分两阶段:先执行本地规范检查(Grep 即时完成)+ 代码逻辑审查(Read 逐文件),再可选调用 Codex CLI 深度审查。
5
+
6
+ 触发场景:
7
+ - /dev 或 /crud 命令完成代码生成后
8
+ - Bug 修复完成后
9
+ - 用户说"审查代码"、"review"、"代码审查"、"检查代码"
10
+ - 用户说"检查一下刚写的代码"
11
+ - Stop Hook 提示后用户输入"review"
12
+
13
+ 触发词:代码审查、review、审查代码、检查代码、code review、代码质量、codex审查、codex review
14
+ ---
15
+
16
+ # 代码审查工作流
17
+
18
+ > 两阶段审查:**本地检查**(规范 + 逻辑) + **Codex 深度审查**(可选)。
19
+
20
+ ## Phase 1: 收集变更范围
21
+
22
+ ```bash
23
+ git diff --name-only HEAD
24
+ git diff --cached --name-only
25
+ ```
26
+
27
+ 如果没有变更文件,提示"没有检测到代码变更"并终止。
28
+
29
+ 将变更文件按类型分组:
30
+ - **Java 文件**:Controller / Business / Service / Mapper / Entity / VO / DTO
31
+ - **XML 文件**:Mapper XML
32
+ - **SQL 文件**:建表/变更脚本
33
+ - **其他**:配置文件等
34
+
35
+ ---
36
+
37
+ ## Phase 2: 本地检查(必做)
38
+
39
+ 分两步执行:**Step A** 用 Grep 批量扫描规范问题(秒级),**Step B** 用 Read 逐文件审查代码逻辑。
40
+
41
+ ### Step A: 项目规范扫描(Grep 批量检查)
42
+
43
+ #### 🔴 A1. 包名规范
44
+ ```bash
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 \
245
+ --cd . \
246
+ --sandbox read-only \
247
+ --PROMPT "Review the following changed files for code quality issues:
248
+
249
+ FILES TO REVIEW:
250
+ {变更文件列表,含相对路径}
251
+
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
269
+
270
+ OUTPUT FORMAT:
271
+ For each issue:
272
+ - [SEVERITY] CRITICAL / WARNING / SUGGESTION
273
+ - [FILE] filepath:line_number
274
+ - [ISSUE] Description
275
+ - [FIX] Recommended fix
276
+
277
+ If no issues: ALL CLEAR
278
+
279
+ IMPORTANT: All comments in Chinese, code/paths in English."
280
+ ```
281
+
282
+ **关键约束**:
283
+ - 始终使用 `--sandbox read-only`,Codex 不直接修改文件
284
+ - 变更文件过多时(>10 个),按模块分批审查
285
+ - 使用 `run_in_background` 避免阻塞
286
+
287
+ ---
288
+
289
+ ## Phase 4: 用户确认后修复
290
+
291
+ 合并 Phase 2 和 Phase 3 的所有问题,等待用户确认:
292
+ - **全部修复**:"修复所有问题" → 逐个修复所有 🔴 + 🟡
293
+ - **选择性修复**:"只修复严重问题" → 仅修复 🔴
294
+ - **跳过**:"不需要修复" → 终止
295
+
296
+ 修复时:
297
+ 1. 按文件逐个修复,使用 Edit 工具
298
+ 2. 每修复一个文件,简要说明改动
299
+ 3. 🔵 建议级别默认跳过,除非用户明确要求
300
+ 4. 修复完成后运行 `git diff` 展示所有变更
301
+
302
+ ---
303
+
304
+ ## Phase 5: 最终确认
305
+
306
+ 修复完成后询问:"是否需要再次审查确认?"
307
+ - 如果用户同意 → 回到 Phase 2 重新审查
308
+ - 如果用户拒绝 → 输出最终结论并终止
309
+
310
+ ```
311
+ 结论: ✅ 通过 / ⚠️ 需修复 / ❌ 不通过
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
  |------|------|