BE-01-SB Spring Boot MVC 架构差距审计
BE-01-SB Spring Boot MVC 架构差距审计
基线
- 已检查 backend/pom.xml、全部领域模型和 BookingReconciliationService;服务只有两个公开决策入口,验证和安全分支在服务内闭环。
- 当前仅有 Java 17、JUnit、Compiler 和 Surefire;没有 Spring Boot、Web/MVC、启动类、HTTP 错误映射或 traceId。
- 基线命令
mvn -f backend/pom.xml test:21 tests,0 failures,0 errors,0 skipped,BUILD SUCCESS(2026-07-20 10:42:14 +08:00)。 - 本文不修改生产或测试代码。数据库、供应商客户端、消息队列、调度和持久化仍不做。
最小结构
com.shgalaxy.assessment
|- BookingReconciliationApplication 启动类、Clock、默认 service Bean
|- api
| |- BookingReconciliationController
| |- CreateReconciliationRequest
| |- QueryReconciliationRequest
| |- ApiError
| `- ApiExceptionHandler
`- web
`- TraceIdFilter
model / service 保持无 Spring 依赖
POM 仅引入兼容 Java 17 的 Spring Boot 3.x dependency management、spring-boot-starter-web、spring-boot-starter-validation、测试范围 spring-boot-starter-test 和 Spring Boot Maven plugin;测试 starter 管理 JUnit,移除单独 junit-jupiter。默认 new BookingReconciliationService() 继续提供三次查询和五分钟间隔;不增加配置绑定、Repository、接口或状态机框架。
REST 契约
| 入口 | 路径 | 请求体 | 成功响应 |
|---|---|---|---|
| 建单结果对账 | POST /api/v1/booking-reconciliations/create-results | CreateReconciliationRequest { order: OrderSnapshot, result: CreateAttemptResult } | 200,ReconciliationDecision,X-Trace-Id |
| 查单结果对账 | POST /api/v1/booking-reconciliations/query-results | QueryReconciliationRequest { order: OrderSnapshot, result: SupplierQueryResult } | 200,ReconciliationDecision,X-Trace-Id |
Controller 使用一次 Instant.now(clock) 调用纯决策服务,不接受外部 now。Instant 使用 ISO-8601 UTC,枚举沿用 Java 枚举名称,SupplierQueryResult 的 matches=null 保持现有构造器的空列表归一化。成功响应直接序列化 ReconciliationDecision,不增加响应 DTO。业务外部数据异常仍返回 200 + MANUAL_REVIEW;不得被 MVC 改写为自动重试或重新下单。
错误、校验与 traceId
- 空 body、JSON/时间/枚举无法解析、顶层 order/result 缺失:400 INVALID_REQUEST。
- 服务的 IllegalArgumentException:400 INVALID_REQUEST,响应不回显 body。
- 业务数据异常:保持现有 MANUAL_REVIEW 决策。
- 非预期故障:500 INTERNAL_ERROR,记录完整异常,不暴露栈、令牌、供应商标识或原始 body。
- TraceIdFilter 读取 X-Trace-Id;缺失生成 UUID,非法值返回含新 traceId 的 400。将同一值写入 MDC、request attribute 和响应头。
- 正常路径写结构化审计日志:traceId、operation、orderId、action、reasonCode;不记录 confirmation code、supplier booking id 或完整 body。
- 请求头、响应头、错误 body、错误日志与审计日志使用同一个 traceId。当前审计介质仅结构化应用日志,后续持久化审计必须原样复用该 traceId。
安全复用与门禁
BookingReconciliationService 仍是唯一判定者:不确定建单/非白名单拒绝查单;唯一白名单拒绝才能重建;多匹配、结果冲突、标识冲突、终态和人工审核语义全部保持原样。Controller 只做 HTTP 适配。
实施顺序:POM + 启动类 + Bean,保留现有 21 个测试;请求 records、Controller 和异常处理的 MockMvc 测试;trace filter/审计日志并验证 trace 贯通;最后运行 mvn -f backend/pom.xml test。