This commit is contained in:
@@ -106,12 +106,12 @@ def _format_param_details_section(report: EndpointChangeReport) -> List[str]:
|
||||
def _format_endpoint_block(report: EndpointChangeReport) -> str:
|
||||
"""
|
||||
格式化单个接口块,按模板匹配格式输出。
|
||||
全路径类名显示为 source_file(相对仓库根的完整 .java 路径)。
|
||||
路径显示为 source_file(相对仓库根的完整 .java 路径)。
|
||||
"""
|
||||
change_type = "新增接口" if report.is_new_endpoint else ("删除接口" if report.is_removed_endpoint else "修改参数")
|
||||
uri_line = f"**{report.http_method}** `{report.uri}`"
|
||||
file_path = report.source_file or report.controller_class
|
||||
class_line = f"- **全路径类名:** <font color=\"info\">**{file_path}**</font>"
|
||||
class_line = f"- **路径:** <font color=\"info\">**{file_path}**</font>"
|
||||
|
||||
header = [
|
||||
f"- **变更类型:** <font color=\"warning\">**{change_type}**</font>",
|
||||
@@ -441,7 +441,7 @@ def build_path_change_markdown(
|
||||
# 变更类型高亮
|
||||
type_highlight = f"<font color=\"warning\">**{change_type}**</font>"
|
||||
|
||||
# 全路径类名高亮
|
||||
# 路径高亮
|
||||
class_highlight = f"<font color=\"info\">**{file_name}**</font>"
|
||||
|
||||
# 根据变更类型优化 URI 展示
|
||||
@@ -459,7 +459,7 @@ def build_path_change_markdown(
|
||||
"# 【API路径变更通知】",
|
||||
"",
|
||||
f" 变更类型: {type_highlight}",
|
||||
f" 全路径类名: {class_highlight}",
|
||||
f" 路径: {class_highlight}",
|
||||
f" 修改人: {push_user}",
|
||||
f" 修改时间: {push_time}",
|
||||
"",
|
||||
@@ -496,7 +496,7 @@ def build_method_change_markdown(
|
||||
"# 【API请求方式变更通知】",
|
||||
"",
|
||||
f" 变更类型: {type_highlight}",
|
||||
f" 全路径类名: {class_highlight}",
|
||||
f" 路径: {class_highlight}",
|
||||
f" 修改人: {push_user}",
|
||||
f" 修改时间: {push_time}",
|
||||
"",
|
||||
|
||||
160
.gitea/checker/api-templates/README.md
Normal file
160
.gitea/checker/api-templates/README.md
Normal file
@@ -0,0 +1,160 @@
|
||||
# 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源文件 + 方法名 + 参数类型签名
|
||||
```
|
||||
|
||||
仅 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。
|
||||
38
.gitea/checker/api-templates/api-method-change.md
Normal file
38
.gitea/checker/api-templates/api-method-change.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# API 请求方式变更通知模版
|
||||
|
||||
对应 `11.py` → `build_method_change_markdown()`。
|
||||
适用:URI 不变,仅 **HTTP 方法** 变化(如 `GET` → `POST`)。
|
||||
|
||||
> 第一期是否纳入,待产品确认;模版先备齐。
|
||||
|
||||
---
|
||||
|
||||
## 完整示例
|
||||
|
||||
```
|
||||
# 【API请求方式变更通知】
|
||||
|
||||
变更类型: <font color="warning">**修改请求方式**</font>
|
||||
路径: <font color="info">**jnpf-ftb/jnpf-ftb-biz/src/main/java/jnpf/workflow/controller/ApplyClockInController.java**</font>
|
||||
修改人: dongzi
|
||||
修改时间: 2026-06-08 16:30:00
|
||||
|
||||
---------------------------------------
|
||||
|
||||
#### 【请求方式变更详情】
|
||||
- **URI:** <font color="info">**`/apply/clockIn/{id}`**</font>
|
||||
- **原请求方式:** <font color="warning">**GET**</font>
|
||||
- **新请求方式:** <font color="info">**PUT**</font> ← <font color="info">**请求方式已变更**</font>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 检测逻辑
|
||||
|
||||
- 方法指纹相同 + URI 相同 + `httpMethod` 不同 → `is_method_changed = true`
|
||||
- 与路径变更、参数变更报告**互斥拆分**(同 11.py `comparator` 约定)
|
||||
|
||||
## 实现
|
||||
|
||||
- `EndpointDiffEngine`
|
||||
- `ApiChangeNotifier.buildMethodChangeMarkdown()`
|
||||
121
.gitea/checker/api-templates/api-param-change.md
Normal file
121
.gitea/checker/api-templates/api-param-change.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# API 参数变更通知模版
|
||||
|
||||
对应 `11.py` → `build_markdown_notification()` 中参数变更分支 + `_format_endpoint_block()`。
|
||||
适用:**URI 与 HTTP 方法均未变**,仅入参发生变化。
|
||||
|
||||
---
|
||||
|
||||
## 完整示例
|
||||
|
||||
```
|
||||
# 【API参数变更通知】
|
||||
- **修改人:** dongzi
|
||||
- **修改时间:** 2026-06-08 16:30:00
|
||||
|
||||
- **变更类型:** <font color="warning">**修改参数**</font>
|
||||
- **URI:** **POST** `/apply/clockIn`
|
||||
- **路径:** <font color="info">**jnpf-ftb/jnpf-ftb-biz/src/main/java/jnpf/workflow/controller/ApplyClockInController.java**</font>
|
||||
|
||||
---------------------------------------
|
||||
|
||||
#### 【接口参数变动详情】
|
||||
|
||||
**类对象变更(一级字段)**
|
||||
|
||||
共 **1** 个类对象 · **2** 项字段变更
|
||||
|
||||
**applyAttendanceChangeDto** · `ApplyAttendanceChangeDto`
|
||||
|
||||
├─ `taskIds` · `List<String>` · 必填 [新增]
|
||||
> 说明:流程主键集合
|
||||
└─ `applyUser1` · `Integer` [删除]
|
||||
> 说明:申请人员
|
||||
|
||||
**普通参数变更**
|
||||
|
||||
共 **1** 项变更
|
||||
|
||||
1. `id` · `String` · 路径参数 [新增]
|
||||
> 说明:主键
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 示例(仅普通参数,无 RequestBody)
|
||||
|
||||
```
|
||||
# 【API参数变更通知】
|
||||
- **修改人:** dongzi
|
||||
- **修改时间:** 2026-06-08 16:30:00
|
||||
|
||||
- **变更类型:** <font color="warning">**修改参数**</font>
|
||||
- **URI:** **GET** `/apply/clockIn/{id}`
|
||||
- **路径:** <font color="info">**jnpf-ftb/.../ApplyClockInController.java**</font>
|
||||
|
||||
---------------------------------------
|
||||
|
||||
#### 【接口参数变动详情】
|
||||
|
||||
**普通参数变更**
|
||||
|
||||
共 **1** 项变更
|
||||
|
||||
1. `pageSize` · `Integer` · 查询参数 [新增]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 参数分类与检测
|
||||
|
||||
| 来源注解 | `source` 字段 | diff 粒度 |
|
||||
|----------|---------------|-----------|
|
||||
| `@RequestBody` | `body` | Dto **一级字段**(复用 `FieldDiffEngine`) |
|
||||
| `@PathVariable` | `path` | 参数名、类型、增删 |
|
||||
| `@RequestParam` | `query` | 参数名、类型、required、增删 |
|
||||
| 无注解 | `simple` | 待确认是否纳入 |
|
||||
|
||||
### 排除的框架参数(建议默认开启)
|
||||
|
||||
`HttpServletRequest`、`HttpServletResponse`、`BindingResult`、`Principal`、`Authentication`、`Model`、`ModelMap`、`UriComponentsBuilder` 等。
|
||||
|
||||
---
|
||||
|
||||
## ParameterChange 数据结构(对齐 11.py)
|
||||
|
||||
| 字段 | 说明 |
|
||||
|------|------|
|
||||
| `param_name` | 当前参数名 / 字段名 |
|
||||
| `old_name` | 重命名前名称 |
|
||||
| `param_type` | 类型字符串,如 `List<String>` |
|
||||
| `description` | 说明(@Schema / 注释) |
|
||||
| `source` | `body` / `path` / `query` |
|
||||
| `body_param_name` | `@RequestBody` 形参名 |
|
||||
| `parent_dto` | Dto 简单类名 |
|
||||
| `change_type` | `added` / `removed` / `modified` / `renamed` |
|
||||
| `detail` | 类型变化等详情 |
|
||||
|
||||
---
|
||||
|
||||
## 与路径变更的拆分规则(11.py 约定)
|
||||
|
||||
| 同一次改动 | 通知策略 |
|
||||
|------------|----------|
|
||||
| 仅参数变 | 本模版 |
|
||||
| 路径变 + 参数变 | **拆两条**:先路径通知,再参数通知 |
|
||||
| 方法变 + 参数变 | **拆两条**:先方法通知,再参数通知 |
|
||||
| 新增接口 + 带参数 | 路径通知可**附带**参数详情区块 |
|
||||
|
||||
---
|
||||
|
||||
## JavaParser 实现要点
|
||||
|
||||
1. **EndpointSnapshotParser**:遍历 `MethodDeclaration.getParameters()`,读参数注解
|
||||
2. **@RequestBody**:取 Dto 类型 → `ClassFieldParser.parseFields()` 得字段列表
|
||||
3. **ParameterDiffEngine**:旧/新快照按方法指纹对齐后 diff
|
||||
4. **ApiChangeNotifier**:渲染本模版;泛型类型展示规则与类变更通知一致(`<>` 不 HTML 转义)
|
||||
|
||||
## 实现
|
||||
|
||||
- `ParameterDiffEngine`
|
||||
- `ApiChangeNotifier.formatEndpointBlock()`
|
||||
- 复用 `FieldDiffEngine` / `WeComNotifier` 中的字段行格式(可选统一)
|
||||
88
.gitea/checker/api-templates/api-path-change.md
Normal file
88
.gitea/checker/api-templates/api-path-change.md
Normal file
@@ -0,0 +1,88 @@
|
||||
# API 路径变更通知模版
|
||||
|
||||
对应 `11.py` → `build_path_change_markdown()`。
|
||||
适用:**新增接口**、**删除接口**、**修改路径**。
|
||||
|
||||
---
|
||||
|
||||
## 完整示例(修改路径)
|
||||
|
||||
```
|
||||
# 【API路径变更通知】
|
||||
|
||||
变更类型: <font color="warning">**修改路径**</font>
|
||||
路径: <font color="info">**jnpf-ftb/jnpf-ftb-biz/src/main/java/jnpf/workflow/controller/ApplyClockInController.java**</font>
|
||||
修改人: dongzi
|
||||
修改时间: 2026-06-08 16:30:00
|
||||
|
||||
---------------------------------------
|
||||
|
||||
#### 【URI变更详情】
|
||||
- **原路径:** <font color="warning">~~`/apply/clockIn`~~</font> ← <font color="warning">**旧路径**</font>
|
||||
- **新路径:** <font color="info">**`/apply/clockIn/v2`**</font> ← <font color="info">**新路径**</font>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 示例(新增接口)
|
||||
|
||||
```
|
||||
# 【API路径变更通知】
|
||||
|
||||
变更类型: <font color="warning">**新增接口**</font>
|
||||
路径: <font color="info">**jnpf-ftb/.../ApplyClockInController.java**</font>
|
||||
修改人: dongzi
|
||||
修改时间: 2026-06-08 16:30:00
|
||||
|
||||
---------------------------------------
|
||||
|
||||
#### 【URI变更详情】
|
||||
- **原路径:** `-`
|
||||
- **新路径:** <font color="info">**`/apply/clockIn`**</font> ← <font color="info">**新增**</font>
|
||||
```
|
||||
|
||||
> 若新增接口同时有参数变更,可在路径通知后追加【接口参数变动详情】区块(见 `api-param-change.md`)。
|
||||
|
||||
---
|
||||
|
||||
## 示例(删除接口)
|
||||
|
||||
```
|
||||
# 【API路径变更通知】
|
||||
|
||||
变更类型: <font color="warning">**删除接口**</font>
|
||||
路径: <font color="info">**jnpf-ftb/.../ApplyClockInController.java**</font>
|
||||
修改人: dongzi
|
||||
修改时间: 2026-06-08 16:30:00
|
||||
|
||||
---------------------------------------
|
||||
|
||||
#### 【URI变更详情】
|
||||
- **原路径:** <font color="warning">**`/apply/clockIn/{id}`**</font> ← <font color="warning">**已删除**</font>
|
||||
- **新路径:** `已删除`
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 字段说明
|
||||
|
||||
| 占位符 | 来源 |
|
||||
|--------|------|
|
||||
| 变更类型 | `新增接口` / `删除接口` / `修改路径` |
|
||||
| 路径 | Controller `.java` 相对仓库根路径(`source_file`) |
|
||||
| 原路径 / 新路径 | 类级 `@RequestMapping` + 方法级 Mapping 拼接后的 URI |
|
||||
| HTTP 方法 | 路径变更通知中默认不展示;与请求方式变更模版区分 |
|
||||
|
||||
## 检测逻辑(JavaParser)
|
||||
|
||||
1. 解析旧/新 commit 下同一 Controller 源码 AST
|
||||
2. 提取每个方法的 `httpMethod` + `uri`(已有 `EndpointParser` 逻辑)
|
||||
3. 用**方法指纹**(类文件 + 方法名 + 参数类型签名)匹配新旧接口
|
||||
4. 指纹相同且 URI 不同 → **修改路径**
|
||||
5. 仅旧有新无 → **删除**;仅新有旧无 → **新增**
|
||||
|
||||
## 实现
|
||||
|
||||
- `EndpointSnapshotParser` — 解析快照
|
||||
- `EndpointDiffEngine` — 对比产出 `EndpointChangeReport.is_renamed_endpoint` 等标志
|
||||
- `ApiChangeNotifier.buildPathChangeMarkdown()` — 渲染本模版
|
||||
Reference in New Issue
Block a user