# 使用AI进行code review

#### 用法(code-review.md)

打开claude、hermes-agent 或者你顺手的可以长时间执行的工具,输入下面的提示词，你也可以要求每次扫描前获取最新的代码

claude 自动确认，不反复提示
- 使用 shift+tab键切换到 auto mode
- 启动claude时增加参数

  ```
  
  # 完全跳过所有的权限检查，AI 可以无条件执行任何命令和文件修改，全程不再打扰
  --dangerously-skip-permissions
  
  
  # 自动执行，尽可能的减少交互
  --permission-mode auto
  
  ```
 
`````````

```
./
├── 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. **【待改造】关键操作日志埋点（增加、修改、删除）**
    - 对数据库的新增、修改、删除操作，必须记录操作日志：操作人、操作时间、操作内容（含操作前后数据快照）



``````