mirror of
https://github.com/hpd840321/craftlabs-authorization-sdk.git
synced 2026-06-10 02:20:28 +08:00
650c1caffa
Add I8/I9 design and implementation review markdown, update parallel iteration index and I7 review cross-links, and add FRONTEND_UI_SPECIFICATION for design handoff (Figma Make). Made-with: Cursor
4.1 KiB
4.1 KiB
I8 设计 — Webhook 平台投递 DEAD 重放(MVP)
角色:解决方案架构;指导前后端实现与 Runbook。
前置:I7 已落地webhook_platform_delivery(PENDING/SENT/DEAD)与调度器;平台platform_callback_inbox.webhook_receipt_id与 Webhook 收据主键对齐(PlatformCallbackRequestPlanner写入webhookReceiptId)。
1. 问题与目标
| 维度 | 说明 |
|---|---|
| 问题 | 出库 DEAD 后仅能通过查库/SQL 手工改状态,无受控运维入口,易误操作。 |
| 目标 | Ops 在 Callback 详情 一键将对应 DEAD 投递重新入队(PENDING),由现有调度器按 max-attempts 再次尝试 POST /internal/v1/callback-events。 |
| 非目标 | 修改比特 Callback 契约;不实现全量 DLQ 控制台;不在浏览器直连 Webhook 服务。 |
2. 信任边界与 API 分层
flowchart LR
UI[delivery-platform-ui OPS JWT]
API[delivery-platform-api]
WH[license-webhook-ingress]
UI -->|Bearer JWT| API
API -->|X-Webhook-Ops-Token + receiptId| WH
WH -->|调度| API
- 浏览器只调平台
POST /api/v1/callback-inbox/{id}/replay-webhook-delivery,沿用CallbackInboxController的@PreAuthorize("hasAnyRole('OPS','SYS_ADMIN')")。 - 平台服务器到 Webhook 使用 独立共享密钥
X-Webhook-Ops-Token(与X-Platform-Internal-Token分离:前者保护 Webhook 运维面,后者保护平台内部 ingest)。 - Webhook 暴露
POST /internal/v1/platform-deliveries/by-receipt/{receiptId}/replay,由 Servlet Filter 校验 Ops Token(模块无 Spring Security 依赖,与现有/webhook/bitanswer/callback并存)。
3. 业务规则
| 规则 | 说明 |
|---|---|
| 关联键 | 使用平台收件箱的 webhook_receipt_id(字符串数字)对应 webhook_platform_delivery.receipt_id(唯一)。缺失则 400,提示未关联 Webhook 出库记录。 |
| 仅 DEAD 可重放 | Webhook 侧若行不存在 → 404;若状态为 PENDING/SENT → 409,避免误重置进行中或已成功任务。 |
| 重放语义 | status=PENDING,attempts=0,last_error=NULL,next_retry_at=NULL,updated_at=now(重新给满 max-attempts 次数)。 |
| 平台幂等 | 重放仅重新 HTTP 投递;若平台 Inbox 已存在同 (sourceSystem, externalMessageId),内部 ingest 返回 duplicate,不新建 Inbox(与现有幂等一致)。 |
4. 配置项
| 组件 | 属性 / 环境变量 | 说明 |
|---|---|---|
| Webhook | craftlabs.webhook.ops-token / LICENSE_WEBHOOK_OPS_TOKEN |
非空才启用 /internal/** 鉴权;空则 503 所有内部运维路径(避免误暴露)。 |
| Platform | craftlabs.webhook.base-url / LICENSE_WEBHOOK_BASE_URL |
Webhook 根协议+主机+端口。 |
| Platform | craftlabs.webhook.ops-token |
与 Webhook 相同密钥,仅驻内存。 |
Runbook:在 RUNBOOK.md §10.5 旁补充:重放前确认平台已恢复;同 receipt 不要并发多次重放(单机调度即可)。
5. 前端
- Callback 详情:展示
webhookReceiptId;若存在则显示 「重新入队出库(DEAD→待投递)」,调平台 POST;成功/失败用现有apiErrorMessage。 - 可见性:路由已为 OPS/SYS_ADMIN,与 I7 一致。
6. 契约
- 更新
contracts/openapi/delivery-platform-api.json:POST /api/v1/callback-inbox/{id}/replay-webhook-delivery与响应 DTO(如status、receiptId)。 - Webhook 内部路由 不入 对外 OpenAPI。
7. 测试与验收
| 层级 | 验收 |
|---|---|
| Webhook | 单测:replayDeadByReceiptId 对 DEAD/非 DEAD/缺行行为;集成或 MockMvc:401/503 无 token。 |
| Platform | 单测或 Mock:CallbackInboxService 在缺 receipt、Webhook 409/404 时映射 HTTP。 |
| 手工 | DEAD 一行 → 详情点重放 → 行变 PENDING → 调度成功后 SENT。 |
8. 修订记录
| 日期 | 说明 |
|---|---|
| 2026-04-06 | 初版:I8 DEAD 重放架构(平台代理 + Webhook 内部 API)。 |