13 KiB
复盘文档 - 检索操作
元数据
- 需求编号:003-06
- 创建时间:2026-02-06
- 创建人:AI Assistant
- 状态:已完成
复盘概述
本次复盘对 Salesforce Metadata API 检索操作功能的开发过程进行了全面回顾。从需求定义到变更记录的每个阶段都严格按照 SSOT 流程执行,确保了代码的可追溯性和可维护性。本次开发实现了元数据异步检索、状态轮询、历史查询等功能,支持 ZIP 文件 Base64 编码返回和完整的错误处理机制。
目标与实际产出对比
目标
- 实现元数据检索功能,支持提交检索请求和获取结果
- 正确处理 Salesforce Metadata API 的异步检索流程(提交-轮询-结果)
- 实现数据库持久化,记录检索历史和状态
- 提供完整的 REST API 接口(5 个接口)
- 遵循 SSOT 流程,确保所有开发活动都有文档依据
- 生成符合项目规范的代码,包含单元测试
实际产出
- ✅ 成功实现元数据检索功能,支持提交检索请求
- ✅ 正确处理异步检索流程,实现了状态轮询机制
- ✅ 实现了 ZIP 文件 Base64 编码返回,不存储到数据库
- ✅ 实现了异步日志记录,使用 @Async 注解
- ✅ 提供了 5 个 REST API 接口:
POST /salesforce/metadata/retrieve- 提交检索请求GET /salesforce/metadata/retrieve/status/{asyncId}- 轮询检索状态GET /salesforce/metadata/retrieve/check/{asyncId}- 单次检查状态GET /salesforce/metadata/retrieve/history- 获取检索历史GET /salesforce/metadata/retrieve/record/{asyncId}- 查询检索记录
- ✅ 创建了
datai_metadata_retrieve表(13 个字段,4 个索引) - ✅ 定义了 10 个专用错误码(RETRIEVE_001 ~ RETRIEVE_010)
- ✅ 生成了 15+ 个代码文件(9 个手动 + 6+ 个代码生成器)
- ✅ 编写了 11 个单元测试用例,覆盖成功/失败/轮询/异常场景
- ✅ 严格按照 SSOT 流程执行,每个阶段都有相应的文档
成功经验
1. 异步处理模式的成功应用
经验描述:针对 Salesforce Metadata API 的异步特性,设计了"提交请求-轮询状态-获取结果"的完整流程,确保了异步操作的正确处理。
具体实现:
// 提交检索请求
public AsyncResult retrieveMetadata(RetrieveRequest request) {
MetadataConnection connection = connectionFactory.getConnection("source");
AsyncResult asyncResult = connection.retrieve(sfRequest);
recordRetrieveRequest(asyncResult); // 记录到数据库
return asyncResult;
}
// 轮询状态直到完成
public RetrieveResultVo pollRetrieveResult(String asyncId, long interval, long timeout) {
long startTime = System.currentTimeMillis();
while (System.currentTimeMillis() - startTime < timeout) {
RetrieveResultVo result = checkRetrieveStatus(asyncId);
if (Boolean.TRUE.equals(result.getDone())) {
return result;
}
Thread.sleep(interval);
}
throw new SalesforceOperationException("RETRIEVE_003", "检索操作超时");
}
带来的好处:
- 正确处理 Salesforce 异步 API 的特性
- 提供了灵活的状态查询机制
- 支持超时控制,防止无限等待
2. 代码生成器与手动实现的良好结合
经验描述:在阶段 6 中,先使用代码生成器生成基础 CRUD 代码(Entity、Mapper、基础 Service),然后手动实现业务逻辑代码(DTO、VO、业务 Service、Controller)。这种方式既保证了代码的规范性,又满足了业务需求。
具体实践:
- 代码生成器生成了
DataiMetadataRetrieveEntity、DataiMetadataRetrieveMapper等基础代码 - 手动实现了
RetrieveRequestDTO(包含复杂的嵌套结构)、RetrieveResultVoVO、IMetadataRetrieveService接口和MetadataRetrieveServiceImpl实现 - 手动实现了
MetadataRetrieveController提供 REST API 接口
带来的好处:
- 减少了重复劳动,提高了开发效率
- 保证了基础代码的规范性和一致性
- 业务逻辑代码更加清晰、可维护
3. 复杂 DTO 结构的设计
经验描述:RetrieveRequest DTO 包含了复杂的嵌套结构(Unpackaged、PackageTypeMember),通过合理的设计实现了与 Salesforce API 的映射。
具体实现:
@Data
@Schema(description = "检索请求")
public class RetrieveRequest implements Serializable {
private Double apiVersion;
private Boolean singlePackage;
private Unpackaged unpackaged; // 嵌套结构
private String[] packageNames;
private String[] specificFiles;
@Data
public static class Unpackaged implements Serializable {
private List<PackageTypeMember> types; // 嵌套列表
}
@Data
public static class PackageTypeMember implements Serializable {
private String name;
private String[] members;
}
}
带来的好处:
- 清晰表达了 Salesforce RetrieveRequest 的结构
- 支持复杂的元数据类型配置
- 便于前端理解和使用
4. 完整的错误码体系
经验描述:定义了 10 个专用错误码,覆盖了检索操作的各种异常情况,便于问题定位和错误处理。
错误码设计:
- RETRIEVE_001 ~ RETRIEVE_010:涵盖认证失败、操作失败、超时、参数错误等各种场景
- 每个错误码都有明确的含义和处理建议
- 错误码与异常类型对应,便于统一处理
带来的好处:
- 提高了错误处理的规范性
- 便于前端展示友好的错误信息
- 有利于问题定位和排查
5. 异步日志记录的性能优化
经验描述:使用 Spring 的 @Async 注解实现异步日志记录,避免日志写入阻塞主业务流程,提高了 API 响应速度。
具体实现:
@Async("threadPoolTaskExecutor")
public void recordRetrieveRequestAsync(AsyncResult asyncResult) {
// 异步记录检索历史
}
带来的好处:
- 主业务流程不被日志写入阻塞
- 提高了 API 响应速度
- 解耦了业务逻辑和日志记录
改进点
1. ZIP 文件处理可以更加灵活
问题描述:当前实现将 ZIP 文件内容 Base64 编码后直接返回,对于大文件可能会导致内存问题。
改进建议:
- 考虑支持流式下载,避免内存占用过高
- 可以添加 ZIP 文件大小限制和分片下载支持
- 考虑将大 ZIP 文件临时存储到文件系统或对象存储
优先级:中 计划时间:下一个迭代
2. 检索历史查询可以支持更多筛选条件
问题描述:当前的检索历史查询只支持按数量限制返回,不支持按时间范围、状态等条件筛选。
改进建议:
- 添加时间范围筛选(开始时间、结束时间)
- 添加状态筛选(Pending、InProgress、Succeeded、Failed)
- 添加用户筛选(按操作用户查询)
- 支持分页查询
优先级:中 计划时间:下一个迭代
3. 单元测试可以覆盖更多边界场景
问题描述:当前的单元测试主要覆盖了正常场景和常见异常场景,对于一些边界场景(如超长 asyncId、特殊字符等)覆盖不足。
改进建议:
- 添加边界值测试(如 asyncId 长度限制)
- 添加特殊字符处理测试
- 添加并发场景测试
- 添加性能测试(大 ZIP 文件处理)
优先级:低 计划时间:技术债清理阶段
问题分析
问题 1:DTO 与 Salesforce API 对象的转换逻辑较复杂
问题描述:RetrieveRequest 需要转换为 Salesforce 的 RetrieveRequest 对象,转换逻辑涉及多个字段和嵌套结构,代码较复杂。
根因分析:
- Salesforce API 对象结构复杂
- 需要处理可选字段和默认值
- 嵌套结构的递归转换
解决方案:
- 使用 MapStruct 等映射工具自动生成转换代码
- 将转换逻辑抽取到单独的 Converter 类中
- 添加详细的注释说明每个字段的映射关系
状态:已记录,待下一个迭代优化
问题 2:轮询间隔和超时时间的配置不够灵活
问题描述:当前的轮询间隔和超时时间是硬编码的,无法根据不同场景灵活调整。
根因分析:
- 硬编码参数缺乏灵活性
- 没有考虑不同元数据类型的检索时间差异
解决方案:
- 将轮询间隔和超时时间配置化(application.yml)
- 支持在请求参数中指定超时时间
- 根据元数据类型动态调整超时时间
状态:已记录,待下一个迭代优化
行动计划
| 序号 | 行动项 | 责任人 | 计划时间 | 优先级 |
|---|---|---|---|---|
| 1 | 优化 ZIP 文件处理,支持流式下载 | 开发团队 | 下一个迭代 | 中 |
| 2 | 扩展检索历史查询功能,支持更多筛选条件 | 开发团队 | 下一个迭代 | 中 |
| 3 | 增强单元测试覆盖,添加边界场景测试 | 开发团队 | 技术债清理 | 低 |
| 4 | 使用 MapStruct 优化 DTO 转换逻辑 | 开发团队 | 下一个迭代 | 中 |
| 5 | 将轮询参数配置化,支持动态调整 | 开发团队 | 下一个迭代 | 低 |
提取模式
有效的 Prompt 技巧
1. 引用真源确保一致性
技巧描述:在提示词开头明确引用需求文档、设计文档、ADR 文档等真源,确保生成的代码符合需求和设计要求。
应用示例:
请基于以下真源文档实现检索操作功能:
- 需求文档:docs/requirements/sub/2026-01-28-003-06-检索操作.md
- 设计文档:docs/design/2026-02-03-003-06-检索操作-设计.md
- ADR 文档:docs/decisions/2026-02-03-003-06-ADR-检索操作技术选型.md
效果:
- 生成的代码符合需求和设计要求
- 减少了返工和修改的次数
- 提高了代码的准确性和一致性
2. 详细的输出格式要求
技巧描述:在提示词中明确指定需要生成的文件、路径、格式等,可以提高生成代码的准确性和规范性。
应用示例:
请生成以下代码文件:
1. RetrieveRequest.java - 位于 model/dto/ 包下,包含 Unpackaged 和 PackageTypeMember 内部类
2. RetrieveResultVo.java - 位于 model/vo/ 包下,包含 fromSalesforceResult 转换方法
3. IMetadataRetrieveService.java - 位于 service/ 包下,定义 retrieveMetadata、pollRetrieveResult、checkRetrieveStatus 等方法
效果:
- 生成的代码结构清晰、规范
- 减少了手动调整的工作量
- 提高了代码的可维护性
3. 分步骤生成复杂代码
技巧描述:对于复杂的业务逻辑,分步骤生成代码,先生成接口和 DTO,再生成实现类,最后生成单元测试。
应用示例:
第一步:生成 DTO 和 VO 类
第二步:生成 Service 接口
第三步:生成 Service 实现类
第四步:生成 Controller 类
第五步:生成单元测试类
效果:
- 每个步骤的代码更加聚焦和清晰
- 便于逐步验证和调整
- 减少了整体出错的可能性
避免的坑
1. 不要忽略异步操作的特性
坑描述:Salesforce Metadata API 的检索操作是异步的,如果忽略这一点,可能会导致状态查询失败或结果获取不完整。
避免方法:
- 在需求分析阶段明确识别异步操作特性
- 设计完整的状态轮询机制
- 添加超时控制和错误处理
2. 不要在数据库中存储大文件内容
坑描述:将 ZIP 文件内容存储到数据库中会导致数据库性能问题和存储空间浪费。
避免方法:
- 在 ADR 阶段明确决策不存储 ZIP 文件到数据库
- 使用 Base64 编码在 API 响应中返回
- 考虑使用对象存储或文件系统存储大文件
3. 不要硬编码配置参数
坑描述:硬编码轮询间隔、超时时间等参数会导致系统缺乏灵活性,无法适应不同场景。
避免方法:
- 将配置参数抽取到 application.yml
- 支持在请求参数中动态指定
- 添加合理的默认值和校验逻辑
模板迭代
当前模板的不足
经过本次复盘,发现当前的提示词模板在以下方面可以改进:
- 异步操作处理:模板中缺少对异步操作特性的明确说明和处理建议
- 大文件处理:模板中缺少对大文件处理的指导(如 ZIP 文件、图片等)
- 配置参数管理:模板中缺少对配置参数管理的建议(如轮询间隔、超时时间等)
模板更新计划
计划在下一个迭代中更新以下模板:
-
更新代码生成提示词模板(
docs/Prompt/0000-template.md):- 增加异步操作处理章节
- 增加大文件处理指导
- 增加配置参数管理建议
-
更新 DTO 设计模板:
- 增加嵌套结构 DTO 的设计示例
- 增加与外部 API 对象映射的指导
-
更新单元测试模板:
- 增加异步操作的测试示例
- 增加边界场景测试的检查清单