使用AI进行code review
用法(code-review.md)
打开claude、hermes-agent 或者你顺手的可以执行长时间的工具,输入下面的提示词,你也可以要求每次扫描前获取最新的代码
```
./
├── admin-java/ # 后端源代码
├── front-admin/
│ ├── front-admin-web/ # 前端源代码(管理端网站)
│ └── front-admin-app/ # 前端源代码(管理端APP)
├── front-client/
│ ├── front-c-admin-web/ # 前端源代码(面客端网站1)
│ └── front-client-web/ # 前端源代码(面客端网站2)
└── easy-nvr/
└── front-easynvr-web/ # 前端源代码(管理端NVR子网站)
```
根据规则:./java-code-review.md
对代码进行 代码审查。输出审查报告,文件名:代码审查-[年-月-日-时].md(如 代码审查-2026-09-03-15.md)
每次扫描前应该更新主分支代码,主分支名称为 development或dev
相关提示词(java-code-review.md)
# 后端JAVA代码 Code Review 检查项
标签语义:
- 【停用】:本条不检查,扫描时跳过
- 【待改造】:本条仍然要检查,按目标态标准执行;发现的存量不合规项不报违规,归入清单管理
## 一、架构与设计类
1. **分层规范(Controller / Service / DAO 职责边界)**
- Controller 只做参数接收校验、调 Service、组装响应,禁止写业务逻辑、禁止直接调 Mapper/DAO
- Service 承担业务逻辑与事务边界,不出现 HttpServletRequest 等 Web 层对象
- DAO/Mapper 只做数据存取,不写业务判断;禁止 Service 之间循环依赖
2. **面客端与管理端接口分离**
- 面客端(网站 / APP / 小程序)和管理端(WEB / APP)的接口不得混在同一个 Controller 里,必须分开建 Controller。
- URL 规范:
- 【待改造】管理端接口路径规范:/api/<服务>/<路径>
- 【待改造】面客端接口路径规范: /api/<服务>/client/<路径>,即路径必须含 /client/ 段
- 接口归属判定:以 Controller 映射路径是否含 /client/ 段为准,**含 /client/ 段为面客端接口,无 /client/ 段一律视为管理端接口**;与前端源码(面客端 / 管理端分别提供)做交叉验证,面客端前端调用了但没有 /client/ 段的,列入改造清单;有 /client/ 段但没有被面客端前端调用的,列入清理清单。
- 两端走各自的认证鉴权链和过滤器配置,互不复用;管理端接口不得挂在面客端路由下,反之亦然
- 管理端网关:/api
- 面客端网关:/c-api,不带 /client/ 段的路由一律拒绝(须在路由匹配前以 GlobalFilter 拦截)
- 接口归属须与用户提供并标注的前端源码双向交叉验证:同一 Controller 被两端前端共同调用即违规;前端调用了但后端找不到对应 Controller
的路径,按违规报告;接口既未被管理端前端调用、也未被面客端前端调用的,列为未归属接口报告,不得静默跳过(第 7 条的越权检查依赖本条的归类结果)
3. **接口设计**
- RESTful 规范:所有接口统一使用 POST,参数一律通过 @RequestBody 从请求 body 中接收;禁止使用 GET / PUT / DELETE,禁止用 @RequestParam / @PathVariable / 表单形式接收参数。确有特殊情况(如第三方回调、文件下载等)必须使用其他方式的,须在代码注释中明确注明原因,未注明原因的按违规报告;统一返回格式 { code, message, data }
- 写接口需幂等:重复调用不产生副作用
- 禁止开启 Swagger / OpenAPI 文档端点,不管什么环境(项目未使用,发现依赖或配置开启即报告)
4. **第三方调用**
- 调用外部服务必须设置超时(connect + read)
- 必须有降级 / 重试策略(熔断器如 Sentinel / Resilience4j);重试设最大次数和退避间隔
- 关键调用必须记录请求和响应日志(脱敏后)
## 二、安全类
5. **【停用】CVE 漏洞扫描**
- 检查 pom.xml 中写死版本号的三方依赖,比对 NVD / Snyk / dependency-check 是否落在已知漏洞影响区间内
- 同一依赖出现多个版本并存的,报告中列出各模块使用的版本,建议收敛到父 pom 统一管理;扫描阶段只标记不修复
- 命中漏洞的依赖:报告中列出所用版本、漏洞编号(CVE ID)、官方修复版本号;扫描阶段只标记不修复
6. **SQL 注入**
- mapper XML 和注解 SQL(@Select 等)中,凡是接收外部输入的地方一律用 #{} 预编译,禁止 ${} 拼接和字符串拼接 SQL
- ORDER BY 排序字段:列名不能用 #{} 预编译,服务端必须用白名单映射(前端传别名,服务端换真实列名),方向只允许 asc / desc
- 分页 limit:每页条数、页码等数值用 #{} 预编译传参,禁止 ${} 拼接(如 limit ${offset});每页条数设上限(最大 1000 条)防止一次拉全表
- MyBatis-Plus Wrapper 的 .last() / .apply() 中不允许拼接用户输入;IN 子句参数数量设置上限(最大 10个)
7. **没有增加权限标识(含越权)**
- 每个接口都必须声明鉴权方式:方法上加权限注解(`@PreAuthorize` / `@RequiresPermissions` / 自定义注解),或在 SecurityConfig 中配置路径规则;没声明的就是缺权限标识
- 管理端接口(无 /client/ 段)权限注解必须全覆盖,写接口(新增/修改/删除)和接收身份参数的接口尤为重要。
- 区分接口是面客端还是管理端,再定用户 ID 的来源:
- 面客端接口(面客端网站 / APP / 小程序):查当前用户数据时,用户 ID 必须从登录 token 中获取,禁止直接接收前端传入的 userId 参数,防止横向越权
- 管理端接口(管理端 WEB / APP):可以按传入的 userId 查询任意用户数据,但必须挂权限标识,登录 ≠ 有权限
- 接口归属面客端还是管理端,按第 2 条的归类规则判定;同一接口被两端前端共同调用的,越权按"从严"(面客端)规则检查
- 根据 ID 查询/修改/删除资源时,必须校验资源归属(用户 A 不能操作用户 B 的数据);普通用户不能调用管理员接口(垂直越权)
- 匿名放行的白名单逐条注明原因,写操作一律不允许匿名访问
8. **认证与会话安全(暴力破解、弱密码、短信轰炸防护)**
- 防暴力破解:同一账号 / IP 连续登录失败 N 次(如 5 次)后锁定或要求验证码,失败计数要落库并可告警
- 密码强度:长度 ≥ 8 位且至少含 3 类字符(大小写 / 数字 / 符号),拒绝常见弱密码(123456、admin123)和与账号相同的密码
- 密码存储用 BCrypt 等加盐慢哈希,禁止 MD5 / SHA / 明文
- 短信轰炸防护:验证码同一手机号 60 秒 1 条,发送前必须先过图形验证码等人机校验
- 会话与 token:必须有过期时间,退出登录、修改密码后旧 token 要立即失效
9. **XSS / CSRF**
- XSS 过滤链必须启用(XssFilter 默认关闭,需配置 renren.xss.enabled=true 才生效);富文本内容入库前必须清洁
- Cookie 会话的服务必须有 CSRF Token;Authorization 头传 token 的接口天然免疫,无需检查
- 响应头正确设置 Content-Type,避免浏览器自动嗅探
10. **敏感信息泄露**
- 日志中禁止出现密码、Token、身份证号、手机号、银行卡号;如需记录必须脱敏(如 138****1234)
- 【停用】配置文件禁止明文存储密码/密钥,使用加密配置或密钥管理服务
- 异常堆栈不得直接返回给前端,统一包装为标准错误响应
## 三、代码质量类
11. **魔法变量**
- 一个变量在生命周期内被不同代码块反复赋值、复用作不同用途(如 result / flag / temp 先后装多种东西),含义随位置漂移,极易误读误改
- 不同用途必须拆成各自独立命名的变量,做到见名知义
- 缩小变量作用域:就近声明、尽量一次赋值,禁止在大方法里跨代码块共享一个变量
12. **非空验证**
- 接口入参用 DTO + @Validated + JSR-303 注解校验,禁止用 Map 裸接参数
- 查询结果(getById、getOne、list.get(0) 等)必须先判空再取值;链式调用(user.getAddress().getCity())注意中间环节判空
- 外部调用(RPC / HTTP / MQ)的返回值使用前必须判空;集合用 CollectionUtils.isEmpty() 判空,Map 取值用 getOrDefault
13. **异常处理**
- 禁止空 catch 块、禁止 e.printStackTrace(),捕获后至少 log.error 带完整堆栈
- 统一走 @ControllerAdvice + @ExceptionHandler 全局捕获;自定义业务异常继承 RuntimeException 并携带错误码
- 不要用异常做流程控制;finally 块中禁止 return(会覆盖 try 中的返回值)
14. **命名与方法设计**
- 类名大驼峰、方法/变量小驼峰、常量全大写下划线;布尔以 is/has/can 开头
- 单个方法不超过 200 行、参数不超过 20 个、嵌套不超过 5 层,用早返回优化
- 【停用】方法名体现行为:get 查询 / save 新增 / update 修改 / remove 删除 / delete 删除
## 四、性能类
15. **数据库查询**
- 禁止循环内查库(N+1 问题):改批量查询或 JOIN;批量插入用 INSERT VALUES (...),(...) 或 batch 模式
- 禁止 SELECT *;大结果集必须分页;单表查询必须命中索引(EXPLAIN 确认执行计划)
- LIKE '%keyword%' 左模糊无法走索引,考虑全文检索(ES)
- @Transactional 范围尽量小,事务中不调外部接口
16. **【停用】缓存**
- 高频读、低频写的数据加缓存
- 缓存必须设置过期时间
- 防缓存穿透(不存在的 key)、雪崩(同时过期)、击穿(热点 key);修改数据后必须同步更新/删除缓存
17. **【停用】并发与线程安全**
- 线程池必须自定义配置,禁止 Executors.newFixedThreadPool() 无界队列;异步任务必须设置超时时间
- SimpleDateFormat 非线程安全,用 DateTimeFormatter;Controller(单例)禁止用实例变量存请求状态
- 余额扣减、库存扣减必须用乐观锁或悲观锁防超卖;定时任务多实例部署时加分布式锁防重复执行
18. **资源管理**
- IO 流、数据库连接必须用 try-with-resources 或 finally 关闭
- 文件上传限制大小;下载文件用流式传输,避免一次性加载到内存
## 五、日志与可观测性
19. **日志规范**
- 使用 SLF4J + Logback / Log4j2,禁止 System.out.println;禁止在循环中打日志
- 级别正确:ERROR 系统异常需人工介入 / WARN 可恢复问题 / INFO 关键业务节点 / DEBUG 生产环境关闭
- 日志必须包含上下文(traceId / userId / 关键参数);异常日志打完整堆栈 log.error("msg", e)
20. **监控埋点(慢 SQL、线程池、GC)**
- 慢 SQL:数据源开启慢 SQL 统计(如 Druid slowSqlMillis / p6spy),超阈值(如 500ms)记日志并告警
- 【停用】线程池:自建线程池必须用 ThreadFactory 命名、暴露活跃线程数 / 队列积压指标,禁用 Executors 快捷方法
- 【停用】GC 与链路:启动参数开启 GC 日志,接入 actuator / micrometer,核心接口有耗时打点(成功率、耗时、QPS)
21. **【停用】关键操作日志埋点(增加、修改、删除)**
- 对数据库的新增、修改、删除操作,必须记录操作日志:操作人、操作时间、操作内容(含操作前后数据快照)