# API 变更检测 — 分析与设计

在现有 **类变更检测**（`class-checker.jar`）基础上，扩展 **API 路径变更** 与 **API 参数变更** 两类能力。通知渲染参考 [`11.py`](./11.py)。

---

## 一、用 JavaParser 做方便吗？

**结论：方便，且与现有技术栈一致。**

| 维度 | 评估 |
|------|------|
| 技术栈 | `class-checker` 已依赖 `javaparser-symbol-solver-core 3.25.10`，`EndpointParser` 已在用 |
| 路径解析 | `@RequestMapping` / `@GetMapping` 等注解 + 类级 path 拼接 — **已实现** |
| HTTP 方法 | Mapping 注解读取 — **已实现** |
| 参数解析 | 方法 `Parameter` + `@RequestBody` / `@PathVariable` / `@RequestParam` 注解 — **需扩展** |
| DTO 字段 diff | `@RequestBody` 的 Dto 一级字段 — 可复用 `ClassFieldParser` + `FieldDiffEngine` |
| 跨提交对比 | `git show oldSha:path` / `newSha:path` + AST 对比 — 与类变更相同模式 |

JavaParser **擅长** 注解驱动的 Spring MVC 声明式接口；**不擅长** 运行时动态路由、非注解配置（如 `WebMvcConfigurer` 手动注册）。

---

## 二、与现有代码的关系

```
现有（类变更）                         待扩展（API 变更）
─────────────────                     ─────────────────
GitChangeScanner          ────────►   Git 扫描 Controller/*.java 变更
EndpointParser（索引）    ────────►   EndpointSnapshotParser（含参数明细）
FieldDiffEngine           ────────►   复用：@RequestBody Dto 字段 diff
ImpactAnalyzer            ────────►   （类变更专用，API 变更不直接用）
WeComNotifier             ────────►   ApiChangeNotifier（新，参考 11.py）
```

当前 `ApiEndpoint` 仅含：`httpMethod`、`uri`、`paramTypes`（类型简单名集合）、`returnTypes`，**不足以做参数级 diff**，需扩展为 `ApiEndpointSnapshot`（含每个参数的 name、type、source、required、description 等）。

---

## 三、检测能力拆分

### 3.1 API 路径变更（功能 1）

| 场景 | 识别方式 | 通知模版 |
|------|----------|----------|
| 新增接口 | 新 commit 有、旧 commit 无（同 Controller 方法指纹） | [`api-path-change.md`](./api-path-change.md) · 新增接口 |
| 删除接口 | 旧有、新无 | 删除接口 |
| 修改路径 | 类级/方法级 `@RequestMapping` path 变化，HTTP 方法不变 | 修改路径 |
| 修改请求方式 | 同 URI（或同方法指纹）HTTP 方法变化 | [`api-method-change.md`](./api-method-change.md) |

**方法指纹建议**（用于跨 commit 匹配同一接口）：

```
controller源文件 + 方法名（不含参数信息；增删参/改类型等由 ParameterDiffEngine 检测）
```

仅 URI 匹配在「改路径」场景会失效，需指纹辅助。

### 3.2 API 参数变更（功能 2）

| 参数来源 | 检测内容 | 展示分组 |
|----------|----------|----------|
| `@RequestBody` Dto | Dto **一级字段** 增删改/重命名/类型 | 类对象变更 |
| `@PathVariable` | 名称、类型、是否新增/删除 | 普通参数变更 |
| `@RequestParam` | 名称、类型、required | 普通参数变更 |
| 无注解简单参数 | 视项目规范决定是否纳入 | 待确认 |

**排除**（参考 11.py / comparator 惯例）：`HttpServletRequest`、`HttpServletResponse`、`BindingResult`、`Principal`、`Model`、`ModelMap` 等框架注入参数。

模版见 [`api-param-change.md`](./api-param-change.md)。

---

## 四、建议架构（Java 实现）

```
.gitea/checker/src/main/java/com/aicheck/
├── api/
│   ├── ApiCheckMain.java              # 可选：独立 CLI 或并入 ClassCheckMain
│   ├── scanner/
│   │   └── ControllerChangeScanner.java   # git diff 筛 Controller 文件
│   ├── parser/
│   │   └── EndpointSnapshotParser.java    # 扩展 EndpointParser，输出完整快照
│   ├── analyzer/
│   │   ├── EndpointDiffEngine.java        # 路径/方法/增删对比
│   │   └── ParameterDiffEngine.java       # 参数 + Body Dto 字段对比
│   ├── model/
│   │   ├── EndpointSnapshot.java
│   │   ├── EndpointChangeReport.java      # 对齐 11.py EndpointChangeReport
│   │   └── ParameterChange.java           # 对齐 11.py ParameterChange
│   └── notify/
│       └── ApiChangeNotifier.java         # 对齐 11.py 三类模版
```

**流程**：

1. `git diff --name-only oldSha newSha` 筛 `endpoint_scan.controllers` 下 `.java`
2. 对每个变更 Controller，分别读取 old/new 源码
3. `EndpointSnapshotParser` 解析两端快照
4. `EndpointDiffEngine` 产出路径/方法/增删报告
5. URI+方法未变的接口 → `ParameterDiffEngine` 产出参数报告
6. `ApiChangeNotifier` 按类型发企微（路径/方法/参数分条发送，与 11.py 一致）

---

## 五、模版文件

| 文件 | 对应 11.py | 场景 |
|------|------------|------|
| [api-path-change.md](./api-path-change.md) | `build_path_change_markdown` | 新增 / 删除 / 修改路径 |
| [api-method-change.md](./api-method-change.md) | `build_method_change_markdown` | 修改 HTTP 方法 |
| [api-param-change.md](./api-param-change.md) | `_format_endpoint_block` | URI+方法不变，仅参数变 |
| [11.py](./11.py) | 参考实现（Python + comparator） | 通知渲染逻辑 |

---

## 六、配置扩展建议（`config.yaml`）

```yaml
api_check:
  enabled: true
  endpoint_scan:
    controllers:
      - jnpf-ftb/jnpf-ftb-biz/src/main/java
    feign_apis: []          # 是否纳入 Feign，待确认
  exclude_framework_params: true
  body_dto_field_depth: 1   # @RequestBody 只 diff 一级字段
```

可与 `class_check` 共用 `wecom` 配置。

---

## 七、工作量粗估

| 模块 | 难度 | 说明 |
|------|------|------|
| EndpointSnapshotParser | 中 | 扩展参数注解解析 |
| EndpointDiffEngine | 中 | 方法指纹 + 路径/方法对比 |
| ParameterDiffEngine | 中高 | Body Dto 复用 FieldDiffEngine；普通参数 diff |
| ApiChangeNotifier | 低 |  largely 翻译 11.py |
| CI / 配置 / 联调 | 低 | 扩展 workflow 或合并 Main |

整体：**可行，约 3–5 个核心类 + 1 个 Notifier**，与类变更检测复用 Git + JavaParser + 企微基础设施。

---

## 八、实现状态（已并入 `class-checker.jar`）

| 模块 | 包路径 | 状态 |
|------|--------|------|
| 配置 | `AppConfig` + `config.yaml` `api_check` | ✅ |
| 扫描 | `api.scanner.ApiFileChangeScanner` | ✅ |
| 解析 | `api.parser.EndpointSnapshotParser`、`NestedDtoFieldParser` | ✅ |
| 分析 | `api.analyzer.ApiChangeAnalyzer`、`EndpointDiffEngine`、`ParameterDiffEngine` | ✅ |
| 通知 | `api.notify.ApiChangeNotifier`（路径/方法/参数分条） | ✅ |
| 编排 | `ClassCheckMain`（类变更与 API 变更独立执行） | ✅ |
| 公共 | `common.MarkdownStyles`、`common.WeComMarkdownSender` | ✅ |

**已确认策略**：并入同一 jar；含 Feign；含请求方式变更；嵌套 Dto 字段；对齐类变更通知规范；分条发送；路径+参数同改拆两条；不含 LLM。
