229 lines
11 KiB
Markdown
229 lines
11 KiB
Markdown
# 复盘文档 - 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)
|
||
- 建立数据库字段标准清单,确保所有新表都包含标准字段
|
||
- 在提示词中明确指定需要包含的标准字段
|
||
|
||
### 问题 3:SoapConnection 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)
|