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

229 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 复盘文档 - 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 的 `QueryWrapper``insert()` 方法,但项目实际使用的是标准 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
- 是否建立了适当的索引
- 是否符合命名规范(表名、字段名)
## 相关文档
- [需求文档](../requirements/sub/2026-01-28-002-02-Apex代码编译和执行.md)
- [设计文档](../design/2026-02-02-002-02-Apex代码编译和执行-设计.md)
- [决策记录](../decisions/2026-02-02-002-02-ADR-Apex代码编译和执行技术选型.md)
- [SQL 脚本](../sql/2026-02-02-002-02-Apex代码编译和执行.sql)
- [提示词文档](../prompts/2026-02-02-002-02-prompt-Apex代码编译和执行.md)
- [变更日志](../changelog/2026-02-02-002-02-changelog.md)
- [会话记录](../sessions/2026-02-02-002-02-session.md)