docs(docs): coord 完成 15 模块 issue 仲裁与基础设施同步

coord.md 新增 ARB-019/020/021 三章仲裁章节,修正 ARB-001。

- coord.md: 新增 ARB-019/020/021(student/parent/admin-portal 24 项)
- coord.md: 修正 ARB-001(admin P2 预留/schema 文件名/classes 数据源)
- 004 §4: 依赖图加 PBFF→DataAna+Msg
- 004 §7.2: push-gateway→Redis 软失败标注
- 004 §11.4: 错误码前缀矩阵(11 服务+i18n key)
- 004 §11.5: ActionState 信封规范(降级模式方案 B)
- matrix §1: 依赖矩阵加 PBFF 边
- matrix §2: 移除 api-gateway 为 iam gRPC 消费方
- matrix §4: admin-portal→teacher-bff
- matrix §5: 移除 /sse+鉴权头统一
- matrix §6: 错误码表补 i18n key 列
- 15 个 issue.md: 仲裁结论回写
- push-gateway_contract: 移除 /sse+鉴权头改 X-Internal-Token
- packages/contracts: 新建包 ADMIN_* 权限点常量

AI: coord
This commit is contained in:
SpecialX
2026-07-10 16:30:51 +08:00
parent df62ffc176
commit c179af64a6
22 changed files with 2320 additions and 382 deletions

View File

@@ -375,6 +375,8 @@ graph TB
PBFF --> IAM
PBFF --> CoreEdu
PBFF --> DataAna
PBFF --> Msg
CoreEdu -.事件.-> Content
CoreEdu -.事件.-> DataAna
@@ -626,6 +628,12 @@ graph LR
| `edu.content.question.published` | 题目发布 | Content | AI、ES |
| `edu.insight.mastery.updated` | 掌握度更新 | DataAna | CoreEdu、Msg |
> **必需依赖软失败标注**ARB-015 §17.6ISSUE-058 覆盖 ISSUE-055
>
> - push-gateway → Redis**软失败**Redis 故障仅告警 + `degraded: true` + /readyz 返 200不返 503、不触发 Pod 重启)
> - 理由Redis 故障时单实例仍能服务本地连接(仅跨实例广播失效);重启会丢失本地连接表,加剧雪崩风险
> - ISSUE-055 必需依赖列表应排除 push-gateway → Redis
### 7.3 核心领域事件
| 事件 | 触发场景 | 消费者动作 |
@@ -955,6 +963,127 @@ graph LR
DataLoader --> S3
```
### 11.4 错误码前缀矩阵
> 来源coord 仲裁 ARB-017 §19.6 / ARB-014 / ARB-015 / ARB-018 / G14 / F4
> 规则:服务名大写 + 下划线分隔,禁止子前缀(如 EXAMS_/HOMEWORK_/GRADES_ 已移除)
| 层级 | 服务 | 前缀 | 示例 | 仲裁依据 |
| ---- | ------------ | -------------- | ------------------------------------------------------------- | -------- |
| 网关 | api-gateway | `GW_` | GW_UNAUTHORIZED / GW_RATE_LIMITED | ARB-014 |
| 网关 | push-gateway | `PUSH_` | PUSH_DEVICE_NOT_FOUND / PUSH_CHANNEL_FAILED | ARB-015 |
| BFF | teacher-bff | `BFF_TEACHER_` | BFF_TEACHER_UNAUTHORIZED / BFF_TEACHER_BAD_GATEWAY | ARB-016 |
| BFF | student-bff | `BFF_STUDENT_` | BFF_STUDENT_UNAUTHORIZED / BFF_STUDENT_VALIDATION_ERROR | ARB-017 |
| BFF | parent-bff | `BFF_PARENT_` | BFF_PARENT_CHILD_NOT_BOUND / BFF_PARENT_BAD_GATEWAY | ARB-018 |
| 业务 | iam | `IAM_` | IAM_USER_NOT_FOUND / IAM_INVALID_CREDENTIALS | ARB-003 |
| 业务 | core-edu | `CORE_EDU_` | CORE_EDU_EXAM_NOT_FOUND / CORE_EDU_GRADE_NOT_FOUND | ARB-004 |
| 业务 | content | `CONTENT_` | CONTENT_QUESTION_NOT_FOUND / CONTENT_TEXTBOOK_NOT_FOUND | ARB-005 |
| 业务 | msg | `MSG_` | MSG_NOTIFICATION_NOT_FOUND / MSG_TEMPLATE_NOT_FOUND | ARB-008 |
| 业务 | data-ana | `DATA_ANA_` | DATA_ANA_DASHBOARD_UNAVAILABLE / DATA_ANA_ANALYTICS_NOT_READY | ARB-009 |
| 业务 | ai | `AI_` | AI_GENERATION_FAILED / AI_QUOTA_EXCEEDED | ARB-010 |
**前端 i18n key 映射规则**F4 裁决):
| 服务 | i18n key 模式 | 示例 |
| ------------ | ------------------------------- | -------------------------------------- |
| api-gateway | `error.gateway.<code_snake>` | `error.gateway.unauthorized` |
| push-gateway | `error.push.<code_snake>` | `error.push.device_not_found` |
| teacher-bff | `error.bffTeacher.<code_snake>` | `error.bffTeacher.unauthorized` |
| student-bff | `error.bffStudent.<code_snake>` | `error.bffStudent.validation_error` |
| parent-bff | `error.bffParent.<code_snake>` | `error.bffParent.child_not_bound` |
| iam | `error.iam.<code_snake>` | `error.iam.user_not_found` |
| core-edu | `error.core_edu.<code_snake>` | `error.core_edu.exam_not_found` |
| content | `error.content.<code_snake>` | `error.content.question_not_found` |
| msg | `error.msg.<code_snake>` | `error.msg.notification_not_found` |
| data-ana | `error.data_ana.<code_snake>` | `error.data_ana.dashboard_unavailable` |
| ai | `error.ai.<code_snake>` | `error.ai.generation_failed` |
### 11.5 ActionState 信封规范
> 来源coord 仲裁 ARB-017 §19.6
> 适用范围:所有 BFF / Gateway HTTP 响应、GraphQL response 的 errors 扩展字段
> 设计原则:统一错误信封 + 降级模式方案 Bdegraded 放 error.details 子字段)
**信封结构**
```typescript
interface ActionState<T = unknown> {
success: boolean; // 整体成功/失败
data: T | null; // 成功时返回数据,失败时为 null
error: {
code: string; // 错误码(见 §11.4 前缀矩阵)
message: string; // 人类可读错误消息i18n key 解析后)
details?: Record<string, unknown>; // 附加详情(含 degraded 字段)
traceId: string; // 链路追踪 IDX-Request-Id
} | null; // 成功时为 null
}
```
**降级模式(方案 B**
- `success = true`(整体成功)
- `data` 内含 `extensions.degraded: true` 子字段
- `error` 仍为 null非错误
- 用于部分聚合失败场景(如 teacher-bff 聚合 iam 成功但 core-edu 失败)
**示例 1完全成功**
```json
{
"success": true,
"data": { "userId": "u001", "name": "张老师" },
"error": null
}
```
**示例 2完全失败**
```json
{
"success": false,
"data": null,
"error": {
"code": "BFF_TEACHER_BAD_GATEWAY",
"message": "下游服务不可用",
"details": { "downstream": "core-edu", "reason": "timeout" },
"traceId": "req-abc123"
}
}
```
**示例 3降级模式部分聚合成功**
```json
{
"success": true,
"data": {
"user": { "userId": "u001", "name": "张老师" },
"classes": null,
"extensions": { "degraded": true, "failedServices": ["core-edu"] }
},
"error": null
}
```
**GraphQL errors 数组扩展**
GraphQL 响应中,错误通过 `errors[].extensions` 携带 ActionState 字段:
```json
{
"errors": [
{
"message": "下游服务不可用",
"extensions": {
"code": "BFF_TEACHER_BAD_GATEWAY",
"details": { "downstream": "core-edu" },
"traceId": "req-abc123"
}
}
]
}
```
---
## 12. 架构约束