datai/datai-scenes/datai-scene-salesforce/docs/retros/2026-02-06-003-06-retro.md

13 KiB
Raw Blame History

复盘文档 - 检索操作

元数据

  • 需求编号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_retrieve13 个字段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。这种方式既保证了代码的规范性又满足了业务需求。

具体实践

  • 代码生成器生成了 DataiMetadataRetrieve Entity、DataiMetadataRetrieveMapper 等基础代码
  • 手动实现了 RetrieveRequest DTO包含复杂的嵌套结构RetrieveResultVo VO、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 文件处理)

优先级:低 计划时间:技术债清理阶段

问题分析

问题 1DTO 与 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
  • 支持在请求参数中动态指定
  • 添加合理的默认值和校验逻辑

模板迭代

当前模板的不足

经过本次复盘,发现当前的提示词模板在以下方面可以改进:

  1. 异步操作处理:模板中缺少对异步操作特性的明确说明和处理建议
  2. 大文件处理:模板中缺少对大文件处理的指导(如 ZIP 文件、图片等)
  3. 配置参数管理:模板中缺少对配置参数管理的建议(如轮询间隔、超时时间等)

模板更新计划

计划在下一个迭代中更新以下模板:

  1. 更新代码生成提示词模板docs/Prompt/0000-template.md

    • 增加异步操作处理章节
    • 增加大文件处理指导
    • 增加配置参数管理建议
  2. 更新 DTO 设计模板

    • 增加嵌套结构 DTO 的设计示例
    • 增加与外部 API 对象映射的指导
  3. 更新单元测试模板

    • 增加异步操作的测试示例
    • 增加边界场景测试的检查清单

相关文档