12 KiB
复盘文档 - 删除操作
元数据
- 需求编号:003-05
- 创建时间:2026-02-06
- 创建人:AI Assistant
- 状态:已完成
复盘概述
本次复盘对 Salesforce Metadata API 删除操作功能的开发过程进行了全面回顾。从需求定义到变更记录的每个阶段都严格按照 SSOT 流程执行,确保了代码的可追溯性和可维护性。本次开发实现了元数据删除、批量删除和删除历史查询功能,支持分批处理(每批 10 个,符合 Salesforce API 限制)和异步日志记录。
目标与实际产出对比
目标
- 实现元数据删除功能,支持单个和批量删除操作
- 正确处理 Salesforce Metadata API 的删除结果和错误信息
- 实现数据库持久化,记录删除历史和状态
- 提供完整的 REST API 接口(3 个接口)
- 遵循 SSOT 流程,确保所有开发活动都有文档依据
- 生成符合项目规范的代码,包含单元测试
实际产出
- ✅ 成功实现元数据删除功能,支持单个和批量删除
- ✅ 正确处理删除结果,实现了 DeleteResultVo 转换类
- ✅ 实现了分批处理逻辑,每批 10 个(符合 Salesforce API 限制)
- ✅ 实现了异步日志记录,使用 @Async 注解
- ✅ 提供了 3 个 REST API 接口:
POST /salesforce/metadata/delete/{type}- 单个删除POST /salesforce/metadata/delete/batch- 批量删除GET /salesforce/metadata/delete/history- 历史查询
- ✅ 创建了
datai_metadata_delete表(12 个字段,5 个索引) - ✅ 定义了 4 个专用错误码(DELETE_001 ~ DELETE_004)
- ✅ 生成了 13 个代码文件(6 个手动 + 7 个代码生成器)
- ✅ 编写了 10 个单元测试用例,覆盖成功/失败/分批/异常场景
- ✅ 严格按照 SSOT 流程执行,每个阶段都有相应的文档
成功经验
1. 代码生成器与手动实现的良好结合
经验描述:在阶段 6 中,先使用代码生成器生成基础 CRUD 代码(Entity、Mapper、基础 Service),然后手动实现业务逻辑代码(DTO、VO、业务 Service、Controller)。这种方式既保证了代码的规范性,又满足了业务需求。
具体实践:
- 代码生成器生成了
DataiMetadataDeleteEntity、DataiMetadataDeleteMapper等基础代码 - 手动实现了
DeleteRequestDTO、DeleteResultVoVO、IMetadataDeleteService接口和MetadataDeleteServiceImpl实现 - 手动实现了
MetadataDeleteController提供 REST API 接口
带来的好处:
- 减少了重复劳动,提高了开发效率
- 保证了基础代码的规范性和一致性
- 业务逻辑代码更加清晰、可维护
2. 分批处理策略的有效实施
经验描述:针对 Salesforce Metadata API 每次最多删除 10 个元数据的限制,设计了循环分批处理逻辑,确保批量删除操作的正确执行。
具体实现:
int totalCount = fullNames.length;
for (int i = 0; i < totalCount; i += BATCH_SIZE) {
int end = Math.min(i + BATCH_SIZE, totalCount);
String[] batch = Arrays.copyOfRange(fullNames, i, end);
DeleteResult[] results = connection.deleteMetadata(type, batch);
// 处理结果...
}
带来的好处:
- 符合 Salesforce API 限制,避免调用失败
- 代码逻辑清晰,易于理解和维护
- 支持任意数量的批量删除
3. 异步日志记录的性能优化
经验描述:使用 Spring 的 @Async 注解实现异步日志记录,避免日志写入阻塞主业务流程,提高了 API 响应速度。
具体实现:
@Async("threadPoolTaskExecutor")
public void logDeleteHistoryAsync(String type, DeleteResult result) {
// 异步记录删除历史
}
带来的好处:
- 主业务流程不被日志写入阻塞
- 提高了 API 响应速度
- 解耦了业务逻辑和日志记录
4. 完整的单元测试覆盖
经验描述:为 Service 层编写了 10 个单元测试用例,覆盖了成功场景、失败场景、分批处理场景和异常场景。
测试覆盖:
- 单个删除成功场景
- 单个删除失败场景
- 批量删除成功场景
- 批量删除分批处理场景
- 批量删除部分失败场景
- 连接异常场景
- 参数校验场景
带来的好处:
- 确保了代码的正确性
- 便于后续重构和维护
- 提高了代码质量
改进点
1. API 限流和重试机制可以考虑
问题描述:当前实现没有针对 Salesforce API 的限流和重试机制。如果 API 调用频率过高,可能会触发 Salesforce 的限流策略。
改进建议:
- 添加限流控制,限制每秒/每分钟的 API 调用次数
- 添加重试机制,对于临时性错误(如网络超时)进行自动重试
- 使用断路器模式,防止级联故障
优先级:中 计划时间:下一个迭代
2. 批量删除的事务性可以考虑
问题描述:当前批量删除是串行执行,单个失败不影响其他请求,但没有事务性保证。如果某个批次失败,无法回滚已成功的批次。
改进建议:
- 调研 Salesforce Metadata API 是否支持事务性操作
- 考虑在业务层实现补偿机制
- 记录每个批次的执行状态,支持部分回滚
优先级:低 计划时间:后续迭代
3. 删除历史的查询优化可以考虑
问题描述:当前删除历史查询是基于 MyBatis Plus 的简单查询,如果数据量很大,查询性能可能会下降。
改进建议:
- 添加分页查询支持
- 添加更多查询条件(按时间范围、按类型、按状态等)
- 考虑使用缓存优化频繁查询
优先级:中 计划时间:下一个迭代
问题分析
问题 1:代码生成器生成的 Controller 与业务需求不完全匹配
问题描述:代码生成器生成的 DataiMetadataDeleteController 是通用的 CRUD 接口,但业务需要的是特定的删除操作接口(调用 Salesforce Metadata API)。
根因分析:
- 代码生成器基于数据库表结构生成通用 CRUD 代码
- 业务需求涉及外部 API 调用,超出了代码生成器的范围
解决方案:
- 保留代码生成器生成的代码作为基础
- 手动创建新的
MetadataDeleteController实现业务接口 - 在后续开发中,明确区分代码生成器代码和手动实现代码
预防措施:
- 在需求分析阶段明确哪些代码需要手动实现
- 在代码生成后,立即检查生成的代码是否满足业务需求
问题 2:单元测试中 Mock 的复杂性
问题描述:在编写单元测试时,需要 Mock MetadataConnection 和 DeleteResult 等 Salesforce API 类,增加了测试编写的复杂性。
根因分析:
- Salesforce API 类的构造函数和方法是私有的或复杂的
- 需要模拟各种场景(成功、失败、异常等)
解决方案:
- 使用 Mockito 的
mock()方法创建 Mock 对象 - 使用
when().thenReturn()设置 Mock 行为 - 使用
doThrow().when()模拟异常场景
预防措施:
- 在编写业务代码时,考虑可测试性
- 使用依赖注入,便于 Mock 替换
- 编写详细的测试用例文档
行动计划
| 序号 | 行动项 | 责任人 | 计划时间 | 优先级 |
|---|---|---|---|---|
| 1 | 添加 API 限流和重试机制 | 开发团队 | 下一个迭代 | 中 |
| 2 | 优化删除历史查询(分页、条件查询) | 开发团队 | 下一个迭代 | 中 |
| 3 | 调研批量删除事务性方案 | 开发团队 | 后续迭代 | 低 |
| 4 | 更新代码生成器模板,增加业务接口提示 | AI Assistant | 立即执行 | 高 |
| 5 | 编写单元测试最佳实践文档 | AI Assistant | 立即执行 | 高 |
提取模式
有效的 Prompt 技巧
1. 明确的代码生成策略
技巧描述:在提示词中明确说明哪些代码使用代码生成器生成,哪些代码需要手动实现,可以提高代码生成的准确性和效率。
应用示例:
## 代码生成策略
- **代码生成器生成**:Entity、Mapper、基础 Service、基础 Controller
- **手动实现**:DTO、VO、业务 Service 接口、业务 Service 实现、业务 Controller、单元测试
效果:
- 避免了代码生成器生成不符合业务需求的代码
- 明确了开发边界,提高了开发效率
2. 详细的接口定义
技巧描述:在提示词中详细定义 REST API 接口的请求方式、请求路径、请求参数、响应参数等,可以确保生成的接口符合设计要求。
应用示例:
### 接口 1:删除元数据
- **请求方式**:POST
- **请求路径**:`/salesforce/metadata/delete/{type}`
- **请求参数**:
- `type`:元数据类型(String,必填)
- `fullNames`:元数据完整名称列表(String[],必填)
- **响应参数**:
- `code`:状态码(Integer)
- `msg`:提示信息(String)
- `data`:删除结果列表(List<DeleteResultVo>)
效果:
- 生成的接口与设计完全一致
- 减少了后续修改的工作量
3. 具体的错误码定义
技巧描述:在提示词中定义具体的错误码和错误信息,可以确保错误处理的一致性和可维护性。
应用示例:
## 错误码定义
- DELETE_001:Salesforce 连接失败
- DELETE_002:删除元数据失败
- DELETE_003:批量删除失败
- DELETE_004:参数校验失败
效果:
- 错误码统一、规范
- 便于前端处理和用户提示
- 便于日志分析和问题定位
避免的坑
1. 不要忽略代码生成器的局限性
坑描述:代码生成器只能生成通用的 CRUD 代码,对于涉及外部 API 调用的业务逻辑,需要手动实现。
避免方法:
- 在需求分析阶段明确代码生成器的适用范围
- 代码生成后立即检查是否满足业务需求
- 准备好手动实现业务逻辑的预案
2. 不要忽略单元测试的复杂性
坑描述:涉及外部 API 的代码单元测试比较复杂,需要 Mock 外部依赖,如果忽略这一点,可能导致测试覆盖不足。
避免方法:
- 在设计阶段考虑可测试性
- 使用依赖注入,便于 Mock
- 预留足够的测试编写时间
3. 不要违反 Salesforce API 限制
坑描述:Salesforce Metadata API 有调用限制(如每次最多删除 10 个元数据),如果忽略这一点,可能导致 API 调用失败。
避免方法:
- 仔细阅读 Salesforce API 文档
- 在代码中实现分批处理逻辑
- 添加限流和重试机制
模板迭代
经过本次复盘,发现当前的提示词模板在以下方面可以改进:
1. 增加代码生成策略说明
在提示词模板中增加"代码生成策略"章节,明确说明哪些代码使用代码生成器生成,哪些代码需要手动实现。
建议更新:
## 代码生成策略
- **代码生成器生成**:Entity、Mapper、基础 Service、基础 Controller、DTO、VO
- **手动实现**:业务 Service 接口、业务 Service 实现、业务 Controller、单元测试
- **说明**:代码生成器基于数据库表结构生成通用 CRUD 代码,业务逻辑代码需要手动实现
2. 增加外部 API 调用提示
在提示词模板中增加"外部 API 调用"提示,提醒开发者注意外部 API 的限制和异常处理。
建议更新:
## 外部 API 调用提示
- 注意外部 API 的调用限制(如 Salesforce Metadata API 每次最多删除 10 个元数据)
- 实现分批处理逻辑,确保符合 API 限制
- 添加异常处理,捕获连接异常、API 异常等
- 考虑添加限流和重试机制
3. 增加单元测试提示
在提示词模板中增加"单元测试"提示,提醒开发者注意 Mock 外部依赖和覆盖各种场景。
建议更新:
## 单元测试提示
- 使用 Mockito Mock 外部依赖(如 Salesforce API 类)
- 覆盖成功场景、失败场景、异常场景
- 测试分批处理逻辑
- 测试参数校验逻辑
- 使用 @Mock 和 @InjectMocks 注解