迭代 I5 / I6 设计说明 — M5 Callback Inbox、M6 集成最小面、Webhook 生产链与 UAT 冻结
仓库:craftlabs-authorization-sdk(分支 develop)。
角色:解决方案架构设计稿;不在本任务中落地代码。
实现锚点(与现有模式一致):delivery-platform-api 使用 Flyway V5__… 起(当前末版为 V4__delivery_batch_and_license_sn.sql)、AuditService + AuditEntityTypes / AuditActions、ApiExceptionHandler、公开业务 API 经 SecurityConfig + JwtAuthenticationFilter(Authorization: Bearer);OpenAPI SSOT 为 contracts/openapi/delivery-platform-api.json 与 OpenApiContractSnapshotTest。
Webhook 工程名:本工作区已实现为 license-webhook-ingress(services/README.md:webhook_callback_receipt、Idempotency-Key)。
0. 上游文档走查(按路径引用,不全文摘录)
Part A — I5:本单体工作区内的 MVP 切片
A.1 问题与目标结果
| 维度 |
说明 |
| 业务问题 |
比特规则 HTTPS Callback 需 不断链、可审计、可运营处置;平台侧需统一收件箱,避免只在 Webhook 边缘落库不可见。 |
| I5 目标结果(E2E) |
模拟或真实 Callback 经 license-webhook-ingress →(持久化收据后)投递 → delivery-platform-api Inbox 表出现一行;运营账号用 JWT 在 UI 列表可见、详情可打开。 |
| 幂等 |
与轨道 A 一致:Idempotency-Key(HTTP 头)+ 比特稳定 message_id(或等价字段);DB 唯一约束 (source_system, external_message_id);重复请求 不重复插入、返回与首次一致的接受语义(HTTP 200 + 相同 inboxId 或约定 DTO)。 |
| schemaVersion |
事件体或头携带 schemaVersion(与轨道 A 的 X-Event-Schema-Version 二选一或并存,须写 ADR 定一种主口径);平台拒绝无法识别的 major 版本时返回 4xx 并记录可观测字段,避免静默损坏。 |
A.2 数据模型(delivery-platform-api,PostgreSQL + Flyway)
命名与现有表一致采用 platform_* 前缀(见 V1~V4 迁移)。
A.2.1 platform_callback_inbox(M5 Inbox P0)
| 列(示例) |
类型/说明 |
id |
UUID / BIGSERIAL PK |
source_system |
VARCHAR,如 BITANSWER |
external_message_id |
VARCHAR,比特侧稳定消息 ID |
| 唯一约束 |
UNIQUE (source_system, external_message_id) |
schema_version |
VARCHAR,与 payload 解析版本对齐 |
event_type |
VARCHAR,与 M5-F05 字典一致(如 sn:pre_activate) |
status |
ENUM/VARCHAR:PENDING / PROCESSED / FAILED / IGNORED(对应产品「待处理、已处理、失败、忽略」) |
raw_payload |
JSONB(或 TEXT + 大小上限);UI 脱敏展示 |
idempotency_key |
VARCHAR NULL,审计与排障 |
| 关联(均可 NULL,支撑 M5-F04) |
license_sn_id → platform_license_sn;contract_id / project_id(若已有表);解析字段如 sn_code、mid 等冗余列便于列表筛选 |
product_line_id / integration_environment_id |
FK → M6 最小表(可选,便于按产品线/环境筛选) |
received_at |
平台收件时间 |
processed_at / processed_by_user_id |
运营处置 |
failure_reason / operator_note |
文本,P1 可扩展「失败原因分类」字典 |
| 标准审计 |
与现有实体一致可补充 created_at/updated_at;关键状态迁移建议走 AuditService(扩展 AuditEntityTypes / AuditActions) |
A.2.2 M6 最小只读支撑表
仅包含 I5 UI 与 Inbox 筛选 所需字段;不做 M6-F03~F06 全量。
| 表 |
P0 字段(示例) |
platform_product_line |
id、code(唯一)、name、description NULL、启用标志 |
platform_integration_environment |
id、code(唯一)、name、bitanswer_base_url(对应 M6-F02)、kind(DEV/TEST/STAGING/PROD 等枚举)、可选 product_line_id 或后续多对多(MVP 可 单列 FK 简化) |
MVP 裁减:比特产品/模版/业务 ID 映射(M6-F03)、特征映射(M6-F04)、JSON 模板与发布记录(M6-F05/F06)推迟至 V1.1 或 Mid,除非比特联调硬依赖。
A.3 公开 REST API(JWT,/api/v1)
与现有 Controller 风格一致;RBAC:与当前演示一致 SYS_ADMIN / DEVELOPER 均可访问 MVP 接口(与 AuthController 对齐),I7+ 再收紧为 Ops 专用权限码。
| 方法 |
路径 |
说明 |
GET |
/api/v1/callback-inbox |
分页;查询建议:status、eventType、snCode、projectId、productLineId、environmentId、from/to(receivedAt)、page、size |
GET |
/api/v1/callback-inbox/{id} |
详情;含 rawPayload(或单独 GET .../payload 若需权限分级) |
PATCH |
/api/v1/callback-inbox/{id}/status |
运营状态迁移:PENDING → PROCESSED / FAILED / IGNORED;非法迁移 409 + 业务错误码(与合同/交付模式一致,经 ApiExceptionHandler) |
PATCH |
/api/v1/callback-inbox/{id}/link(可选) |
人工挂接:licenseSnId / projectId / contractId 等,支撑 M5-F04 |
可选:POST /api/v1/callback-inbox/simulate(仅非生产,对应 M5-F10 P2 — I5 若排期紧可不做,改用 curl → Webhook → 平台链)。
M6 只读
| 方法 |
路径 |
说明 |
GET |
/api/v1/integration/environments |
列表/分页 |
GET |
/api/v1/integration/product-lines |
列表/分页 |
GET |
/api/v1/integration/environments/{id}、.../product-lines/{id} |
详情(按需) |
写接口(维护环境/产品线)MVP 可 仅种子数据 + Flyway 或 管理员 POST(若 I5 周可交付则加 POST/PUT,否则 推迟)。
A.4 内部 API(平台服务间,license-webhook-ingress → delivery-platform-api)
| 项 |
说明 |
| 路径 |
POST /internal/v1/callback-events |
| 认证(MVP 推荐) |
共享密钥:X-Platform-Internal-Token(或 Authorization: Bearer <internal>),配置与 PLATFORM_JWT_SECRET 分离;生产建议路线图:mTLS 或双向签名(文档中注明 I6 Runbook:轮换步骤)。 |
| 幂等 |
请求头 Idempotency-Key + 体 sourceSystem + externalMessageId 与 Inbox 唯一键一致;重复 POST → 200 且 body 指向同一 inboxId。 |
| 行为 |
校验 schemaVersion → 插入或跳过(幂等)→ 尝试解析并 填充关联列(失败则 status=PENDING 保留人工挂接)。 |
请求 / 响应 JSON 示例(示意)
A.5 license-webhook-ingress 链路
| 步骤 |
说明 |
| 1 |
验签 / token(现有 x-bitanswer-token 与 CRAFTLABS_WEBHOOK_EXPECTED_TOKEN) |
| 2 |
持久化收据(现有 webhook_callback_receipt + Idempotency-Key 幂等) |
| 3 |
HTTP 转发 至平台 POST /internal/v1/callback-events:带重试(指数退避、最大次数、超时);贯通 traceparent / X-Request-Id(轨道 A §3) |
| 对比特的 HTTP 响应 |
与轨道 A 一致:2xx 须在收据已持久化(或可靠入队)之后再返回。MVP 推荐:先落库收据即对比特 2xx,平台投递 异步重试;若 同步 转发,须 短超时 且平台幂等,避免比特侧超时重放放大。 |
| 平台非 2xx |
Webhook 侧重试;仍失败则记 DLQ/失败计数(日志 + DB 字段,M5-F08 完整监控可推迟);不因平台暂时不可用而对已持久化收据重复向比特报错(若已 2xx)。 |
A.6 OpenAPI 与 springdoc
| 项 |
说明 |
| SSOT |
更新 contracts/openapi/delivery-platform-api.json:仅 公开 /api/v1/callback-inbox*、/api/v1/integration/* 路径、components/schemas、错误码与 security(Bearer JWT)。 |
| 内部路由 |
/internal/** 建议排除在默认 springdoc 分组之外,或打上 tag internal 且 生产禁用该分组(与「对外契约」分离,避免集成方误用)。 |
| 校验 |
UPDATE_OPENAPI=1 mvn test -Dtest=OpenApiContractSnapshotTest(见 contracts/README.md)。 |
A.7 前端(web/delivery-platform-ui)
| 路由 |
页面职责 |
/callbacks |
Inbox 列表、CallbackInboxTable;跳转详情 |
/callbacks/:id |
详情 + CallbackPayloadViewer(脱敏);状态 PATCH、可选人工挂接 |
/integration/environments |
M6 环境只读表 |
/integration/product-lines |
产品线只读表 |
路由 meta:权限码与 I1 壳一致;菜单对 SYS_ADMIN / DEVELOPER 可见(MVP)。
A.8 SDK 轨道(本仓库,I5 硬交付清单)
- Schema:
schemas/craftlabs-auth-config.schema.json 等 — 若 BP-10 变更类型触及「平台导出 → Schema → 客户端」,按 轨道 C §3 bump 规则执行。
- Java
AuthConfigs:与 Schema 同步(表见轨道 C BP-10)。
examples/:与最新字段及环境变量说明一致;CI 与 Schema 校验对齐。
- 文档:明确 SDK 版本线 ≠ 平台 Fat JAR 版本;引用 BPM BP-10 与产品 M6-F01/F02 口径。
- 不做:Native 与 Webhook 运行时耦合;平台不嵌入 JNI。
Part B — I6:本文件内仅规划(不展开实现)
| 主题 |
内容要点 |
| UAT 门禁 |
跑通 BP-01~06、11 主链路(与 轨道 B I6 E2E 一致);Callback 场景含重复投递幂等、关联失败人工挂接。 |
| 冻结清单 |
SDK:定版 tag、CHANGELOG、BitAnswer 兼容矩阵(轨道 C);OpenAPI 快照冻结;两 JAR 版本与镜像标签可追踪;前端 VITE_API_BASE 环境矩阵文档化。 |
| Runbook |
复用并增补 services/RUNBOOK.md:内部 token 轮换、Webhook→平台连通性检查、DB 迁移顺序(flyway_platform_api / flyway_webhook)。 |
| 安全加固 |
安全响应头、Cookie/Session 策略(若 Mid 前仍为 JWT 则文档化 仅 Bearer)、依赖扫描与已知 CVE 处理;禁止 I6 周排入大块新功能(仅缺陷与加固)。 |
Part C — 实现顺序与 MVP 切割
- 平台 DB(Flyway
V5+):platform_callback_inbox + M6 两表 + 必要索引与外键;种子数据(环境/产品线)可选。
- 平台内部 API:
POST /internal/v1/callback-events + 幂等与 schemaVersion 校验 + AuditService 钩子(状态/关联变更)。
- 平台公开 API:
GET/PATCH callback-inbox、M6 只读 GET;统一异常经 ApiExceptionHandler。
- OpenAPI 快照 与契约测试更新。
- Webhook:在收据落库后增加 转发客户端(重试、观测头);配置项:
PLATFORM_INTERNAL_BASE_URL、PLATFORM_INTERNAL_TOKEN。
- 集成测试:Testcontainers + 双模块或 Compose(与轨道 A I5+
cross-service-it 建议一致)。
- 前端:路由与表格/详情/脱敏展示;联调 staging。
- SDK / Schema / examples:按 BP-10 终版对齐并过 CI。
MVP 明确推迟(若全量 M5/M6 过大)
| 推迟项 |
说明 |
| M6-F03~F09 |
比特 ID 映射、特征映射、模板库、发布记录、影响分析 |
| M5-F06~F09 |
失败分类字典、批量重试 UI、积压监控、M8 待办联动 |
| M5-F10 |
模拟投递 UI(可用 curl/Postman 代替) |
| MQ 投递 |
保留 HTTP MVP;MQ + 消费者为 ADR 备选(轨道 A 已列 B 方案) |
Part D — 可追溯性(设计章节 → 产品功能点)
| 设计章节 |
产品模块 / 功能点(适用处) |
| A.1 幂等与 schemaVersion |
M5 运营基础;BP-06 |
A.2.1 platform_callback_inbox |
M5-F01~F04(列表、详情、状态、关联兜底) |
A.2.1 event_type、字典 |
M5-F05 |
| A.2.2 产品线 / 环境表 |
M6-F01、M6-F02 |
| A.3 公开 REST |
M5-F01~F03;人工挂接 M5-F04 |
| A.4 内部 API |
BP-06 入站;与轨道 A Webhook↔平台契约 |
| A.5 Webhook 转发 |
BP-06 步骤①②;不丢链 |
| A.8 SDK / Schema |
BP-10;M6 配置治理(文档与校验链) |
| Part B I6 |
BP-01~06、11 UAT;M11 安全与运维 |
修订记录
| 日期 |
说明 |
| 2026-04-06 |
初版:I5/I6 架构设计,对齐并行索引、三轨道文档与产品 M5/M6 P0。 |