供应商订单安全对账实现提示词
供应商订单安全对账实现提示词
将本文件全文交给负责实现的 AI。它应在仓库根目录工作,完成代码、测试和交付文档,而不是只输出方案。
角色与目标
你是一名负责酒店 B2B 订单安全的 Java 后端工程师。请完成或审计现有 BookingReconciliationService,确保供应商建单结果不确定、事件重复、事件乱序或供应商数据冲突时,不会导致重复下单或静默覆盖,并产出稳定、可解释的决策。
最终必须交付可运行代码、通过的测试以及完成后的 README.md、DECISIONS.md、AI_USAGE.md。
工作方式
- 先读取根目录
AGENTS.md,按其中要求设置 PowerShell UTF-8 字符集并执行公共门禁。 - 本任务属于完整后端实现,读取
.project/rules/backend/00-index.md后,按索引加载01-foundation.md至06-testing-delivery.md。 - 完整阅读
CANDIDATE_TASK.md、当前服务、全部模型、测试、backend/pom.xml和三份交付文档。 - 当前源码可能已经有部分或完整实现。先运行
mvn -f backend/pom.xml test建立基线,不要假设 starter 仍为空,也不要重写已经正确的代码。 - 对照本提示词和项目规则做差距审计。只有测试能证明行为缺失或错误时才修改代码;不要为了“更像架构”做重构。
- 完成实现、补齐有价值的测试和文档,再运行完整 Maven 测试。
- 不要停在分析或计划阶段,持续完成到所有门禁通过;若确实阻塞,明确报告阻塞事实和已验证内容。
当前仓库基线
- 后端模块:
backend/。 - 技术栈:Java 17、Maven、JUnit 5。
- 根包:
com.shgalaxy.assessment。 - 领域模型:
backend/src/main/java/com/shgalaxy/assessment/model/。 - 决策服务:
backend/src/main/java/com/shgalaxy/assessment/service/BookingReconciliationService.java。 - 测试:
backend/src/test/java/com/shgalaxy/assessment/service/BookingReconciliationServiceTest.java。 - 服务是纯决策逻辑,不需要数据库、网络、消息队列或外部 API。
- 最近一次基线检查为 12 个测试通过,但该结果不是完成证明;执行任务时必须重新运行。
README.md、DECISIONS.md、AI_USAGE.md仍可能保留 starter 内容或TODO,必须以实际代码为准完成。
功能规划
阶段 1:锁定安全不变量
先用现有测试或新增测试固定以下规则:
- “没有收到成功响应”不等于“供应商没有创建订单”。
- 只有
EXPLICIT_REJECT且errorCode精确等于NO_INVENTORY_NO_BOOKING_CREATED时,safeToCreateAgain才能为true。 - 其他所有路径,包括超时、500、断网、未知拒绝、查询无结果和人工审核,
safeToCreateAgain必须为false。 - 已保存的供应商订单号或确认号与新结果冲突时,不覆盖本地值,进入
MANUAL_REVIEW。 - 多匹配不自动选第一条;未知、矛盾或关键字段缺失时采用人工审核这一安全默认值。
阶段 2:完成 afterCreate
按以下行为审计并补齐:
| 输入 | 预期决策 |
|---|---|
SUCCESS 且订单号、确认号完整,无冲突 |
CONFIRMED + SYNC_CONFIRMED,回填两个标识,禁止重建 |
SUCCESS 但标识缺失 |
MANUAL_REVIEW + CONFIRMED_RESULT_INCOMPLETE,不部分回填 |
SUCCESS 与本地标识冲突 |
MANUAL_REVIEW + SUPPLIER_IDENTIFIER_CONFLICT |
| 白名单明确拒绝 | FAILED_FINAL + MARK_FAILED + safeToCreateAgain=true |
| 其他明确拒绝 | PENDING_RECONCILIATION + QUERY_BY_CLIENT_REFERENCE |
TIMEOUT、HTTP_5XX、NETWORK_ERROR |
PENDING_RECONCILIATION + QUERY_BY_CLIENT_REFERENCE |
需要立即查询时使用传入的 now 作为 nextCheckAt,不要调用系统时钟。
阶段 3:完成 afterQuery
查询处理先看匹配数量,再看唯一结果状态:
| 输入 | 预期决策 |
|---|---|
| 多条匹配 | MANUAL_REVIEW + MULTIPLE_SUPPLIER_BOOKINGS,message 明确重复订单风险 |
唯一 CONFIRMED 且标识完整、无冲突 |
CONFIRMED + SYNC_CONFIRMED,安全回填 |
唯一 PENDING 且未达上限 |
PENDING_RECONCILIATION + RETRY_QUERY_LATER,nextCheckAt=now+retryDelay |
唯一 PENDING 且本次达到上限 |
MANUAL_REVIEW + QUERY_ATTEMPTS_EXHAUSTED |
唯一 FAILED 或 CANCELLED |
MANUAL_REVIEW + SUPPLIER_TERMINAL_STATUS_REVIEW |
| 零匹配或查询错误,未达上限 | 保持待对账并延迟重试 |
| 零匹配或查询错误,本次达到上限 | MANUAL_REVIEW + QUERY_ATTEMPTS_EXHAUSTED |
| 唯一结果与本地标识冲突 | MANUAL_REVIEW + SUPPLIER_IDENTIFIER_CONFLICT,不覆盖 |
查询次数语义固定为:reconciliationAttempts 是本次查询前的已完成次数;处理本次后按 attempts + 1 >= maxQueryAttempts 判断是否耗尽。默认上限为 3、重试间隔为 5 分钟。
阶段 4:幂等、乱序和终态
- 相同输入必须产生内容相同的决策,不使用随机数、系统当前时间或进程内事件集合。
- 已确认订单收到相同订单号和确认号:
NOOP+ALREADY_CONFIRMED。 - 已确认订单收到不同订单号或确认号:进入人工审核。
- 已确认订单收到更旧的同订单
PENDING:NOOP+STALE_EVENT_IGNORED,不得降级。 - 已确认订单收到更新或同时发生的矛盾状态:进入人工审核,不自动降级。
- 标识冲突优先于乱序忽略;旧事件中的另一张供应商订单仍是风险证据。
MANUAL_REVIEW为粘性状态,自动事件不得使其退出。FAILED_FINAL重复收到同类白名单拒绝可以NOOP;后续出现供应商订单证据必须人工审核。
阶段 5:校验与异常处理
区分调用契约错误和供应商业务数据异常:
order、result、now为null,订单主键/状态/更新时间无效,查询次数为负,或服务配置非法:抛带明确参数名的IllegalArgumentException。- 事件缺少
eventId、clientReference、occurredAt,引用不一致,匹配缺少订单号/状态,或确认结果缺少确认号:返回MANUAL_REVIEW,不要抛异常。 - 查询同时返回一条匹配和错误码:
QUERY_RESULT_CONFLICT。 - 查询返回多条匹配时,即使同时带错误码,也优先报告
MULTIPLE_SUPPLIER_BOOKINGS。 - 不吞
RuntimeException,不使用异常推动正常业务状态,不创建自定义异常层级。
阶段 6:完成测试与交付
先盘点现有测试,不为凑数量复制场景。针对尚未覆盖的高风险分支补最小测试,重点检查:
HTTP_5XX、NETWORK_ERROR和非白名单拒绝。- 已确认订单收到不同供应商订单号或确认号。
- 唯一
PENDING、CANCELLED和查询错误。 clientReference不匹配、查询结果自相矛盾、构造参数与入口契约错误。MANUAL_REVIEW粘性、FAILED_FINAL后出现供应商订单证据。
每个决策测试除状态和动作外,还应按场景断言 safeToCreateAgain、reasonCode、回填字段和 nextCheckAt。不要测试私有方法。
更新交付文档:
README.md:使用mvn -f backend/pom.xml test,说明核心设计、运行方式、已知限制和生产化缺口;删除 starter 中“服务未实现”的描述。DECISIONS.md:在建议的 800 字内回答核心风险、状态转移、唯一允许重建条件、人工处理条件,以及生产环境的持久化、并发/锁、消息去重和可观测性方案。AI_USAGE.md:在建议的 500 字内如实记录实际使用的 AI、参与环节、验证方法和产品边界。
实现约束
- 保持
BookingReconciliationService.afterCreate(...)和afterQuery(...)两个入口。 - 优先保留现有
record、enum和包结构;现有状态和动作足够时不要新增。 - 使用 JDK 标准库,不新增依赖,不引入 Spring、Lombok 或状态机框架。
- 可用少量私有辅助方法统一构造决策,但不要创建接口、工厂、仓储层或生产基础设施。
- 前端、数据库、HTTP API、消息队列、分布式锁和监控实现不在本次范围;只在
DECISIONS.md说明生产方案。 - 当前没有外部接口,因此
traceId接口门禁不适用;不要为了满足该门禁凭空新增接口。 - 保留用户已有改动,不做无关格式化或重构。
完成门禁
提交结果前逐项确认:
mvn -f backend/pom.xml test全部通过,报告测试数量和结果。- 只有白名单明确拒绝允许再次创建供应商订单。
- 多匹配、冲突、无结果耗尽、异常数据均不会静默覆盖或自动重建。
- 重复事件和旧事件不会让已确认订单降级。
- 所有决策包含稳定原因码和非空排查消息;需要查询时包含正确的
nextCheckAt。 README.md、DECISIONS.md、AI_USAGE.md无未说明的TODO,且与代码一致。- 没有新增不需要的依赖、分层或基础设施。
最终回复格式
完成后只报告:
- 修改了哪些行为和文件。
- 执行了什么验证,测试数量及结果。
- 仍未实现但已在文档说明的生产化事项。
不要粘贴整份源码,不要声称未执行的检查已经通过。