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

11 KiB
Raw Permalink Blame History

复盘文档 - Apex 代码编译和执行

元数据

  • 需求编号002-02
  • 需求名称Apex 代码编译和执行
  • 创建时间2026-02-02
  • 创建人AI Assistant
  • 状态:已完成

复盘概述

本次复盘对 Apex 代码编译和执行功能的开发过程进行了全面回顾,从需求定义到变更日志的每个阶段都进行了分析,总结了成功经验、改进点、问题分析和行动计划,旨在提高后续开发过程的效率和质量。

目标与实际产出对比

目标

  • 实现 Apex 代码编译和执行功能,包括编译 Apex 类、编译 Apex 触发器、编译并测试、执行匿名 Apex 代码
  • 提供查询编译历史、测试结果、代码覆盖率等辅助功能
  • 遵循 SSOT 流程,确保所有开发活动都有文档依据
  • 生成符合项目规范的代码,支持多线程安全和数据一致性
  • 创建 4 张数据库表用于存储编译历史、测试结果、测试失败详情和代码覆盖率

实际产出

  • 成功实现了所有核心功能compileClasses、compileTriggers、compileAndTest、executeAnonymous
  • 提供了完整的查询功能queryCompileHistory、queryTestResults、queryCodeCoverage
  • 严格按照 SSOT 流程执行每个阶段都有相应的文档需求、设计、ADR、SQL、提示词、变更日志
  • 生成的代码符合项目规范,使用 ReentrantLock 保证多线程安全,使用 @Transactional 保证数据一致性
  • 创建了 4 张数据库表包含标准字段dept_id、create_by、create_time、update_by、update_time
  • 生成了 29 个代码文件Controller 3个、Service 2个、DTO 5个、VO 7个、Entity 4个、Mapper 4个、基础 Service/Controller 4个
  • 提供了 7 个 REST API 接口,支持外部调用

成功经验

1. SSOT 流程的严格执行

从需求定义到变更日志的每个阶段都严格按照项目规则执行,确保了所有开发活动都有文档依据。每个阶段的文档都包含了详细的元数据、内容和相关链接,提高了代码的可追溯性和可维护性。

具体做法

  • 每个阶段都创建了标准化的文档
  • 文档命名遵循 YYYY-MM-DD-00X-功能名.md 格式
  • 及时更新索引和需求文档,确保文档之间的引用关系正确

2. 详细的提示词设计

阶段 5 生成的提示词包含了详细的输出格式要求、代码规范要求和测试要求,确保了生成的代码符合项目规范和需求。提示词中引用了需求文档、设计文档、决策记录和 SQL 脚本等真源,确保了代码生成的准确性。

具体做法

  • 提示词开头明确引用真源文档
  • 详细描述每个需要生成的文件及其路径
  • 明确指定代码规范、命名规范、注释规范
  • 包含测试要求(覆盖率不低于 80%

3. 完整的数据库设计

在阶段 4 中,根据用户反馈及时更新了 SQL 脚本为所有表添加了标准字段dept_id、create_by、create_time、update_by、update_time。这确保了数据库表结构符合项目规范支持多租户和审计功能。

具体做法

  • 参考项目现有 SQL 脚本确定标准字段
  • 及时响应用户反馈,更新 SQL 脚本
  • 确保所有表结构一致,便于后续维护

4. 合理的架构决策

在阶段 3 中,通过 ADR 文档记录了关键的技术选型决策:

  • 选择数据库持久化而非内存缓存,确保数据可靠性和审计能力
  • 选择直接使用 apex.jar 原生类而非二次封装,减少代码复杂度
  • 选择 ReentrantLock 而非 synchronized提供更好的灵活性和性能
  • 选择 4 张独立表而非单表存储,确保数据结构的清晰和查询效率

具体做法

  • 分析至少两种技术方案
  • 对比各方案的优缺点
  • 记录决策理由和后续行动

改进点

1. 代码生成前的依赖检查可以更完善

在阶段 6 生成代码时,发现 ApexCompileServiceImpl.java 存在编译错误,主要原因是:

  • 使用了 MyBatis Plus 的 QueryWrapperinsert() 方法,但项目实际使用的是标准 MyBatis
  • 方法签名与 Salesforce API 的实际方法不匹配(如 getProblemType() 应为 getProblem()
  • 异常声明在接口和实现类之间不一致

改进建议

  • 在生成代码前扫描项目现有代码确认使用的持久层框架MyBatis vs MyBatis Plus
  • 扫描 Salesforce API 源代码,确认方法签名和返回值
  • 在提示词中明确指定持久层框架和版本

2. 异常处理可以更统一

在修复编译错误的过程中,发现异常处理存在以下问题:

  • 部分方法没有声明 throws 子句
  • 接口和实现类的异常声明不一致
  • 部分异常类型使用不当

改进建议

  • 在 Service 接口中统一声明异常SalesforceAuthException、SalesforceOperationException
  • 确保接口和实现类的异常声明完全一致
  • 在提示词中明确指定异常处理规范

3. API 文档可以更早生成

目前的流程是在阶段 9 生成 API 文档,但 API 文档的内容实际上在阶段 2设计和阶段 6代码生成时就已经确定了。如果可以更早生成 API 文档,可以在代码生成前就发现接口设计的问题。

改进建议

  • 考虑在阶段 2设计或阶段 6代码生成后生成初版 API 文档
  • 在阶段 9 对 API 文档进行完善和确认
  • 探索使用 Swagger 注解自动生成 API 文档

问题分析

问题 1编译错误修复耗时较长

现象:在阶段 6 生成代码后,发现了大量编译错误,包括:

  • MyBatis Plus 方法不存在selectList、insert 等)
  • Salesforce API 方法不存在getProblemType、getLog 等)
  • 异常声明不匹配
  • 类型转换错误Long 转 String

根因

  • 提示词中没有明确指定持久层框架类型
  • 没有扫描 Salesforce API 源代码确认方法签名
  • 代码生成后没有立即进行编译验证

解决方案

  • 在提示词中明确指定使用标准 MyBatis 而非 MyBatis Plus
  • 在生成代码前扫描 Salesforce API 源代码,确认方法签名
  • 代码生成后立即执行编译验证,及时发现和修复问题

问题 2数据库字段标准不一致

现象:在阶段 4 生成 SQL 脚本后用户指出缺少标准字段dept_id、create_by 等)。

根因

  • 没有提前参考项目现有的 SQL 脚本确定标准字段
  • 对项目的数据库规范了解不够深入

解决方案

  • 在生成 SQL 脚本前,参考项目现有的 SQL 脚本(如 datai_config_audit.sql
  • 建立数据库字段标准清单,确保所有新表都包含标准字段
  • 在提示词中明确指定需要包含的标准字段

问题 3SoapConnection API 方法调用错误

现象:在 ApexConnectionServiceImpl.java 中,方法调用与 SoapConnection API 的实际方法不匹配:

  • setSessionHeader(SessionHeader_element) 应为 setSessionHeader(String sessionId)
  • setCallOptions(CallOptions_element) 应为 setCallOptions(String client)
  • setDebuggingHeader(DebuggingHeader_element) 应为 setDebuggingHeader(LogInfo[] categories, LogType debugLevel)

根因

  • 没有详细扫描 SoapConnection 源代码确认方法签名
  • 假设了方法参数类型,与实际 API 不符

解决方案

  • 在生成代码前,详细扫描 SoapConnection 源代码
  • 确认每个方法的参数类型和返回值
  • 在提示词中引用 SoapConnection 源代码作为真源

行动计划

序号 行动项 责任人 时间节点 优先级
1 在提示词中明确指定持久层框架类型MyBatis vs MyBatis Plus AI Assistant 立即执行
2 建立数据库字段标准清单包含所有标准字段dept_id、create_by 等) AI Assistant 立即执行
3 在生成代码前扫描 Salesforce API 源代码,确认方法签名 AI Assistant 立即执行
4 代码生成后立即执行编译验证,及时发现和修复问题 AI Assistant 立即执行
5 统一 Service 接口和实现类的异常声明 AI Assistant 立即执行
6 探索使用 Swagger 注解自动生成 API 文档 项目团队 下一个迭代

提取模式

有效的 Prompt 技巧

  1. 引用真源文档

    • 在提示词开头明确引用需求文档、设计文档、决策记录等真源
    • 使用相对路径或绝对路径,确保 AI 可以准确定位文档
    • 示例:基于需求文档 [需求文档](../requirements/2026-01-28-002-02-Apex代码编译和执行.md)
  2. 明确指定技术栈和版本

    • 在提示词中明确指定使用的框架和版本(如 MyBatis 而非 MyBatis Plus
    • 明确指定依赖库的版本(如 apex.jar 的版本)
    • 示例:使用标准 MyBatis 进行数据库操作,不要使用 MyBatis Plus
  3. 详细的输出格式要求

    • 明确列出需要生成的文件清单,包括文件名和路径
    • 明确指定每个文件的类名、方法名、参数类型、返回值类型
    • 示例:- ApexCompileController.java - 编译相关接口路径src/main/java/com/datai/apex/controller/

避免的坑

  1. 不要假设 API 方法签名

    • 不要根据方法名猜测参数类型和返回值
    • 必须扫描源代码确认方法签名
    • 反例:假设 setSessionHeader 接受 SessionHeader_element 对象,实际接受 String sessionId
  2. 不要忽略项目规范

    • 不要忽略项目的数据库规范(如标准字段)
    • 不要忽略项目的代码规范(如异常处理、日志记录)
    • 反例:生成的 SQL 脚本缺少 dept_id、create_by 等标准字段
  3. 不要延迟编译验证

    • 代码生成后应立即进行编译验证
    • 不要等待所有代码生成后再进行验证
    • 反例:生成所有代码后才发现大量编译错误,修复耗时较长

模板迭代

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

1. 增加技术栈确认章节

在提示词模板中增加一个章节,明确要求确认以下技术栈:

  • 持久层框架MyBatis / MyBatis Plus / JPA
  • 数据库类型MySQL / PostgreSQL / Oracle
  • 缓存框架Redis / Caffeine / 无
  • 其他关键依赖库的版本

2. 增加 API 扫描要求

在提示词模板中增加一个章节,要求扫描外部 API 源代码:

  • 列出需要扫描的 API 类和方法
  • 确认方法签名(参数类型、返回值类型)
  • 引用扫描结果作为代码生成的依据

3. 增加数据库规范检查清单

在提示词模板中增加一个数据库规范检查清单:

  • 是否包含标准字段dept_id、create_by、create_time、update_by、update_time
  • 是否包含软删除字段del_flag
  • 是否建立了适当的索引
  • 是否符合命名规范(表名、字段名)

相关文档