BE-01-SB Spring Boot MVC 架构差距审计

article
2026年7月20日阅读约 2 分钟234 字

更新于 2026年7月20日

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。