codex-code-review

两阶段审查:本地检查(规范 + 逻辑) + Codex 深度审查(可选)。

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "codex-code-review" with this command: npx skills add xu-cell/ai-engineering-init/xu-cell-ai-engineering-init-codex-code-review

代码审查工作流

两阶段审查:本地检查(规范 + 逻辑) + Codex 深度审查(可选)。

Phase 1: 收集变更范围

git diff --name-only HEAD git diff --cached --name-only

如果没有变更文件,提示"没有检测到代码变更"并终止。

将变更文件按类型分组:

  • Java 文件:Controller / Business / Service / Mapper / Entity / VO / DTO

  • XML 文件:Mapper XML

  • SQL 文件:建表/变更脚本

  • 其他:配置文件等

Phase 2: 本地检查(必做)

分两步执行:Step A 用 Grep 批量扫描规范问题(秒级),Step B 用 Read 逐文件审查代码逻辑。

Step A: 项目规范扫描(Grep 批量检查)

🔴 A1. 包名规范

Grep pattern: "package org.dromara." path: [目标目录] glob: "*.java"

  • ❌ package org.dromara.xxx → ✅ package net.xnzn.core.xxx

🔴 A2. 禁止 RuoYi 工具类

Grep pattern: "MapstructUtils" path: [目标目录] glob: ".java" Grep pattern: "ServiceException" path: [目标目录] glob: ".java" Grep pattern: "import javax.validation" path: [目标目录] glob: "*.java"

  • ❌ MapstructUtils → ✅ BeanUtil.copyProperties()

  • ❌ ServiceException → ✅ LeException

  • ❌ javax.validation.* → ✅ jakarta.validation.* (JDK 21)

🔴 A3. 审计字段名称

Grep pattern: "private.*createBy|private.*updateBy|private.*createTime|private.updateTime" path: [目标目录] glob: ".java"

  • ❌ createBy/updateBy/createTime/updateTime → ✅ crby/upby/crtime/uptime

🔴 A4. del_flag 值语义

Grep pattern: "delFlag.*=.0|del_flag.=.0" path: [目标目录] glob: ".java"

  • ❌ delFlag = 0 (RuoYi 正常值) → ✅ delFlag = 2 (leniu 正常值,1=删除)

🔴 A5. Entity 不含 tenant_id

Grep pattern: "tenantId|tenant_id" path: [目标目录] glob: "*.java"

  • ❌ 双库物理隔离,无需 tenant_id 字段

🔴 A6. 禁止 Map 传递业务数据

Grep pattern: "Map<String,\sObject>" path: [目标目录] glob: ".java"

  • ❌ Map<String, Object> → ✅ 使用 VO/DTO 类

🟡 A7. 事务注解缺少 rollbackFor

Grep pattern: "@Transactional\b" path: [目标目录] glob: "*.java"

对命中文件二次检查:是否缺少 rollbackFor

Grep pattern: "@Transactional((?!.*rollbackFor)" path: [命中文件]

  • ❌ @Transactional → ✅ @Transactional(rollbackFor = Exception.class)

🔴 A7b. selectOne 无唯一保障

Grep pattern: "selectOne(" path: [目标目录] glob: "*.java"

命中行检查:是否有 LIMIT 1 或注释说明唯一索引

  • ❌ 无 LIMIT 且无唯一索引 → ✅ 加 .last("LIMIT 1") 或确保有唯一索引

🟡 A7c. selectCount 用于存在性判断

Grep pattern: "selectCount" path: [目标目录] glob: "*.java"

检查命中行是否用于 > 0 判断(存在性),而非真正计数

  • ❌ selectCount(w) > 0 → ✅ mapper.exists(w) 或 selectList(w.last("LIMIT 1"))

🔴 A7d. Redis KEYS 命令

Grep pattern: "keysByPattern|.keys(" path: [目标目录] glob: "*.java"

  • ❌ redisTemplate.keys() / keysByPattern() → ✅ 使用 Redisson deleteByPattern() (内部 SCAN + UNLINK)

🟡 A7e. Optional.of 误用

Grep pattern: "Optional.of(" path: [目标目录] glob: "*.java"

排除 ofNullable 的命中

  • ❌ Optional.of(可能为null) → ✅ Optional.ofNullable(value)

🟡 A7f. 布尔字段类型错误

Grep pattern: "private Integer (if|is|has)" path: [目标目录] glob: "*.java"

  • ❌ private Integer isEnabled → ✅ private Boolean enabled

🟡 A7g. Wrapper 嵌套过深

人工审查:Read 文件时检查 Wrapper 嵌套是否超过 2 层

  • ❌ Wrapper 嵌套 >2 层 → ✅ 迁移到 XML 原生 SQL

🟡 A8. 请求体封装

Grep pattern: "@RequestBody [^L]" path: [目标目录] glob: "*Controller.java"

  • 建议 POST 请求使用 @RequestBody LeRequest<T> 封装

🟡 A9. 金额类型错误

Grep pattern: "Double|Float|double|float" path: [目标目录] glob: "*.java"

在命中行中检查是否涉及金额字段(amount/price/money/fee/cost)

  • ❌ Double/Float 处理金额 → ✅ Long (分)或 BigDecimal

🟡 A10. BigDecimal 比较错误

Grep pattern: "BigDecimal.*==|==.BigDecimal" path: [目标目录] glob: ".java"

  • ❌ bigDecimal1 == bigDecimal2 → ✅ bigDecimal1.compareTo(bigDecimal2) == 0

🟡 A11. SELECT * 查询

Grep pattern: "SELECT *|select *" path: [目标目录] glob: "*.xml"

  • ❌ SELECT * → ✅ 明确列出需要的字段

🟡 A12. SQL 注入风险

Grep pattern: '${' path: [目标目录] glob: "*.xml"

  • ❌ ${} 拼接参数 → ✅ #{} 参数化查询(ORDER BY 等特殊场景除外)

🟡 A13. 国际化异常

Grep pattern: 'new LeException("[^"][\u4e00-\u9fa5]' path: [目标目录] glob: ".java"

  • 建议使用 I18n.getMessage() 替代硬编码中文

Step B: 代码逻辑审查(Read 逐文件检查)

对每个变更的 Java 文件执行 Read,按以下清单逐项审查。

Java 必检项(所有 Java 文件)

检查项 检查要点 严重级

B1 空指针风险 selectOne /getOne /selectById 返回值是否有 null 判断;Optional 是否正确处理 🔴

B2 参数校验 入参是否校验非空和合法性(@NotNull /@NotEmpty /Objects.requireNonNull /手动 if 判断) 🔴

B3 并发安全 查询+新增/查询+更新的组合操作是否有竞态条件;是否需要分布式锁 🔴

B4 事务边界 多表写操作是否加了 @Transactional(rollbackFor = Exception.class)

🔴

B5 资源关闭 Stream/IO流/数据库连接是否用 try-with-resources 或 finally 关闭 🔴

B6 集合并发修改 forEach 内是否有 remove/add 操作;应使用 Iterator 或 removeIf

🔴

B7 分页泄漏 PageMethod.startPage() 是否紧贴查询语句,中间不能有其他 SQL 查询 🔴

Java 安全项

检查项 检查要点 严重级

B8 租户隔离(仅定时任务) 定时任务中是否使用 Executors.doInTenant() /doInAllTenant() 切换到商户库;普通接口默认在商户库,无需额外处理 🔴

B9 SQL 注入 动态 SQL 是否使用参数化查询;拼接 SQL 是否转义 🔴

B10 越权访问 删除/修改操作是否校验数据归属(检查 where 条件是否包含归属字段) 🔴

B11 敏感信息 日志中是否打印了密码、token、身份证、银行卡等敏感信息 🔴

B12 批量操作限制 批量删除/更新是否限制了最大数量,防止误操作全表 🟡

Java 跨模块调用项

检查项 检查要点 严重级

B13 返回值兜底 返回 List /Map 时是否有空集合兜底(Collections.emptyList() ),避免调用方 NPE 🟡

B14 集合参数防御 集合入参(List /Set )是否判空,空集合的 IN() 会导致 SQL 异常 🔴

B15 异常透传 是否吞掉异常不抛出(空 catch 块);跨模块调用需要明确的异常传递 🔴

B16 日志追踪 关键操作或异常分支是否有日志(log.info /log.error ),便于跨模块问题排查 🟡

Java 代码规范项

检查项 检查要点 严重级

B17 魔法值 是否存在未定义的常量(状态码 1/2/3 必须用枚举,字符串必须定义常量) 🟡

B18 方法长度 方法是否过长(>50 行),需要拆分为子方法 🔵

B19 注释完整性 公共 API(Controller/Business 方法)是否有 JavaDoc 注释 🔵

B20 空 catch 块 catch 块是否为空或仅打印日志而不处理/不抛出 🟡

B21 过时 API 是否使用了 @Deprecated 的方法或类 🔵

B22 返回值一致性 Controller 层是否统一返回 LeResponse<T> ,不能裸返回 🟡

MyBatis XML 检查(仅 XML 文件)

检查项 检查要点 严重级

X1 SQL 注入 使用 ${} 而非 #{} 进行参数拼接(ORDER BY 等场景需白名单校验) 🔴

X2 IN 查询防护 IN 查询是否用 <foreach> 且考虑集合为空的情况(空 IN 会 SQL 异常) 🔴

X3 动态 SQL 语法 <if> /<where> /<choose> 标签使用是否正确,是否会产生多余的 AND/OR 🟡

X4 **SELECT *** 是否使用 SELECT * ,应明确列出需要的字段 🟡

X5 缺少 WHERE UPDATE/DELETE 是否缺少 WHERE 条件(全表操作风险) 🔴

X6 索引失效 WHERE 条件是否对索引字段使用了函数(DATE(crtime) )或隐式类型转换 🟡

X7 LIKE 前模糊 LIKE '%xxx%' 或 LIKE CONCAT('%', #{}, '%') 前模糊导致全表扫描 🟡

X8 大表无分页 大表查询是否遗漏分页,可能造成 OOM 🟡

X9 namespace 匹配 namespace 是否与 Mapper 接口全限定名完全匹配 🔴

X10 resultMap 映射 是否正确定义 resultMap,字段名和属性名是否对应 🟡

本地检查结果展示

代码审查报告

审查范围: [变更文件列表]

🔴 严重问题(X 项)

  1. [B1 空指针风险] 文件: OrderServiceImpl.java:42 问题: selectById 返回值未做 null 判断 修复: if (ObjectUtil.isNull(entity)) throw new LeException("数据不存在");

  2. [A2 禁止 RuoYi 工具类] 文件: UserServiceImpl.java:15 问题: 使用了 MapstructUtils 修复: 替换为 BeanUtil.copyProperties()

🟡 警告问题(X 项)

...

🔵 建议(X 项)

...

✅ 通过项

  • A1 包名规范 (net.xnzn.core.*)
  • A3 审计字段正确 (crby/crtime/upby/uptime)
  • A4 del_flag 语义正确 (2=正常)
  • B8 租户隔离正确 ...

结论: ✅ 通过 / ⚠️ 需修复 X 项 / ❌ 不通过

如果全部通过 → 展示"本地检查通过",询问是否需要 Codex 深度审查。 如果有问题 → 先修复严重问题,修复后再询问是否需要 Codex 深度审查。

Phase 3: Codex 深度审查(可选)

依赖 collaborating-with-codex skill 的 codex_bridge.py 脚本。 Codex 擅长发现本地规则难以覆盖的逻辑 Bug、复杂并发问题、架构缺陷。

Phase 2 完成后询问用户:"是否需要 Codex 深度审查?"

  • 用户同意 → 执行以下流程

  • 用户拒绝 → 跳到 Phase 5

python3 .claude/skills/collaborating-with-codex/scripts/codex_bridge.py
--cd .
--sandbox read-only
--PROMPT "Review the following changed files for code quality issues:

FILES TO REVIEW: {变更文件列表,含相对路径}

REVIEW FOCUS (beyond basic lint):

  1. Logic bugs: race conditions, off-by-one, incorrect state transitions, edge cases
  2. Security: privilege escalation, data leakage across tenants, missing auth checks
  3. Architecture: Controller calling Mapper directly, Business layer bypassed, circular dependencies
  4. Performance: N+1 queries, missing pagination on large tables, unnecessary DB calls in loops
  5. Concurrency: check-then-act without locking, shared mutable state, CompletableFuture error handling

PROJECT CONTEXT:

  • Package: net.xnzn.core.* (NOT org.dromara.*)
  • 4-layer: Controller → Business → Service → Mapper
  • 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
  • Audit fields: crby/crtime/upby/uptime
  • del_flag: 1=deleted, 2=normal
  • Exception: LeException (NOT ServiceException)
  • Object copy: BeanUtil.copyProperties() (NOT MapstructUtils)
  • Amount: stored as Long (fen/cents), NOT Double/Float
  • Pagination: PageMethod.startPage() must be immediately before query

OUTPUT FORMAT: For each issue:

  • [SEVERITY] CRITICAL / WARNING / SUGGESTION
  • [FILE] filepath:line_number
  • [ISSUE] Description
  • [FIX] Recommended fix

If no issues: ALL CLEAR

IMPORTANT: All comments in Chinese, code/paths in English."

关键约束:

  • 始终使用 --sandbox read-only ,Codex 不直接修改文件

  • 变更文件过多时(>10 个),按模块分批审查

  • 使用 run_in_background 避免阻塞

Phase 4: 用户确认后修复

合并 Phase 2 和 Phase 3 的所有问题,等待用户确认:

  • 全部修复:"修复所有问题" → 逐个修复所有 🔴 + 🟡

  • 选择性修复:"只修复严重问题" → 仅修复 🔴

  • 跳过:"不需要修复" → 终止

修复时:

  • 按文件逐个修复,使用 Edit 工具

  • 每修复一个文件,简要说明改动

  • 🔵 建议级别默认跳过,除非用户明确要求

  • 修复完成后运行 git diff 展示所有变更

Phase 5: 最终确认

修复完成后询问:"是否需要再次审查确认?"

  • 如果用户同意 → 回到 Phase 2 重新审查

  • 如果用户拒绝 → 输出最终结论并终止

结论: ✅ 通过 / ⚠️ 需修复 / ❌ 不通过

前端审查(如涉及前端文件变更)

前端项目路径:/Users/xujiajun/Developer/frontProj/web

检查项 检查要点

F1 响应码 成功码是 10000 (不是 200)

F2 Token Admin-Token (localStorage)

F3 租户头 MERCHANT-ID (请求头)

F4 金额显示 后端返回分,前端用 money() 转元

F5 权限指令 按钮权限使用 v-hasPerm

F6 加密 敏感字段使用 SM4 加密

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

dev

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

leniu-api-development

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

leniu-code-patterns

No summary provided by upstream source.

Repository SourceNeeds Review