供应商订单安全对账实现规格与任务拆分
供应商订单安全对账实现规格与任务拆分
状态:可执行
规格来源:CANDIDATE_TASK.md、.project/docs/prompt/IMPLEMENTATION_PROMPT.md、当前源码与项目规则
基线日期:2026-07-20
1. 使用方式
本文同时是行为规格、验收基线和任务领取清单。开发人员领取任务后,必须按任务卡中的前置依赖、允许修改范围和验收项执行;不得用后续任务中的假设反向改变本规格。
任务状态建议只使用:待领取、开发中、待验收、已完成、阻塞。每个任务单独提交,提交说明包含需求编号、修改文件、验证命令与结果。
2. 当前基线与范围
2.1 已验证基线
| 模块 | 当前状态 | 基线命令 | 结果 |
|---|---|---|---|
| 后端 | Java 17 + Maven + JUnit 5,纯决策服务 | mvn -f backend/pom.xml test |
21 个测试通过,0 失败,0 错误,0 跳过 |
| 前端 | Vite + TypeScript,无运行时依赖,当前仅有空状态页面 | cd frontend; npm run build |
类型检查与构建通过 |
现有实现可能已经满足部分行为。所有后端任务均采用“先证明缺口,再做最小修改”的方式:现有测试已经完整证明的行为不重复实现,新增测试失败后才修改生产代码。
2.2 本轮必须交付
- 审计并补齐
BookingReconciliationService.afterCreate(...)与afterQuery(...)。 - 通过自动化测试固定安全不变量、状态转移、幂等、乱序和异常分类。
- 更新
README.md、DECISIONS.md、AI_USAGE.md,使其与最终代码和验证结果一致。 - 后端保持纯决策模块,不接数据库、网络、消息队列或系统时钟。
2.3 前端范围说明
原始实现提示词明确将前端和 HTTP API 排除在本轮后端交付之外。因此前端任务分为两组:
FE-01至FE-04:可独立开发的只读决策展示原型,使用本地展示数据,不复制后端决策算法。FE-05:真实接口集成,当前阻塞;必须等产品方给出查询 API、鉴权、分页和错误协议后才能领取。
前端原型不得成为后端完成门禁,也不得推动后端增加 Controller、DTO 或框架依赖。
2.4 明确不做
- 不实现数据库、HTTP API、供应商客户端、消息队列、分布式锁、定时调度、监控或人工审核写操作。
- 不引入 Spring、Lombok、状态机框架、前端框架、状态库、组件库或测试框架。
- 不用进程内
eventId集合伪装持久化去重。 - 不新增状态和动作;现有
record、enum和包结构足够。 - 不把查不到订单、请求超时或本地缺少供应商订单号解释为“可以重新下单”。
3. 需求规格
3.1 安全不变量
| 编号 | 规格 | 可验收结果 |
|---|---|---|
| SAFE-01 | 未收到成功响应不等于供应商未创建订单 | TIMEOUT、HTTP_5XX、NETWORK_ERROR 均禁止重建并进入查单 |
| SAFE-02 | 只有白名单明确拒绝允许重建 | 仅 EXPLICIT_REJECT 且 errorCode 精确等于 NO_INVENTORY_NO_BOOKING_CREATED 时 safeToCreateAgain=true |
| SAFE-03 | 未知结果采用安全默认值 | 未知拒绝、零匹配、查询错误、查询耗尽和人工审核均为 safeToCreateAgain=false |
| SAFE-04 | 本地标识不得被冲突值覆盖 | supplierBookingId 或 confirmationCode 任一冲突即进入人工审核,决策不输出回填值 |
| SAFE-05 | 多匹配不得自动选第一条 | 多匹配优先进入人工审核,原因码为 MULTIPLE_SUPPLIER_BOOKINGS |
| SAFE-06 | 只有同步确认动作可以输出回填标识 | 非 SYNC_CONFIRMED 决策的两个回填字段均为 null |
| SAFE-07 | 所有决策可解释且确定 | 相同输入得到内容相同的决策;原因码稳定,消息非空且不含敏感数据 |
3.2 领域输入输出
OrderSnapshot
| 字段 | 规则 |
|---|---|
orderId |
非空;同时作为供应商侧 clientReference |
state |
非空,取现有 BookingState |
supplierBookingId |
可空;存在时不得被不同值自动覆盖 |
confirmationCode |
可空;存在时不得被不同值自动覆盖 |
updatedAt |
非空;用于终态乱序判断 |
reconciliationAttempts |
非负;表示本次查询前已完成的查询次数 |
事件与查询结果
CreateAttemptResult必须包含有效eventId、clientReference、outcome和occurredAt。SupplierQueryResult必须包含有效eventId、clientReference和occurredAt;matches=null按空列表处理。- 每个
SupplierBooking必须包含匹配的clientReference、supplierBookingId和status。 CONFIRMED匹配还必须包含confirmationCode;其他供应商状态不强制要求确认号。
ReconciliationDecision
每次调用必须完整返回:nextState、action、safeToCreateAgain、reasonCode、message、supplierBookingId、confirmationCode、nextCheckAt。
时间规则:
- 立即查单:
nextCheckAt=now。 - 延迟重试:
nextCheckAt=now+retryDelay。 - 其他动作:
nextCheckAt=null。 - 服务不得调用
Instant.now()。
3.3 afterCreate 决策表
| 编号 | 条件 | nextState / action | reasonCode | 其他断言 |
|---|---|---|---|---|
| CREATE-01 | SUCCESS,两个标识完整且无冲突 |
CONFIRMED / SYNC_CONFIRMED |
CREATE_CONFIRMED |
回填两个标识;禁止重建;不调度查询 |
| CREATE-02 | SUCCESS,任一标识缺失 |
MANUAL_REVIEW / ESCALATE_MANUAL_REVIEW |
CONFIRMED_RESULT_INCOMPLETE |
不部分回填;禁止重建 |
| CREATE-03 | SUCCESS,任一标识与本地冲突 |
MANUAL_REVIEW / ESCALATE_MANUAL_REVIEW |
SUPPLIER_IDENTIFIER_CONFLICT |
不覆盖;禁止重建 |
| CREATE-04 | 白名单明确拒绝且没有供应商订单证据 | FAILED_FINAL / MARK_FAILED |
EXPLICIT_NO_BOOKING_CREATED |
唯一 safeToCreateAgain=true 路径 |
| CREATE-05 | 其他 EXPLICIT_REJECT 且无供应商订单证据 |
PENDING_RECONCILIATION / QUERY_BY_CLIENT_REFERENCE |
REJECT_WITHOUT_NO_BOOKING_GUARANTEE |
禁止重建;nextCheckAt=now |
| CREATE-06 | TIMEOUT、HTTP_5XX 或 NETWORK_ERROR |
PENDING_RECONCILIATION / QUERY_BY_CLIENT_REFERENCE |
CREATE_RESULT_UNCERTAIN |
禁止重建;nextCheckAt=now |
| CREATE-07 | 拒绝结果同时含任一供应商标识 | MANUAL_REVIEW / ESCALATE_MANUAL_REVIEW |
SUPPLIER_STATUS_CONFLICT 或更高优先级标识冲突码 |
不回填;禁止重建 |
3.4 afterQuery 决策表
查询次数判断固定为:处理本次后使用 reconciliationAttempts + 1 >= maxQueryAttempts 判断耗尽。默认 maxQueryAttempts=3,默认 retryDelay=5 分钟。
| 编号 | 条件 | nextState / action | reasonCode | 其他断言 |
|---|---|---|---|---|
| QUERY-01 | 多条匹配,无论是否同时有错误码 | MANUAL_REVIEW / ESCALATE_MANUAL_REVIEW |
MULTIPLE_SUPPLIER_BOOKINGS |
消息明确重复订单风险 |
| QUERY-02 | 一条匹配且同时有错误码 | MANUAL_REVIEW / ESCALATE_MANUAL_REVIEW |
QUERY_RESULT_CONFLICT |
不回填 |
| QUERY-03 | 唯一 CONFIRMED,字段完整且无冲突 |
CONFIRMED / SYNC_CONFIRMED |
QUERY_CONFIRMED |
回填两个标识;禁止重建 |
| QUERY-04 | 唯一 CONFIRMED 但缺确认号 |
MANUAL_REVIEW / ESCALATE_MANUAL_REVIEW |
CONFIRMED_RESULT_INCOMPLETE |
不回填 |
| QUERY-05 | 唯一 PENDING,本次后未达上限 |
PENDING_RECONCILIATION / RETRY_QUERY_LATER |
SUPPLIER_BOOKING_PENDING |
nextCheckAt=now+retryDelay |
| QUERY-06 | 唯一 PENDING,本次达到上限 |
MANUAL_REVIEW / ESCALATE_MANUAL_REVIEW |
QUERY_ATTEMPTS_EXHAUSTED |
不调度查询 |
| QUERY-07 | 唯一 FAILED 或 CANCELLED |
MANUAL_REVIEW / ESCALATE_MANUAL_REVIEW |
SUPPLIER_TERMINAL_STATUS_REVIEW |
禁止重建 |
| QUERY-08 | 零匹配且未达上限 | PENDING_RECONCILIATION / RETRY_QUERY_LATER |
NO_MATCH_RETRY |
nextCheckAt=now+retryDelay |
| QUERY-09 | 查询错误且未达上限 | PENDING_RECONCILIATION / RETRY_QUERY_LATER |
QUERY_ERROR_RETRY |
nextCheckAt=now+retryDelay |
| QUERY-10 | 零匹配或查询错误,本次达到上限 | MANUAL_REVIEW / ESCALATE_MANUAL_REVIEW |
QUERY_ATTEMPTS_EXHAUSTED |
禁止重建 |
| QUERY-11 | 唯一结果任一标识与本地冲突 | MANUAL_REVIEW / ESCALATE_MANUAL_REVIEW |
SUPPLIER_IDENTIFIER_CONFLICT |
冲突优先于乱序;不回填 |
3.5 幂等、乱序与终态
| 编号 | 条件 | 预期 |
|---|---|---|
| STATE-01 | CONFIRMED 收到相同订单号和确认号 |
保持 CONFIRMED,NOOP / ALREADY_CONFIRMED |
| STATE-02 | CONFIRMED 收到不同订单号或不同确认号 |
MANUAL_REVIEW / SUPPLIER_IDENTIFIER_CONFLICT |
| STATE-03 | CONFIRMED 收到更旧的同订单 PENDING |
保持 CONFIRMED,NOOP / STALE_EVENT_IGNORED |
| STATE-04 | CONFIRMED 收到同时或更新的 PENDING、FAILED、CANCELLED |
MANUAL_REVIEW / SUPPLIER_STATUS_CONFLICT |
| STATE-05 | 乱序事件携带不同供应商标识 | 先报告标识冲突,不得按旧事件忽略 |
| STATE-06 | MANUAL_REVIEW 收到任何自动事件 |
保持 MANUAL_REVIEW,NOOP / MANUAL_REVIEW_REQUIRED |
| STATE-07 | FAILED_FINAL 重复收到相同白名单拒绝 |
保持 FAILED_FINAL,NOOP / ALREADY_FAILED_FINAL,可保持允许重建 |
| STATE-08 | FAILED_FINAL 后出现供应商订单证据 |
进入人工审核;不得静默保留最终失败 |
查询乱序比较优先使用 SupplierBooking.supplierUpdatedAt,为空时使用 SupplierQueryResult.occurredAt。
3.6 校验与异常分类
| 编号 | 类型 | 条件 | 预期 |
|---|---|---|---|
| VALID-01 | 调用契约错误 | order、result 或 now 为 null |
抛 IllegalArgumentException,消息包含参数名 |
| VALID-02 | 调用契约错误 | 订单主键空、状态空、更新时间空、查询次数为负 | 抛 IllegalArgumentException,消息包含字段名 |
| VALID-03 | 调用契约错误 | CreateAttemptResult.outcome=null |
抛 IllegalArgumentException,消息包含 result.outcome |
| VALID-04 | 配置错误 | 最大次数非正、延迟为空或为负 | 构造时抛 IllegalArgumentException,消息包含配置名 |
| VALID-05 | 业务数据异常 | 事件缺少 eventId、clientReference 或 occurredAt |
MANUAL_REVIEW / INVALID_EVENT_DATA |
| VALID-06 | 业务数据异常 | 事件或匹配的 clientReference 不属于本地订单 |
MANUAL_REVIEW / CLIENT_REFERENCE_MISMATCH |
| VALID-07 | 业务数据异常 | 匹配缺少订单号或状态 | MANUAL_REVIEW / INVALID_EVENT_DATA |
业务数据异常不得抛异常;服务不得捕获或吞掉意外 RuntimeException。
4. 后端任务卡
后端任务按 BE-01 -> BE-02 -> BE-03 -> BE-04 -> BE-05 -> BE-06 顺序执行。任务会修改同一个服务和测试文件,不并行开发,避免测试与判定顺序冲突。
BE-01 建立差距清单
目标:确认当前 21 个测试与规格的真实差距,禁止基于 starter 假设重写代码。
前置依赖:无。
允许修改:不修改生产代码;差距记录放在任务/提交说明中。
实施步骤:
- 运行
mvn -f backend/pom.xml test并记录测试数量。 - 将现有测试逐项映射到
SAFE-*、CREATE-*、QUERY-*、STATE-*、VALID-*。 - 标记三种情况:已完整断言、仅部分断言、未覆盖。
- 对“仅部分断言”和“未覆盖”创建后续测试清单;不得按测试数量目标复制场景。
验收:差距清单至少明确检查 QUERY_RESULT_CONFLICT、引用不匹配、构造/入口参数错误、FAILED_FINAL 后订单证据、仅确认号冲突、多匹配与错误码优先级。
验证:mvn -f backend/pom.xml test;提交说明附测试总数和需求编号映射结果。
BE-02 固定并补齐建单结果规格
目标:用测试证明 CREATE-01 至 CREATE-07 与 SAFE-01 至 SAFE-06。
前置依赖:BE-01。
允许修改:
backend/src/test/java/com/shgalaxy/assessment/service/BookingReconciliationServiceTest.java- 仅当新增测试失败时修改
backend/src/main/java/com/shgalaxy/assessment/service/BookingReconciliationService.java
实施步骤:
- 优先参数化三种不确定结果,断言立即查单且禁止重建。
- 覆盖完整成功、两个必填标识分别缺失、本地订单号冲突、本地确认号冲突。
- 覆盖白名单拒绝、非白名单拒绝和“拒绝同时含供应商标识”。
- 每个场景断言全部可观察字段:状态、动作、
safeToCreateAgain、原因码、两个回填字段和nextCheckAt。 - 只修复失败分支,不改公开入口、模型或依赖。
验收:只有 CREATE-04 的 safeToCreateAgain 为 true;人工审核不输出回填值;需要立即查询的场景精确使用传入的 now。
验证:mvn -f backend/pom.xml -Dtest=BookingReconciliationServiceTest test。
BE-03 固定并补齐查单规格
目标:证明 QUERY-01 至 QUERY-11 和查询次数边界。
前置依赖:BE-02。
允许修改:与 BE-02 相同。
实施步骤:
- 覆盖零匹配、查询错误、唯一
PENDING在查询前次数为 1 和 2 时的边界。 - 覆盖唯一
CONFIRMED完整/不完整、FAILED、CANCELLED。 - 覆盖“一条匹配+错误码”和“多条匹配+错误码”,证明多匹配优先。
- 覆盖订单号冲突和确认号冲突,确保不输出覆盖值。
- 对所有延迟场景精确断言
nextCheckAt=now.plus(retryDelay),耗尽场景断言其为null。
验收:查询前次数为 1 时默认仍可安排第三次查询;查询前次数为 2 时处理本次后进入人工审核。任何零匹配或查询错误路径均禁止重建。
验证:mvn -f backend/pom.xml -Dtest=BookingReconciliationServiceTest test。
BE-04 固定终态、幂等与乱序优先级
目标:证明 STATE-01 至 STATE-08,避免已确认订单降级或最终失败掩盖订单证据。
前置依赖:BE-03。
允许修改:与 BE-02 相同。
实施步骤:
- 分别通过
afterCreate和afterQuery覆盖重复确认。 - 分别覆盖供应商订单号不同、确认号不同;旧事件也必须先报告标识冲突。
- 覆盖旧
PENDING的忽略,以及同时/更新的PENDING、FAILED、CANCELLED冲突。 - 分别通过两个入口验证
MANUAL_REVIEW粘性。 - 覆盖
FAILED_FINAL的重复白名单拒绝,以及其后完整/不完整供应商订单证据。 - 对同一输入调用两次并断言两个
ReconciliationDecision内容相等。
验收:任何自动事件都不能让 CONFIRMED 降为待对账或最终失败;任何自动事件都不能让 MANUAL_REVIEW 离开人工状态;标识冲突优先于时间旧。
验证:mvn -f backend/pom.xml -Dtest=BookingReconciliationServiceTest test。
BE-05 固定契约校验与异常数据
目标:证明 VALID-01 至 VALID-07,区分编程错误与供应商业务异常。
前置依赖:BE-04。
允许修改:与 BE-02 相同。
实施步骤:
- 用最小参数化或聚合测试覆盖构造器、订单快照和入口的非法参数,断言异常消息包含字段名。
- 覆盖建单事件、查询事件、供应商匹配各自的缺字段与
clientReference不一致。 - 证明业务异常返回人工审核而非抛异常,且不输出回填字段。
- 不创建自定义异常,不为测试扩大私有方法可见性。
验收:调用契约错误快速失败;外部业务数据异常形成稳定可解释决策;无异常被吞掉或改写为成功。
验证:mvn -f backend/pom.xml -Dtest=BookingReconciliationServiceTest test。
BE-06 完成交付文档与全量门禁
目标:使交付文档与最终行为、实际测试数和生产边界一致。
前置依赖:BE-05。
允许修改:README.md、DECISIONS.md、AI_USAGE.md;只有发现回归时才回到对应代码任务修复。
实施步骤:
- 更新 README 的运行命令、核心设计、默认次数/间隔、限制和生产化缺口。
- 在 DECISIONS 中说明风险、状态转移、唯一重建条件、人工审核条件,以及持久化、并发、去重和可观测性方案。
- 在 AI_USAGE 中如实记录工具、参与环节、验证方法和产品边界,不写未执行的检查。
- 搜索三份文档中的
TODO和“服务未实现”等过期描述。 - 运行全量 Maven 测试并记录最终测试数量。
验收:文档与代码无矛盾;无未说明 TODO;无新增生产依赖、分层或基础设施;全量测试通过。
验证:
mvn -f backend/pom.xml test
rg -n "TODO|服务未实现" README.md DECISIONS.md AI_USAGE.md
5. 前端展示规格
5.1 产品边界
前端原型只帮助开发、运营理解后端已经作出的决策,不执行决策,也不自行计算状态转移。页面必须遵守:
- 不提供“重新下单”“强制同步”“人工审核通过”等写操作。
- 不根据缺少
supplierBookingId推断订单未创建。 safeToCreateAgain=false时不得显示任何可重建暗示。safeToCreateAgain=true只显示“供应商明确未建单,可重新创建”的只读结论,不显示可点击命令。message原样作为排查事实展示;状态、动作和原因码使用稳定枚举值映射中文标签。- 错误、空数据、待对账和人工审核必须是不同状态,不得都显示为“暂无数据”。
5.2 前端内部展示模型
以下仅是前端原型的内部类型,不是 HTTP DTO,也不得要求当前后端实现该接口:
type BookingState =
| 'NEW'
| 'SUBMITTING'
| 'PENDING_RECONCILIATION'
| 'CONFIRMED'
| 'FAILED_FINAL'
| 'MANUAL_REVIEW'
type ReconciliationAction =
| 'SYNC_CONFIRMED'
| 'QUERY_BY_CLIENT_REFERENCE'
| 'RETRY_QUERY_LATER'
| 'MARK_FAILED'
| 'ESCALATE_MANUAL_REVIEW'
| 'NOOP'
interface ReconciliationCaseView {
orderId: string
currentState: BookingState
updatedAt: string
reconciliationAttempts: number
decision: {
nextState: BookingState
action: ReconciliationAction
safeToCreateAgain: boolean
reasonCode: string
message: string
supplierBookingId: string | null
confirmationCode: string | null
nextCheckAt: string | null
}
}
日期字段使用 ISO 8601 字符串。空值保持 null,不得填充会改变业务含义的默认值。
5.3 页面验收
只读工作台采用紧凑列表或表格,至少展示:订单号、当前状态、下一状态、动作、原因码、下次查询时间和安全结论。每条记录可通过原生 <details> 展开 message、查询次数和回填标识。
必须覆盖四种本地演示数据:
MANUAL_REVIEW+MULTIPLE_SUPPLIER_BOOKINGS。PENDING_RECONCILIATION+CREATE_RESULT_UNCERTAIN,含nextCheckAt。CONFIRMED+QUERY_CONFIRMED,含两个回填标识。FAILED_FINAL+EXPLICIT_NO_BOOKING_CREATED,唯一safeToCreateAgain=true。
页面还必须提供独立空状态;数据解析失败时显示错误事实和重新加载页面的提示,不伪造空列表。
6. 前端任务卡
FE-01 至 FE-04 可在后端任务之外执行,但不得修改后端。当前前端没有测试框架,任务只使用 TypeScript、浏览器原生能力和现有 CSS,不新增依赖。
FE-01 定义展示类型与演示数据
目标:建立后端枚举同名的唯一前端类型定义和四个最小演示用例。
前置依赖:第 5.2 节展示模型已确认。
允许修改:
- 新增
frontend/src/reconciliation/types.ts - 新增
frontend/src/reconciliation/cases.ts
实施步骤:
- 按第 5.2 节定义类型,禁止
any。 - 创建第 5.3 节的四条只读演示数据,使用固定 ISO 时间。
- 用
satisfies readonly ReconciliationCaseView[]让编译器校验数据,不写运行时业务决策。
验收:枚举值与 Java 模型完全一致;只有白名单拒绝用例的 safeToCreateAgain 为 true;空值显式为 null。
验证:cd frontend; npm run build。
FE-02 渲染只读对账列表
目标:把当前空页面扩展为可扫描的只读工作台,不引入框架。
前置依赖:FE-01。
允许修改:frontend/index.html、frontend/src/main.ts。
实施步骤:
- 保留现有页面标题与入口,增加列表挂载区域和可感知的结果计数。
- 使用 DOM API 渲染语义化表格或列表;订单号作为稳定键,不用数组位置表达身份。
- 用
<details>展示排查消息、查询次数和可选标识。 - 将“状态/动作/原因码到中文文案”的映射集中在
main.ts或单个相邻模块;不得复制后端判定逻辑。 - 保留独立空状态;捕获展示数据格式错误时渲染错误状态,不吞异常。
验收:四条数据全部可见;nextCheckAt=null 显示“无需后续查询”,非空时显示明确时间;人工审核和待对账不被展示为最终失败。
验证:cd frontend; npm run build,并在浏览器检查桌面与 320px 宽度。
FE-03 落实安全文案与可访问交互
目标:让安全结论不依赖颜色,并确保键盘和辅助技术可读取。
前置依赖:FE-02。
允许修改:frontend/index.html、frontend/src/main.ts。
实施步骤:
- 为每条记录显示明确文本:“禁止自动重新下单”或“供应商明确未建单,可重新创建”。
- 用原生
<details>/<summary>提供键盘展开,不使用可点击div。 - 对结果数量或加载完成状态使用适当的语义区域;错误状态使用
role="alert"。 - 确认页面不存在实际下单按钮、自动重试或自动轮询。
验收:仅用文本即可区分状态和安全结论;Tab/Enter/Space 可操作全部展开项;焦点可见;页面缩放到 200% 后内容不遮挡。
验证:cd frontend; npm run build,浏览器键盘与 200% 缩放手工检查。
FE-04 完成响应式样式与前端门禁
目标:沿用现有视觉语言完成桌面/窄屏布局,保持运营工具的紧凑可扫读性。
前置依赖:FE-03。
允许修改:frontend/src/styles.css。
实施步骤:
- 复用现有颜色、字体、边框与 640px 断点,不引入样式框架。
- 桌面展示紧凑列;窄屏允许按行换行或转为标签/值布局,禁止水平内容遮挡。
- 为链接、
summary和其他实际交互补充:focus-visible;颜色之外保留文本标签。 - 处理长订单号、原因码和英文枚举换行,避免溢出。
- 运行最终构建,不手工修改
dist/。
验收:320px 至 1440px 无文字遮挡或不可达内容;状态不是只靠颜色表达;构建产物由 Vite 正常生成。
验证:cd frontend; npm run build。
FE-05 接入真实查询 API(阻塞)
目标:用真实服务端数据替换本地演示数据。
当前状态:阻塞,不得开始。
解锁条件:产品/后端另行确认以下契约:
- 查询端点、HTTP 方法、鉴权方式和权限模型。
- 返回 DTO、分页/排序规则、时间格式与稳定错误码。
- 加载、空结果、网络错误、超时、服务端错误的交互要求。
- 是否允许刷新、人工处理或其他写操作;每个写操作的幂等与审计要求。
- 请求、响应、错误日志和审计记录共用的
traceId规则。
禁止提前实现:不得在 main.ts 中硬编码 URL、鉴权头或猜测 DTO;不得为了本任务给 Java 纯决策模块增加 Controller。
7. 依赖与并行边界
后端:BE-01 -> BE-02 -> BE-03 -> BE-04 -> BE-05 -> BE-06
前端原型:FE-01 -> FE-02 -> FE-03 -> FE-04
|
+-> FE-05(等待外部 API 契约)
- 两条轨道可以并行,但当前实现提示词的完成只由 BE 轨道决定。
- 后端任务之间顺序执行,因为它们共享同一服务和测试文件。
- 前端任务之间顺序执行,避免入口、语义和样式互相返工。
- FE-05 不属于本轮;API 契约确认后应重新做规格评审。
8. 追踪矩阵
| 需求 | 实现/验证任务 | 前端可见性 |
|---|---|---|
| SAFE-01 至 SAFE-07 | BE-02、BE-03、BE-06 | FE-02、FE-03 |
| CREATE-01 至 CREATE-07 | BE-02 | FE-01 演示关键结果,不执行判定 |
| QUERY-01 至 QUERY-11 | BE-03 | FE-01、FE-02 展示结果与下次时间 |
| STATE-01 至 STATE-08 | BE-04 | FE-02 只展示后端结论 |
| VALID-01 至 VALID-07 | BE-05 | FE-02 展示数据错误,不推断业务状态 |
| 文档与全量门禁 | BE-06 | FE-04 独立构建门禁 |
9. 完成定义
后端必做完成定义
mvn -f backend/pom.xml test全部通过,并报告实际测试数量。- 只有白名单明确拒绝允许重建;其他所有决策均为
safeToCreateAgain=false。 - 多匹配、冲突、查询耗尽和异常外部数据不会触发静默覆盖或自动重建。
- 重复和旧事件不会让已确认订单降级;人工审核保持粘性。
- 所有决策包含稳定原因码、非空消息和符合动作语义的回填/调度字段。
- 三份交付文档无未说明
TODO,且与代码、测试一致。 - 未新增依赖、无关抽象、生产基础设施或 HTTP 接口。
前端原型完成定义
cd frontend; npm run build通过。- 四类决策和独立空/错误状态均可区分。
- 页面无写操作,不重复后端决策逻辑,不把未知状态显示为可重建。
- 320px 和桌面宽度无溢出,键盘可访问,状态不只依赖颜色。
- FE-05 保持阻塞,直到真实 API 契约另行批准。