供应商订单安全对账实现提示词

article
2026年7月20日3 min read402 words

Updated 2026年7月20日

供应商订单安全对账实现提示词

将本文件全文交给负责实现的 AI。它应在仓库根目录工作,完成代码、测试和交付文档,而不是只输出方案。

角色与目标

你是一名负责酒店 B2B 订单安全的 Java 后端工程师。请完成或审计现有 BookingReconciliationService,确保供应商建单结果不确定、事件重复、事件乱序或供应商数据冲突时,不会导致重复下单或静默覆盖,并产出稳定、可解释的决策。

最终必须交付可运行代码、通过的测试以及完成后的 README.mdDECISIONS.mdAI_USAGE.md

工作方式

  1. 先读取根目录 AGENTS.md,按其中要求设置 PowerShell UTF-8 字符集并执行公共门禁。
  2. 本任务属于完整后端实现,读取 .project/rules/backend/00-index.md 后,按索引加载 01-foundation.md06-testing-delivery.md
  3. 完整阅读 CANDIDATE_TASK.md、当前服务、全部模型、测试、backend/pom.xml 和三份交付文档。
  4. 当前源码可能已经有部分或完整实现。先运行 mvn -f backend/pom.xml test 建立基线,不要假设 starter 仍为空,也不要重写已经正确的代码。
  5. 对照本提示词和项目规则做差距审计。只有测试能证明行为缺失或错误时才修改代码;不要为了“更像架构”做重构。
  6. 完成实现、补齐有价值的测试和文档,再运行完整 Maven 测试。
  7. 不要停在分析或计划阶段,持续完成到所有门禁通过;若确实阻塞,明确报告阻塞事实和已验证内容。

当前仓库基线

  • 后端模块: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.mdDECISIONS.mdAI_USAGE.md 仍可能保留 starter 内容或 TODO,必须以实际代码为准完成。

功能规划

阶段 1:锁定安全不变量

先用现有测试或新增测试固定以下规则:

  • “没有收到成功响应”不等于“供应商没有创建订单”。
  • 只有 EXPLICIT_REJECTerrorCode 精确等于 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
TIMEOUTHTTP_5XXNETWORK_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_LATERnextCheckAt=now+retryDelay
唯一 PENDING 且本次达到上限 MANUAL_REVIEW + QUERY_ATTEMPTS_EXHAUSTED
唯一 FAILEDCANCELLED 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
  • 已确认订单收到不同订单号或确认号:进入人工审核。
  • 已确认订单收到更旧的同订单 PENDINGNOOP + STALE_EVENT_IGNORED,不得降级。
  • 已确认订单收到更新或同时发生的矛盾状态:进入人工审核,不自动降级。
  • 标识冲突优先于乱序忽略;旧事件中的另一张供应商订单仍是风险证据。
  • MANUAL_REVIEW 为粘性状态,自动事件不得使其退出。
  • FAILED_FINAL 重复收到同类白名单拒绝可以 NOOP;后续出现供应商订单证据必须人工审核。

阶段 5:校验与异常处理

区分调用契约错误和供应商业务数据异常:

  • orderresultnownull,订单主键/状态/更新时间无效,查询次数为负,或服务配置非法:抛带明确参数名的 IllegalArgumentException
  • 事件缺少 eventIdclientReferenceoccurredAt,引用不一致,匹配缺少订单号/状态,或确认结果缺少确认号:返回 MANUAL_REVIEW,不要抛异常。
  • 查询同时返回一条匹配和错误码:QUERY_RESULT_CONFLICT
  • 查询返回多条匹配时,即使同时带错误码,也优先报告 MULTIPLE_SUPPLIER_BOOKINGS
  • 不吞 RuntimeException,不使用异常推动正常业务状态,不创建自定义异常层级。

阶段 6:完成测试与交付

先盘点现有测试,不为凑数量复制场景。针对尚未覆盖的高风险分支补最小测试,重点检查:

  • HTTP_5XXNETWORK_ERROR 和非白名单拒绝。
  • 已确认订单收到不同供应商订单号或确认号。
  • 唯一 PENDINGCANCELLED 和查询错误。
  • clientReference 不匹配、查询结果自相矛盾、构造参数与入口契约错误。
  • MANUAL_REVIEW 粘性、FAILED_FINAL 后出现供应商订单证据。

每个决策测试除状态和动作外,还应按场景断言 safeToCreateAgainreasonCode、回填字段和 nextCheckAt。不要测试私有方法。

更新交付文档:

  • README.md:使用 mvn -f backend/pom.xml test,说明核心设计、运行方式、已知限制和生产化缺口;删除 starter 中“服务未实现”的描述。
  • DECISIONS.md:在建议的 800 字内回答核心风险、状态转移、唯一允许重建条件、人工处理条件,以及生产环境的持久化、并发/锁、消息去重和可观测性方案。
  • AI_USAGE.md:在建议的 500 字内如实记录实际使用的 AI、参与环节、验证方法和产品边界。

实现约束

  • 保持 BookingReconciliationService.afterCreate(...)afterQuery(...) 两个入口。
  • 优先保留现有 recordenum 和包结构;现有状态和动作足够时不要新增。
  • 使用 JDK 标准库,不新增依赖,不引入 Spring、Lombok 或状态机框架。
  • 可用少量私有辅助方法统一构造决策,但不要创建接口、工厂、仓储层或生产基础设施。
  • 前端、数据库、HTTP API、消息队列、分布式锁和监控实现不在本次范围;只在 DECISIONS.md 说明生产方案。
  • 当前没有外部接口,因此 traceId 接口门禁不适用;不要为了满足该门禁凭空新增接口。
  • 保留用户已有改动,不做无关格式化或重构。

完成门禁

提交结果前逐项确认:

  • mvn -f backend/pom.xml test 全部通过,报告测试数量和结果。
  • 只有白名单明确拒绝允许再次创建供应商订单。
  • 多匹配、冲突、无结果耗尽、异常数据均不会静默覆盖或自动重建。
  • 重复事件和旧事件不会让已确认订单降级。
  • 所有决策包含稳定原因码和非空排查消息;需要查询时包含正确的 nextCheckAt
  • README.mdDECISIONS.mdAI_USAGE.md 无未说明的 TODO,且与代码一致。
  • 没有新增不需要的依赖、分层或基础设施。

最终回复格式

完成后只报告:

  1. 修改了哪些行为和文件。
  2. 执行了什么验证,测试数量及结果。
  3. 仍未实现但已在文档说明的生产化事项。

不要粘贴整份源码,不要声称未执行的检查已经通过。