feat(i7): async webhook delivery queue, OPS RBAC, UI role routing; docs and runbook

- Architect: I7_DESIGN.md, I7_IMPLEMENTATION_REVIEW.md; parallel index + track B
- Backend: @EnableMethodSecurity; OPS login; CallbackInbox PreAuthorize; IntegrationCatalog triple role
- Webhook: V2 webhook_platform_delivery; planner + scheduler + single-shot forwarder; tests
- Frontend: Pinia hasAnyRole; MainLayout/HomeView/router for OPS vs dev
- Runbook §10.5 delivery config

Made-with: Cursor
This commit is contained in:
2026-04-06 23:01:10 +08:00
parent ce49fe143c
commit 5fe7181b35
33 changed files with 936 additions and 200 deletions
+122
View File
@@ -0,0 +1,122 @@
# 迭代 I7 架构设计 — 可靠投递、运营权限、前端指令
> **仓库**`craftlabs-authorization-sdk``develop`)。
> **前置**[I6 收口](./I6_CLOSEOUT.md)、[I6 实现审核](./I6_IMPLEMENTATION_REVIEW.md) §3 跟踪项。
> **角色**:迭代功能架构说明;实现以本文件为审查基线。
---
## 1. 目标与范围
| 主题 | I7 要达成 | 非目标(后置) |
| ---------------- | -------------------------------------------------------------------------------------------------- | ----------------------- |
| **Webhook → 平台** | 对比特 **2xx 后立即返回**;平台投递 **异步**、可重试、**落库可观测**(状态/次数/最后错误) | MQ、跨地域多活 |
| **运营权限** | 新增 `**OPS`****Callback Inbox**(读/改/挂接)仅 `**OPS` + `SYS_ADMIN`**`**DEVELOPER**` 保留其余业务与 **M6 只读** | 细粒度按钮与数据范围(I8+) |
| **前端** | 路由 `meta.roles` 与菜单 `**hasAnyRole`** 一致;登录页说明 `**ops/ops**` | Playwright 流水线(I7.1 可选) |
---
## 2. Webhook 侧:平台投递出站队列
### 2.1 行为
1. `**webhook_callback_receipt` 首次插入成功** 且配置了 `craftlabs.platform.internal.base-url` + token 时,写入 `**webhook_platform_delivery`**`status=PENDING`
2. **不**在 Callback HTTP 线程内同步 `RestClient` 调用平台(避免比特侧拖慢与线程占用)。
3. `**@Scheduled`** 周期拉取 `PENDING` / 可重试失败行,`POST /internal/v1/callback-events`;成功 → `SENT`;失败 → `attempts++`,指数退避 `**next_retry_at**`,超过 `**max-attempts**``DEAD`(人工/运维处理)。
4. **未配置 base-url** 时:不建队列行(与 I5「仅收据」行为一致)。
### 2.2 表(Flyway `V2__webhook_platform_delivery.sql`
| 列 | 说明 |
| ----------------------------------------- | ------------------------------------- |
| `receipt_id` | 关联收据 |
| `request_body` | 平台 API JSON 正文 |
| `trace_headers_json` | `traceparent` / `X-Request-Id` 等 JSON |
| `idempotency_key` | 头 `Idempotency-Key` 用值 |
| `status` | `PENDING` / `SENT` / `DEAD` |
| `attempts`, `last_error`, `next_retry_at` | 重试与排障 |
### 2.3 配置(示例)
| Key | 说明 |
| ----------------------------------------------- | ----------- |
| `craftlabs.platform.delivery.scheduler-enabled` | 单测可 `false` |
| `craftlabs.platform.delivery.max-attempts` | 默认 `8` |
| `craftlabs.platform.delivery.batch-size` | 每.tick 处理条数 |
---
## 3. 平台 API:角色与方法安全
### 3.1 角色
| 角色 | 用途 |
| ----------- | ----------------------------------------------------------- |
| `SYS_ADMIN` | 全量(含 Callback |
| `OPS` | **仅** Callback Inbox + 与运营配套能力;**不**开放合同/交付等业务写路径(由路由与菜单裁剪) |
| `DEVELOPER` | 业务+M6 只读;**不**含 Inbox |
### 3.2 安全模型
- `**@EnableMethodSecurity`** + `**@PreAuthorize**` 扛后端契约。
- `**CallbackInboxController**``hasAnyRole('OPS','SYS_ADMIN')`
- `**IntegrationCatalogController**``hasAnyRole('OPS','SYS_ADMIN','DEVELOPER')`
- JWT 仍由 `[JwtAuthenticationFilter](../../../services/delivery-platform-api/src/main/java/cn/craftlabs/platform/api/security/JwtAuthenticationFilter.java)` 注入 `ROLE_*`
### 3.3 演示账号
| 用户 | 密码 | 角色 |
| ------- | ------- | ----------- |
| `admin` | `admin` | `SYS_ADMIN` |
| `dev` | `dev` | `DEVELOPER` |
| `ops` | `ops` | `OPS` |
---
## 4. 前端(`delivery-platform-ui`
### 4.1 路由 `meta.roles`
| 区域 | `meta.roles` |
| ------------------------------ | ------------------------------- |
| 首页及以下业务(客户/项目/合同/交付/SN) | `SYS_ADMIN`, `DEVELOPER` |
| `/callbacks`, `/callbacks/:id` | `SYS_ADMIN`, `OPS` |
| `/integration/*` | `SYS_ADMIN`, `DEVELOPER`, `OPS` |
### 4.2 菜单与首页
- **Pinia** `hasAnyRole(roles)`**MainLayout** / **HomeView** 按角色显示入口,避免 OPS 误以为可点业务页。
---
## 5. 测试与 DoD
| 项 | 标准 |
| ------- | ----------------------------------------------------------------------------------- |
| 平台 | `CallbackInboxControllerTest``DEVELOPER` 访问 Inbox → **403**`SYS_ADMIN`/`OPS` 仍可走通 |
| Webhook | 配置 base-url 时 **enqueue** 产生 `PENDING` 行;单测关闭 scheduler 避免后台线程 |
| 前端 | `npm run build` 通过 |
---
## 6. 修订记录
| 日期 | 说明 |
| ---------- | ---------------------------- |
| 2026-04-06 | I7 初版:异步投递表 + OPS + 前端路由/菜单。 |
| 2026-04-06 | 闭环:实现与 [I7_IMPLEMENTATION_REVIEW.md](./I7_IMPLEMENTATION_REVIEW.md) 复盘。 |