Files
huangping 5fe7181b35 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
2026-04-06 23:01:10 +08:00

123 lines
5.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 迭代 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) 复盘。 |