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. 架构约束

View File

@@ -18,7 +18,7 @@
### 1.2 HTTP 端点
| Method | Path | 用途 | 认证 | 请求体 | 响应 |
| ------ | --------------------------- | -------------------------------------- | --------------------------------------------- | ----------------------------------------------------------- | ----------------------------------------------------------- |
| ------ | --------------------------- | ---------------------------------- | ----------------------------------------------- | ------------------------------ | ----------------------------------------------------------- |
| GET | /ws | WebSocket 升级端点(实时推送通知) | JWT RS256query `?token=``Authorization` | — | 升级为 WebSocket 长连接 |
| POST | /internal/push | 内部单推接口msg 服务触发) | `X-Internal-Token` 头 | `{user_id, event, data, ttl?}` | `{success, delivered, online}` |
| POST | /internal/broadcast | 内部广播接口msg 服务触发) | `X-Internal-Token` 头 | `{event, data, filter?}` | `{success, reached}` |
@@ -27,19 +27,25 @@
| GET | /readyz | 就绪检查readiness | 公开 | — | `{status, degraded?}`Redis/Kafka 软失败时 degraded:true |
| GET | /metrics | Prometheus 指标端点 | 公开(内网) | — | Prometheus 文本格式 |
**ISSUE-001 仲裁项**
- ~~`GET /sse`~~02 文档 §10 建议不支持contract v1 列出但与 02 冲突,待 coord 仲裁移除)
**SSE 端点裁决**ARB-015 §17.3ISSUE-001 已裁决)
**待 ISSUE-002 仲裁项**
- 内部 API 鉴权头命名:本契约采用 `X-Internal-Token`(对齐总裁裁决 §7.2);现码为 `X-Internal-Key`,待仲裁确认后统一
- ❌ 不支持 `GET /sse`(仅 WebSocket /ws删除 contract v1 的 /sse 行02 文档 §10 正确)
- 理由:简化实现 + 统一推送通道 + WebSocket 双向通信能力更强
**鉴权头裁决**ARB-015 §17.3ISSUE-002 已裁决):
- 统一采用 `X-Internal-Token` 头(对齐总裁裁决 §7.2
- 现码 `X-Internal-Key` 需 ai02 统一为 `X-Internal-Token`
**`X-Internal-Token` 校验机制**
- 启动时从 `INTERNAL_API_TOKEN` 环境变量加载
- 与 msg 服务共享同一密钥K8s Secret 注入)
- DevMode`DEV_MODE=true`)下跳过校验,便于本地联调
- 缺失/不匹配 → 401 + `PUSH_UNAUTHORIZED`
**响应语义**/internal/push
- `delivered: true`:本实例或跨实例成功投递到至少一个连接
- `online: false`用户离线msg 应走离线推送SMS/邮件)
- `delivered: false, online: true`:投递失败(连接满/异常msg 应重试或落库
@@ -81,10 +87,12 @@
```
**客户端 → 服务端**
- WebSocket Ping 控制帧心跳30s 间隔,非文本消息)
- 重连时:`GET /ws?token=&session_id=<id>&last_seq=<n>`P6 实现)
**心跳规则**RFC 6455 控制帧):
- 客户端每 30s 发送 Ping
- 服务端自动回 Ponggorilla/websocket 默认)
- 服务端 `SetReadDeadline(60s)`60s 无消息则关闭连接
@@ -102,13 +110,14 @@
### 2.2 Kafka 事件订阅(异步)
| Topic | Event | 发布方 | mock 策略 |
| ------------------------------ | ------------------------ | ---------- | --------------------------------------------------------------------------- |
| ---------------------------- | --------------------- | ---------- | --------------------------------------------------------------------------- |
| `edu.notification.requested` | NotificationRequested | msg (ai10) | msg 就绪前不订阅,使用本地定时器每 30 秒推送 1 条 mock 通知到所有在线客户端 |
> **topic 命名对齐 ISSUE-053 裁决**[president-final-rulings.md](../president-final-rulings.md) §1.5):禁止抽象名 `edu.*.events`,统一 `edu.<domain>.<aggregate>.<action>` 格式。
> 原 contract v1 写的 `edu.msg.notification.events` 已废弃。
**消费语义**
- Consumer Group`push-gateway`
- 至少一次at-least-once消费失败重试 3 次后入死信队列
- 幂等性:基于 `event_id` Redis SETNX 去重TTL 24h
@@ -116,13 +125,13 @@
### 2.3 HTTP 调用(如有)
| 调用方 | Method | Path | 用途 | 时机 |
| -------------- | ------ | --------------------------------- | --------------------------------- | ---------- |
| ------------ | ------ | --------------------------- | --------------------------------- | ---------- |
| push-gateway | GET | `iam/.well-known/jwks.json` | 拉取 RS256 公钥校验 WebSocket JWT | iam 就绪后 |
### 2.4 Redis 协议
| 用途 | 数据结构 | Key 模式 | TTL |
| -------------------- | --------------- | ------------------------------------ | --------------- |
| ---------------------- | --------------- | ------------------------------------ | --------------- |
| 在线用户所在实例集合 | SET | `edu:push:online:<userID>` | 60s心跳续期 |
| 单连接元数据 | HASH | `edu:push:session:<userID>:<connID>` | 60s |
| 跨实例定向推送 channel | Pub/Sub channel | `edu:push:channel:user:<userID>` | — |
@@ -134,7 +143,7 @@
### 2.5 内部接口msg 调用 push-gateway
| 被调用方 | Method.Path | 用途 | 说明 |
| ------------ | ------------------------ | ------------------ | ---------------------------------------- |
| ------------ | ----------------------------- | ------------------ | ------------------------------------------ |
| push-gateway | POST /internal/push | msg 服务单用户推送 | msg 渲染模板后定向推送给目标用户 |
| push-gateway | POST /internal/broadcast | msg 服务批量推送 | msg 收到业务事件后渲染模板,调此接口广播 |
| push-gateway | GET /internal/online/<userID> | msg 查在线状态 | msg 决定走在线推送还是离线推送SMS/邮件) |
@@ -188,7 +197,7 @@
## §5 与 02 文档、现码、总裁裁决的对齐说明
| 维度 | 现 code | 02 文档 | 总裁裁决 | 本 contract 采用 | 对齐任务 |
| ---- | ------- | ------- | -------- | ---------------- | -------- |
| ---------------------- | ------------------ | ------------------------- | --------------------------------------------- | ----------------------------- | ------------------------------------------ |
| 内部端点路径 | `/internal/push` | `/internal/push` | §4.2 as-is 采纳 02 §4.2 | `/internal/push` | ✅ 已对齐v1 写 `/internal/send` 已修正) |
| 鉴权头名 | `X-Internal-Key` | `X-Internal-Token` | §7.2 "X-Internal-Token 重命名" | `X-Internal-Token` | 待 ISSUE-002 仲裁后改代码 |
| 鉴权环境变量 | `INTERNAL_API_KEY` | `INTERNAL_API_TOKEN` | §7.2 | `INTERNAL_API_TOKEN` | 待 ISSUE-002 仲裁后改代码 |
@@ -206,6 +215,6 @@
## §6 变更历史
| 版本 | 日期 | 变更内容 | 变更依据 |
| ---- | ---------- | ------------------------------------------------------------------------ | ------------------------------------- |
| ---- | ---------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- |
| v1 | 2026-07-09 | 初始版本coord 生成) | — |
| v2 | 2026-07-10 | topic 改 `edu.notification.requested`/internal/send → /internal/push鉴权 mTLS → X-Internal-Token移除 /sse待仲裁新增 /internal/online新增 §5 对齐表 | ISSUE-053/055/056/058 + 总裁 §4.2/§7.2 |

File diff suppressed because it is too large Load Diff

View File

@@ -63,6 +63,8 @@ graph TB
PBFF --> IAM
PBFF --> CORE
PBFF --> DATA
PBFF --> MSG
PGW --> MSG
@@ -82,8 +84,8 @@ graph TB
## §2 gRPC 接口提供方矩阵
| 提供方 | gRPC 端口 | Service | RPC 数 | 消费方 | 就绪信号 | 状态 |
| --------------- | --------- | --------------------------------------------------------------------------------- | ------ | ---------------------------------------------------- | ----------------------------- | ---- |
| iam (ai06) | 50052 | IamService | 12 | teacher-bff / student-bff / parent-bff / api-gateway | HealthService.Check = SERVING | ⏳ |
| --------------- | --------- | --------------------------------------------------------------------------------- | ------ | ------------------------------------------- | ----------------------------- | ---- |
| iam (ai06) | 50052 | IamService | 12 | teacher-bff / student-bff / parent-bff | HealthService.Check = SERVING | ⏳ |
| core-edu (ai08) | 50053 | ClassService + ExamService + HomeworkService + GradeService + AttendanceService | 22 | teacher-bff / student-bff / parent-bff | HealthService.Check = SERVING | ⏳ |
| content (ai09) | 50054 | TextbookService + ChapterService + KnowledgeGraphService + QuestionService | 18 | teacher-bff / student-bff / ai | HealthService.Check = SERVING | ⏳ |
| data-ana (ai11) | 50055 | AnalyticsService | 12 | teacher-bff / student-bff / parent-bff / ai | HealthService.Check = SERVING | ⏳ |
@@ -108,7 +110,7 @@ graph TB
| --------------- | --------------------------- | ----------------------------------------------------- | --------------------------------------------------------- | ------- | ---- |
| iam (ai06) | edu.iam.user.events | UserEventcreated/updated/deleted/role_changed | core-edu / msg / push-gateway / teacher-bff / student-bff | ✅ | ⏳ |
| iam (ai06) | edu.iam.role.events | RoleEventcreated/updated | core-edu / msg | ✅ | ⏳ |
| iam (ai06) | edu.iam.audit.created | AuditEventcreate/update/delete/login/logout | admin-portal | ✅ | ⏳ |
| iam (ai06) | edu.iam.audit.created | AuditEventcreate/update/delete/login/logout | teacher-bff | ✅ | ⏳ |
| core-edu (ai08) | edu.exam.events | ExamEventcreated/updated/deleted | msg / data-ana / push-gateway | ✅ | ⏳ |
| core-edu (ai08) | edu.homework.events | HomeworkEventassigned/submitted/graded | msg / data-ana / push-gateway | ✅ | ⏳ |
| core-edu (ai08) | edu.grade.events | GradeEventrecorded/updated | msg / push-gateway / parent-bff | ✅ | ⏳ |
@@ -124,14 +126,13 @@ graph TB
## §5 HTTP 接口矩阵(非 gRPC / 非 GraphQL
| 提供方 | Method | Path | 用途 | 消费方 | 认证 | 状态 |
| ------------------- | ------ | ----------------- | -------------------- | ----------------------------------------------- | -------------- | ---- |
| ------------------- | ------ | ----------------- | -------------------- | -------------------------------------------------------------- | ---------------- | ---- |
| api-gateway (ai01) | * | /api/v1/teacher/* | 反向代理 teacher-bff | teacher-portal | JWT | ⏳ |
| api-gateway (ai01) | * | /api/v1/student/* | 反向代理 student-bff | student-portal | JWT | ⏳ |
| api-gateway (ai01) | * | /api/v1/parent/* | 反向代理 parent-bff | parent-portal | JWT | ⏳ |
| api-gateway (ai01) | * | /api/v1/iam/* | 反向代理 iam | (内部) | JWT | ⏳ |
| push-gateway (ai02) | WS | /ws | WebSocket 推送通道 | teacher-portal / student-portal / parent-portal | JWT | ⏳ |
| push-gateway (ai02) | SSE | /sse | SSE 推送通道 | teacher-portal | JWT | ⏳ |
| push-gateway (ai02) | POST | /internal/push | 内部推送入口 | msg | X-Internal-Key | ⏳ |
| push-gateway (ai02) | WS | /ws | WebSocket 推送通道 | teacher-portal / student-portal / parent-portal / admin-portal | JWT | ⏳ |
| push-gateway (ai02) | POST | /internal/push | 内部推送入口 | msg | X-Internal-Token | ⏳ |
| iam (ai06) | GET | /healthz | 存活检查 | k8s / 监控 | 无 | ⏳ |
| iam (ai06) | GET | /readyz | 就绪检查5 依赖) | k8s / 监控 | 无 | ⏳ |
| 所有服务 | GET | /metrics | Prometheus 指标 | Prometheus | 无 | ⏳ |
@@ -140,19 +141,21 @@ graph TB
## §6 错误码前缀矩阵
| 模块 | 前缀 | 示例 |
| ------------ | --------- | -------------------------------------------------- |
| api-gateway | GW_ | GW_UNAUTHORIZED / GW_RATE_LIMITED |
| push-gateway | PUSH_ | PUSH_DEVICE_NOT_FOUND / PUSH_CHANNEL_FAILED |
| teacher-bff | BFF_XXX_ | BFF_TEACHER_UNAUTHORIZED / BFF_TEACHER_BAD_GATEWAY |
| student-bff | BFF_XXX_ | BFF_STUDENT_UNAUTHORIZED |
| parent-bff | BFF_XXX_ | BFF_PARENT_CHILD_NOT_BOUND |
| iam | IAM_ | IAM_USER_NOT_FOUND / IAM_INVALID_CREDENTIALS |
| core-edu | CORE_EDU_ | CORE_EDU_EXAM_NOT_FOUND |
| content | CONTENT_ | CONTENT_QUESTION_NOT_FOUND |
| msg | MSG_ | MSG_NOTIFICATION_NOT_FOUND |
| data-ana | DATA_ANA_ | DATA_ANA_DASHBOARD_UNAVAILABLE |
| ai | AI_ | AI_GENERATION_FAILED / AI_QUOTA_EXCEEDED |
> 详见 [004 §11.4](../004_architecture_impact_map.md) 错误码前缀矩阵 + i18n key 映射规则
| 模块 | 前缀 | i18n key 模式 | 示例 |
| ------------ | ------------ | ------------------------------- | -------------------------------------------------- |
| api-gateway | GW_ | error.gateway.\<code_snake\> | GW_UNAUTHORIZED / GW_RATE_LIMITED |
| push-gateway | PUSH_ | error.push.\<code_snake\> | PUSH_DEVICE_NOT_FOUND / PUSH_CHANNEL_FAILED |
| teacher-bff | BFF_TEACHER_ | error.bffTeacher.\<code_snake\> | BFF_TEACHER_UNAUTHORIZED / BFF_TEACHER_BAD_GATEWAY |
| student-bff | BFF_STUDENT_ | error.bffStudent.\<code_snake\> | BFF_STUDENT_UNAUTHORIZED |
| parent-bff | BFF_PARENT_ | error.bffParent.\<code_snake\> | BFF_PARENT_CHILD_NOT_BOUND |
| iam | IAM_ | error.iam.\<code_snake\> | IAM_USER_NOT_FOUND / IAM_INVALID_CREDENTIALS |
| core-edu | CORE_EDU_ | error.core_edu.\<code_snake\> | CORE_EDU_EXAM_NOT_FOUND |
| content | CONTENT_ | error.content.\<code_snake\> | CONTENT_QUESTION_NOT_FOUND |
| msg | MSG_ | error.msg.\<code_snake\> | MSG_NOTIFICATION_NOT_FOUND |
| data-ana | DATA_ANA_ | error.data_ana.\<code_snake\> | DATA_ANA_DASHBOARD_UNAVAILABLE |
| ai | AI_ | error.ai.\<code_snake\> | AI_GENERATION_FAILED / AI_QUOTA_EXCEEDED |
---

View File

@@ -30,7 +30,7 @@
ARB-001/ARB-002 均未明确仲裁以下三项,而它们直接影响 admin-portal 实现,建议 coord 补充裁决:
| 待裁决项 | 当前依据 | 影响 |
| -------- | -------- | ---- |
| --------------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------- |
| admin-portal 端口 | matrix.md / ai-allocation.md = 4003 | 01/02 文档误用 3003与 teacher-bff 冲突) |
| admin-portal 是否消费 push-gateway WebSocket | 同类 portalparent-portal契约 = 消费 | 01/02 文档误声明"不消费推送" |
| 审计日志消费机制iam Kafka → teacher-bff → GraphQL auditLogs | matrix.md §4 列 admin-portal 为 edu.iam.audit.created 消费方 | 前端不直连 Kafka需经 teacher-bff 聚合matrix.md 表述不精确 |
@@ -106,4 +106,16 @@ ARB-001/ARB-002 均未明确仲裁以下三项,而它们直接影响 admin-por
## §1 历史问题
(暂无已裁决问题)
### 1.1 仲裁结论汇总coord 2026-07-10
> 详见 [coord.md §23 ARB-021](../coord.md) 完整仲裁章节
| ISSUE | 标题 | 仲裁结论摘要 | 执行方 |
| ----- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
| 001 | 01/02 模块文档归属错误ai07 → ai16 | ✅ 修正为 ai16ai07 产出视为历史草稿 | ai16 修 01/02 头部 |
| 002 | 01/02 端口错误3003 → 4003 | ✅ 确认 admin-portal 端口 4003同步更新 full-stack-runbook §2.1 补齐 4 个 portal 4000 段 | ai16 修 01/02 + coord 修 runbook |
| 003 | 01/02 通信协议与 ARB-001/002 不一致REST → GraphQL | ✅ 统一 GraphQL`POST /api/admin/graphql` → teacher-bff admin 命名空间);删除 useApi/ApiClient | ai16 修 01/02 全文 |
| 004 | 01/02 遗漏审计日志与学校设置 | ✅ 视口补齐为 11 个dashboard/users/roles/permissions/viewports/organization/classes/teachers/students/audit-logs/system | ai16 修 01/02 |
| 005 | teacher-bff 缺 admin 命名空间 GraphQL schema | ✅ ai03 在 P6 启动前补齐 teacher-bff admin 命名空间 schema参照 contract §2.4 | ai03 补 schema |
| 006 | 01/02 推送策略与同类 portal 不一致(轮询 → WebSocket | ✅ admin-portal 接入 push-gateway WebSocket审计告警/异常登录/系统异常);保留轮询仅用于监控指标 | ai16 修 01/02 |
| 007 | matrix.md §4 将 admin-portal 列为 Kafka 直消费方 | ✅ 修正为 teacher-bffadmin-portal 经 teacher-bff 间接消费链路iam → Kafka → teacher-bff → GraphQL → admin-portal | coord 修 matrix.md §4 |

View File

@@ -11,7 +11,7 @@
> 任务要求对已有的仲裁进行核查。coord.md 当前仅含 ARB-001 / ARB-002另在 [port-allocation.md](../../../../infra/port-allocation.md) §7、coord-final-decisions.md、president-final-rulings.md 中存在涉及 ai 的历史仲裁。逐项核查如下。
| 仲裁编号 / 来源 | 主题 | 涉及 ai | 核查结论 | 状态 |
| -------------------------- | ----------------------------------------- | --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------- |
| ---------------------------------------------------------- | ------------------------------------------ | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
| ARB-001coord.md §1 | teacher-bff GraphQL schema 第一版 | ❌ 否 | 与 ai 无关,不适用。 | — |
| ARB-002coord.md §2 | MF Shell 暴露清单 | ❌ 否 | 与 ai 无关,不适用。 | — |
| port-allocation.md §7 | 50058 让给 aipush-gateway 豁免 gRPC | ✅ 是 | **仲裁有效**port-allocation.md §3/§5 已登记 ai = HTTP 3008 / gRPC 50058。ai 的 01/02 文档已按 50058 设计,一致。**但 [matrix.md](../matrix.md) §2 gRPC 接口提供方矩阵、§8 就绪信号跟踪表仍写 50057未同步** → 提请 coord 同步(见 ISSUE-01 | ⚠️ 仲裁有效但未同步 |
@@ -46,6 +46,7 @@
- contracts/ai_contract.md §1.4`edu.ai.usage.events`
events.proto 现状无 `AIUsageEvent` message004 无 topic 记录。三义导致 data-ana 消费方无法对齐。
- **建议方案**ai12 建议采用 `edu.ai.usage`(与 matrix.md 一致,最简短,符合 `edu.<domain>.<action>` 简洁约定)。请 coord 裁定并在 004 §7.2 补登 + events.proto 补 `AIUsageEvent` messageschema 见 02-architecture-design.md §3.3。ai12 据裁决同步 01/02 文档与 contract。
- **状态**:待 coord 仲裁
@@ -60,6 +61,7 @@
- `ChatRequest` 扩展可选字段user_id / session_id / data_scope
关于 RPC 总数存在分歧matrix.md §2 与 contract 写 6 RPC02-architecture-design.md §4.2 单方面扩到 8 RPC追加 GetLessonPlanStatus / ConfirmLessonPlan。需 coord 裁定 P5 目标 RPC 清单。
- **建议方案**ai12 建议 P5 目标 6 RPCChat / StreamChat / GenerateQuestion / StreamGenerateQuestion / OptimizeExpression / GenerateLessonPlan。备课工作流的"查询状态/确认入库"用 HTTP 端点(`GET /ai/v1/lesson/preparation/{id}` + `POST .../confirm`)实现,避免 RPC 膨胀;如 coord 认为查询/确认也需 gRPC则定为 8 RPC。请 coord 在 P5 启动前升级 ai.proto 到 v1 完整版。
- **状态**:待 coord 仲裁
@@ -121,7 +123,25 @@
- **类型**:架构约束
- **描述**004 §11.5 强制响应信封为 ActionState`{success, data, error:{code,message,details,traceId}}`。ai 当前 main.py 违反:返回 `{success:true, data:..., degraded:false}` 顶层 degraded 字段(见 main.py:89/201-210/233-244。01/02 文档已提请A5contracts 未记录。P5 实施必须整改。
- **建议方案**P5 实施时所有 HTTP 端点 + gRPC RPC 返回值改为 ActionStatedegraded 作为 `error.details.degraded` 子字段。请 coord 在 known-issues §2.9 ai 分区记录此约束01 文档已提请,需 coord 落地 known-issues
- **状态**待 coord 在 known-issues 记录约束(整改由 ai12 P5 执行
- **状态**已裁决(见 [coord.md §12 ARB-010](../coord.md#12-arb-010ai-模块-9-项-issue-仲裁)
---
## §1 仲裁结论2026-07-10 coord
> 详见 [coord.md §12 ARB-010](../coord.md#12-arb-010ai-模块-9-项-issue-仲裁)
| ISSUE | 仲裁结论 | 执行方 |
| ----- | ---------------------------------------------------------------------- | ------------ |
| 01 | ✅ 统一端口 50058coord 修 matrix.md | coord |
| 02 | ✅ 统一 `edu.ai.usage`ARB-013 | coord |
| 03 | ✅ P5 目标 6 RPC备课状态查询/确认用 HTTPARB-012 | coord |
| 04 | ✅ coord 补全 events.proto AIUsageEventARB-011 | coord |
| 05 | ✅ ai12 自纠重写 contract端口 50058 / 补 HTTP / topic / 错误码对齐) | ai12 |
| 06 | ✅ P5 用 BackgroundTasks + RedisP6 评估 Temporal | ai12 + coord |
| 07 | ✅ coord 批次 0 补全 iam.proto 12 RPCARB-007 | coord |
| 08 | ✅ 统一 `next_edu_cloud.<domain>.v1`ARB-011 | coord |
| 09 | ✅ P5 强制整改 ActionStatedegraded 移至 error.details | ai12 |
---

View File

@@ -13,7 +13,7 @@
### 0.1 coord-final-decisions.md N1-N5 核查
| 编号 | 仲裁结论 | 02-architecture-design.md 落实位置 | 核查结果 |
| ---- | ----------------------------------------------------------------------- | ------------------------------------------------ | -------- |
| ---- | -------------------------------------------- | ----------------------------------------------- | --------- |
| N1 | P4 首次实现即启用 gRPC server 50054 | §1.2 入口 HTTP 3005 / gRPC 50054§4.2 gRPC API | ✅ 已落实 |
| N2 | 首次实现即检查 DB/Neo4j/Kafka | §6.6 /readyz 多依赖检查 | ✅ 已落实 |
| N3 | P4 即补全 QuestionService proto不等到 P5 | §4.2.4 QuestionService 6 RPC | ✅ 已落实 |
@@ -23,7 +23,7 @@
### 0.2 01-understanding.md §A 已裁决项核查
| 原编号 | 仲裁结论 | 02-architecture-design.md 落实位置 | 核查结果 |
| ------ | --------------------------------------------------------------------- | ----------------------------------------- | -------- |
| ------ | ------------------------------------------ | ------------------------------------------------------- | --------- |
| C2 | P4 必须引入 Outbox004 §12.2 强制条款) | §3.1.5 content_outbox_events 表 + §5.4 Outbox Publisher | ✅ 已落实 |
| C4 | P4 必须实现 gRPC controller | §4.2 gRPC API4 个 Service | ✅ 已落实 |
| C10 | proto 包名保持 `next_edu_cloud.content.v1` | —(保持现状) | ✅ 已落实 |
@@ -87,10 +87,10 @@ N1-N5 与 C2/C4/C10 共 8 项已有仲裁**全部在 02-architecture-design.md
| KnowledgeGraphService | 4 | 4 | — |
| QuestionService | 6无 Publish/Search | 7含 Publish/Search | — |
| **合计** | **18** | **18** | **18** |
- design doc 缺 QuestionService.PublishQuestion / SearchQuestionscontract 有)
- contract 缺 TextbookService.Update/Deletedesign doc 有)
- design doc ChapterService 缺 Updatecontract 有contract ChapterService 缺 Deletedesign doc 也缺)
- **建议方案**:以 contract.md 为契约唯一源(已对齐 matrix.md 18 RPC 总数),反向修正 design doc
1. TextbookService 补 Update/Delete与 contract 对齐)
2. ChapterService 补 Update + Deletedesign doc + contract 都缺 Delete需补
@@ -174,7 +174,7 @@ N1-N5 与 C2/C4/C10 共 8 项已有仲裁**全部在 02-architecture-design.md
## §2 待 coord 仲裁项汇总
| # | 标题 | 阻塞性 | 状态 |
| ---- | -------------------------------------------- | ----------------------- | ------------ |
| --- | ---------------------------------------- | ------------------- | ------------- |
| 001 | REST 端点设计与实现不一致 | 🟡 P4 重构时对齐 | 待 coord 仲裁 |
| 002 | 事件 topic 命名策略冲突(独立 vs 聚合) | 🔴 阻塞 Outbox 实现 | 待 coord 仲裁 |
| 003 | Textbook/Chapter 事件在契约文档遗漏 | 🟡 契约完整性 | 待 coord 仲裁 |
@@ -185,3 +185,22 @@ N1-N5 与 C2/C4/C10 共 8 项已有仲裁**全部在 02-architecture-design.md
| 008 | 缓存策略与 API 版本化策略缺失 | 🟢 长远架构 | 待 coord 仲裁 |
| 009 | knowledge-points schema 实际缺字段 | 🟡 P4 schema 迁移 | 待 coord 仲裁 |
| 010 | Sync Worker 链路与 P4 阶段不必要 | 🟡 设计澄清 | 待 coord 仲裁 |
---
## §3 仲裁结论2026-07-10 coord
> 详见 [coord.md §5 ARB-005](../coord.md#5-arb-005content-模块-10-项-issue-仲裁)
| ISSUE | 仲裁结论 | 执行方 |
| ----- | ------------------------------------------------------------------------------ | -------------------------------- |
| 001 | ✅ P4 重构统一 query 参数风格 + 补 DELETE prerequisite 端点 | ai09 |
| 002 | ✅ 采用聚合 topic + action 字段策略4 聚合 topic | ai09 + coord |
| 003 | ✅ 补登记 edu.content.textbook.events + chapter.events | ai09 已补 + coord 同步 matrix.md |
| 004 | ✅ 统一为 21 RPCTextbook 5 + Chapter 5 + KG 4 + Question 7 | ai09 + coord |
| 005 | ✅ 删除 core-edu 失效事件条目;联动改用 gRPC 调用 | ai09 |
| 006 | ✅ 遵循总裁裁决trunk-based development措辞优化 | ai09 |
| 007 | ✅ `created_by varchar(32) NOT NULL DEFAULT 'system'` | ai09 |
| 008 | ✅ P4 补缓存策略 + API 版本化说明 | ai09 |
| 009 | ✅ P4 迁移补齐 difficulty/metadata/created_at/updated_at | ai09 |
| 010 | ✅ ES Sync Worker 标 P5Neo4j Sync Worker 仅 Outbox 输入;移除 safeCreateNode | ai09 |

View File

@@ -15,7 +15,7 @@
### 0.1 已核查通过的仲裁
| 仲裁编号 | 位置 | 核查结论 |
| -------- | ---- | -------- |
| ------------------------------ | ----------------------------------------------------------------------- | ------------------------------------------------------ |
| coord-cross-review §3.1 | topic 命名统一为 `edu.teaching.<aggregate>.<action>` | ✅ 仲裁真实存在结论准确core-edu 01/02 文档引用正确 |
| coord-cross-review §5.5 | 错误码前缀 `CORE_EDU_*` 统一(不再细分 `EXAMS_`/`HOMEWORK_`/`GRADES_` | ✅ 仲裁真实存在,结论准确 |
| coord-cross-review §5.7 | ActionState 信封结构统一 | ✅ 仲裁真实存在core-edu GlobalErrorFilter 已对齐 |
@@ -73,6 +73,7 @@
- SubmitHomeworkRequest 缺 `answers` 字段02 文档 §4.2 要求含完整 answers
缺失 P3 新增 RPC`PublishExam` / `SubmitExam` / `GradeExam` / `GradeHomework` / `UpdateGrade`。
- **影响**
1. 01-understanding.md L48 仅声称缺 AttendanceService遗漏了 ClassService 也缺失
2. matrix.md §2 声称 core-edu 22 RPC但实际 proto 仅 14 RPC5+4+5
@@ -109,6 +110,7 @@
3. **缺 `schema_version` 字段**:所有 Event messageClassEvent/ExamEvent/HomeworkEvent/GradeEvent均无 `schema_version` 字段。coord §3.1 仲裁 + known-issues §1.3 + 01-understanding.md L67 + 02-architecture-design.md §5.1 均要求事件 payload 含 `schema_version`,但 proto 未定义。
4. **matrix.md §4 与 coord §3.1 仲裁不一致**matrix.md §4 Kafka 事件发布方矩阵仍列 `edu.exam.events` / `edu.homework.events` / `edu.grade.events` / `edu.class.events`,未同步 coord §3.1 仲裁后的 `edu.teaching.*` 命名。
- **影响**
- core-edu 修改 TOPIC_MAP 后,发布到 `edu.teaching.*` topic但 events.proto 注释和 matrix.md 仍记录旧 topic下游 AI 文档被误导
- 缺 AttendanceEvent message 导致 AttendanceService 无事件契约可发布
@@ -133,12 +135,13 @@
02-architecture-design.md 定义的状态命名与 [coord.md](../coord.md) §1.2 GraphQL schema 枚举不一致:
| 维度 | 02-architecture-design.mdcore-edu | coord.md §1.2 GraphQL schemateacher-bff | 不一致点 |
| ---- | ------------------------------------- | ------------------------------------------- | -------- |
| ---------------------------- | --------------------------------------------------------------------------- | --------------------------------------------------------------- | ------------------------------------------------------------------------ |
| ExamStatus | `draft / published / in_progress / grading / graded / archived / cancelled` | `DRAFT / PUBLISHED / IN_PROGRESS / GRADING / SCORED / ARCHIVED` | core-edu 用 `graded`coord GraphQL 用 `SCORED`core-edu 多 `cancelled` |
| SubmissionStatusexam | `in_progress / submitted / graded` | `NOT_SUBMITTED / SUBMITTED / GRADED` | core-edu 用 `in_progress`coord 用 `NOT_SUBMITTED` |
| SubmissionStatushomework | `draft / submitted / graded` | `NOT_SUBMITTED / SUBMITTED / GRADED` | core-edu exam 用 `in_progress`homework 用 `draft`,自身也不一致 |
02 文档 §3.1.1 exam_submissions.status 注释 `in_progress / submitted / graded`§3.1.2 homework_submissions.status 注释 `draft / submitted / graded`**core-edu 内部 exam 与 homework 的初始状态命名也不一致**`in_progress` vs `draft`)。
- **影响**
- teacher-bff GraphQL schema 枚举值与 core-edu DB status 字段值无法直接映射BFF 需要转换层
- 前端展示需处理两套命名
@@ -161,12 +164,13 @@
`class.transferred` 事件的 topic 命名在三处文档不一致:
| 文档 | topic 命名 |
| ---- | ---------- |
| ------------------------------------------------------------- | ----------------------------------------------------- |
| 01-understanding.md L64 / 02-architecture-design.md §5.1 / §7 | `edu.org.class.created`(合并后归 org 域) |
| matrix.md §4 | `edu.class.events`ClassEventaction: transferred |
| events.proto L13 注释 | `edu.class.events` |
core-edu 文档声称"classes 合并后归 org 域"用 `edu.org.class.created`,但 coord 维护的 matrix.md 和 events.proto 仍用 `edu.class.events`。
- **影响**
- core-edu 按 `edu.org.class.created` 实现 TOPIC_MAP 后matrix.md 记录的 `edu.class.events` topic 下游消费者订阅不上
- 命名归类不一致org 域 vs class 域)
@@ -188,12 +192,13 @@
core-edu gRPC RPC 数量在三处文档统计不一致:
| 文档 | RPC 数 | 包含 ClassService | 包含 P3 新增 RPC |
| ---- | ------ | ----------------- | ---------------- |
| ------------------------------ | ------ | ----------------- | ------------------------------------------------------------------- |
| matrix.md §2 | 22 | ✅ 是4 RPC | ❌ 否P2 基线) |
| 02-architecture-design.md §4.2 | 22 | ❌ 否 | ✅ 是PublishExam/SubmitExam/GradeExam/GradeHomework/UpdateGrade |
| core-edu_contract.md §1.1 | 22 | ✅ 是4 RPC | ❌ 否P2 基线) |
P3 全量应为ClassService 4 + ExamService 85+3 新增)+ HomeworkService 54+1 新增)+ GradeService 65+1 新增)+ AttendanceService 4 = **27 RPC**。
- **影响**
- matrix.md §2 声明 22 RPC 但含 ClassService02 文档声明 22 RPC 但不含 ClassService下游 AI 无法判断应实现多少 RPC
- 就绪信号"core-edu gRPC 50053 + 22 RPC"含义模糊
@@ -215,7 +220,7 @@
02-architecture-design.md §13.3 列出 7 项未决设计决策ai08 尚未正式提请 coord 仲裁,现集中提请:
| # | 决策点 | ai08 倾向 |
| - | ------ | --------- |
| --- | ---------------------------------------- | ---------------------------- |
| 1 | classes 服务合并到 core-edu 的时机 | (a) P3 初期合并 |
| 2 | 排课 room_id 是否 P3 实现 | (b) 仅预留字段 |
| 3 | 成绩计算公式 scope 优先级 | (a) class > subject > school |
@@ -225,6 +230,7 @@
| 7 | archived 考试数据是否物理迁移 | (b) P3 仅软删除 |
注:决策 #4 与 02 文档 §3.1.2 homework 表 `gracePeriod: int("grace_period").notNull().default(0)` 默认 0 不一致,仲裁后需统一 schema 默认值。
- **影响**
- 决策未定core-edu P3 实现无法启动
- 决策 #4 schema 默认值与倾向不一致,仲裁前可能实现错
@@ -246,6 +252,22 @@
3. homework/grades controller 权限装饰器覆盖核对L104
ai08 在 P3 实施前需 coord 确认这些项是否作为 P3 验收硬性标准。
- **建议方案**
coord 确认上述 3 项是否纳入 P3 验收标准若纳入ai08 在 P3 实施时补齐。
- **状态**待 coord 仲裁
- **建议方案**coord 确认上述 3 项是否纳入 P3 验收标准若纳入ai08 在 P3 实施时补齐。
- **状态**已裁决(见 [coord.md §4 ARB-004](../coord.md#4-arb-004core-edu-模块-7-项-issue-仲裁)
---
## §3 仲裁结论2026-07-10 coord
> 详见 [coord.md §4 ARB-004](../coord.md#4-arb-004core-edu-模块-7-项-issue-仲裁)
| ISSUE | 仲裁结论 | 执行方 |
| ----- | ---------------------------------------------------------------------------------------------------- | ------------ |
| 001 | ✅ coord 批次 0 补全 core_edu.proto 至 5 Service 27 RPCARB-007 | coord |
| 002 | ✅ coord 批次 0 补全 events.protoAttendanceEvent + schema_version + edu.teaching.* 注释ARB-006 | coord |
| 003 | ✅ 采用方案 A统一 `graded`(去掉 SCOREDsubmissions 统一 `not_submitted/submitted/graded` | ai08 + coord |
| 004 | ✅ 统一为 `edu.teaching.class.transferred` | coord + ai08 |
| 005 | ✅ 统一为 P3 全量 27 RPC | coord + ai08 |
| 006 | ✅ 七项设计决策全部采用 ai08 倾向方案(见 coord.md §4.4 | ai08 |
| 007 | ✅ 3 项Dockerfile/ActionState traceId/权限装饰器)纳入 P3 验收硬性标准 | ai08 |

View File

@@ -13,7 +13,7 @@
### 0.1 coord.md 仲裁核查
| 编号 | 主题 | 涉及 data-ana | 核查结论 |
| ------- | ---------------------------- | ------------- | ------------------------------ |
| ------- | -------------------------- | ------------- | ------------------- |
| ARB-001 | teacher-bff GraphQL schema | ❌ 否 | 不涉及,无需 action |
| ARB-002 | MF Shell 暴露清单 | ❌ 否 | 不涉及,无需 action |
@@ -22,7 +22,7 @@
### 0.2 coord-cross-review.md 仲裁核查8 项涉及 data-ana
| # | 审查章节 | 裁决内容 | 责任方 | 核查结论 |
| -- | ---------------- | ------------------------------------------------------------------ | ------ | ---------------------------------------------------------------------------------------------------- |
| --- | --------------- | ------------------------------------------------------------------------ | ------ | ---------------------------------------------------------------------------------------------------------- |
| 1 | §2.2 #3 | iam 新增 `GetEffectiveDataScope` RPCP4 补全data-ana gRPC 调用 | iam | ⚠️ **未落实**iam.proto 当前仅 4 RPCRegister/Login/RefreshToken/GetUserInfo无 GetEffectiveDataScope |
| 2 | §2.3 P4 行 | content + data-ana P4 启用 gRPC server | ai11 | ⏳ 未到 P4 阶段,待执行 |
| 3 | §3.2 | 补登 `edu.insight.ai.usage` topic + events.proto 补 AIUsageEvent | coord | ⚠️ **未落实**events.proto 当前仅 4 messageClass/Exam/Homework/GradeEvent缺 AIUsageEvent |
@@ -37,7 +37,7 @@
coord-cross-review.md §8.2 声称批次 0 已完成 proto 补全ai11 逐文件核查实际状态:
| 声明产出项 | 声明状态 | 实际文件状态ai11 核查) | 核查结论 |
| -------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------- | ------------ |
| -------------------- | --------------------------- | -------------------------------------------------------------------- | ----------- |
| iam.proto 12 RPC | ✅ 12 RPC | **4 RPC**Register/Login/RefreshToken/GetUserInfo | ⚠️ 严重不符 |
| analytics.proto 扩展 | ✅ 12 RPC含 Stream | **3 RPC**GetClassPerformance/GetStudentWeakness/GetLearningTrend | ⚠️ 严重不符 |
| events.proto 补全 | ✅ 9 message+AuditEvent | **4 message**ClassEvent/ExamEvent/HomeworkEvent/GradeEvent | ⚠️ 严重不符 |
@@ -95,6 +95,7 @@ coord-cross-review.md §8.2 声称批次 0 已完成 proto 补全ai11 逐文
- #10004 §12.2 补充派生数据事件 Outbox 豁免条款 → 004 §12.2 未补充
这导致 01-understanding.md 和 02-architecture-design.md 中引用 004 §4.2/§11.4/§11.5/§15.3 等章节均断裂004 正文仅到 §14§15 在 004-p6-addendum.md 但内容不同。ai11 已在 v2.1 修订中临时改为引用 coord-cross-review.md 对应裁决章节,但这是过渡方案。
- **建议方案**coord 按整改清单 #7/#8/#9/#10 补全 004 对应章节,使 004 成为可信的架构设计意图唯一源。各 AI 文档随后将引用从 coord-cross-review.md 回切到 004 对应章节。
- **状态**:待 coord 仲裁
@@ -108,12 +109,13 @@ coord-cross-review.md §8.2 声称批次 0 已完成 proto 补全ai11 逐文
- **描述**data-ana 发布的掌握度/预警事件 topic 命名在三个文档中不一致:
| 文档 | topic 命名 |
| -------------------------------------- | ------------------------------------- |
| ----------------------------------------------- | --------------------------------------------------------------- |
| 01-understanding.md / 02-architecture-design.md | `edu.insight.mastery.updated` + `edu.insight.warning.triggered` |
| matrix.md §4 | `edu.analytics.mastery` |
| contracts/data-ana_contract.md修正前 | `edu.data_ana.mastery.events` |
按 004 §7.2 命名规范 `edu.<domain>.<aggregate>.<action>`data-ana 属于 D6 智能洞察领域domain=insight`edu.insight.mastery.updated` 符合规范。matrix.md 的 `edu.analytics.mastery` 不符合命名规范(缺 action 层级,且 domain 用了服务名而非领域名)。
- **建议方案**coord 裁决统一为 `edu.insight.mastery.updated` + `edu.insight.warning.triggered`coord 修正 matrix.md §4。ai11 已在 contract.md 中采用此命名。
- **状态**:待 coord 仲裁
@@ -126,4 +128,19 @@ coord-cross-review.md §8.2 声称批次 0 已完成 proto 补全ai11 逐文
- **类型**:其他(声明与实际不符)
- **描述**coord-cross-review.md §8.2 声称批次 0 已完成 iam.proto12 RPC/ analytics.proto12 RPC/ events.proto9 message补全但 ai11 逐文件核查发现实际均未补全(详见 §0.3 核查表)。这影响所有依赖这些 proto 的下游 AI 的排期评估——若 AI 信任 §8.2 声明,会在排期中忽略 proto 补全的等待时间,导致排期失真。
- **建议方案**coord 核实 §8.2 声明真实性。若实际已补全但未合并到各 worktree 分支,请协调合并;若实际未补全,请更新 §8.2 状态为"计划中"或"待执行",并明确补全时间点,以便下游 AI 据此排期。
- **状态**待 coord 仲裁
- **状态**已裁决(见 [coord.md §11 ARB-009](../coord.md#11-arb-009data-ana-模块-6-项-issue-仲裁)
---
## §2 仲裁结论2026-07-10 coord
> 详见 [coord.md §11 ARB-009](../coord.md#11-arb-009data-ana-模块-6-项-issue-仲裁)
| ISSUE | 仲裁结论 | 执行方 |
| ----- | ---------------------------------------------------------------------------------- | ------ |
| 001 | ✅ coord 批次 0 补全 iam.proto 12 RPCARB-007含 GetEffectiveDataScope | coord |
| 002 | ✅ coord 补全 events.proto AIUsageEventARB-011 | coord |
| 003 | ✅ coord 批次 0 补全 analytics.proto 至 12 RPCARB-012 | coord |
| 004 | ✅ coord 补全 004 §7.2/§1.2/§4.1/§12.2 对应章节 | coord |
| 005 | ✅ 统一 `edu.insight.mastery.updated` + `edu.insight.warning.triggered`ARB-013 | coord |
| 006 | ✅ coord 更正 coord-cross-review.md §8.2 状态为"待执行" | coord |

View File

@@ -13,7 +13,7 @@
### 1.1 coord-final-decisions I1-I8iam 专项)核查
| 裁决 | 内容摘要 | 核查结论 | 证据 |
| ---- | -------- | -------- | ---- |
| ---- | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| I1 | P2 即启用 gRPC server 50052REST + gRPC 并存 | ⚠️ **02 文档未回写**[02-architecture-design.md](../../../services/iam/docs/02-architecture-design.md) §1/§7.1/§8.1 决策点 5 仍写"P2 仅 RESTP3 随 core-edu 引入 gRPC"iam.proto 仅 4 RPC 未补全 | [iam.proto](../../../packages/shared-proto/proto/iam.proto) 仅 4 RPC[02 文档 §8.1](../../../services/iam/docs/02-architecture-design.md) 决策点 5 |
| I2 | 直接建 shared-ts Outbox 工具包iam 首次实现即用 | ✅ **工具包已建立**`packages/shared-ts/src/outbox/` 存在 outbox.service.ts + outbox.module.ts 02 文档 §8.1 决策点 4 仍写"iam 自建轻量 Outbox",未回写 | [shared-ts/outbox](../../../packages/shared-ts/src/outbox/) |
| I3 | 首次实现即 DB 驱动 + Redis 缓存,废弃本地 map | ❌ **源码未改造**[permission.guard.ts](../../../services/iam/src/middleware/permission.guard.ts) 第 30-39 行仍用硬编码 `ROLE_PERMISSIONS` mapadmin/teacher02 文档 §8.1 决策点 9 描述为"待改造" | [permission.guard.ts](../../../services/iam/src/middleware/permission.guard.ts) |
@@ -26,7 +26,7 @@
### 1.2 president-final-rulings 相关条款核查
| 条款 | 内容摘要 | 核查结论 |
| ----- | -------- | -------- |
| ----- | ------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| §2.15 | /iam/v1/* 版本化规则Controller 加 v1 前缀) | ❌ 同 I7未落地 |
| §2.16 | gRPC 与 REST 双入口策略gateway HTTP 透传 + BFF gRPC 调用) | ⚠️ 02 文档未体现双入口设计,仅描述 REST 单入口contract.md §1.2 写"无对外 HTTP 端点,仅 gRPC"与此冲突 |
| §3.2 | iam P2 拆分 P2.18 RPC 核心)+ P2.2(扩展) | ⚠️ workline.md 仅粗略列出 P2.1P2.2-P6 未细化(见 worklines/iam_workline.md |
@@ -36,7 +36,7 @@
### 1.3 coord.md ARB-001 / ARB-002 核查
| 仲裁 | 内容摘要 | 核查结论 |
| ------ | -------- | -------- |
| ------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| ARB-001 | teacher-bff GraphQL schema 第一版5 Query | ✅ schema 中 `me: User!``viewports` 依赖 iam与 iam GetUserInfo/GetViewports RPC 对齐,无冲突 |
| ARB-002 | MF Shell 暴露清单 | ✅ 不涉及 iam 直接交付物,无冲突 |
@@ -140,3 +140,19 @@
-->
见上方 §2 新提请异议ISSUE-001 ~ ISSUE-007
---
## §3 仲裁结论2026-07-10 coord
> 详见 [coord.md §3 ARB-003](../coord.md#3-arb-003iam-模块-7-项-issue-仲裁)
| ISSUE | 仲裁结论 | 执行方 |
| ----- | ------------------------------------------------------------------------------ | ------------ |
| 001 | ✅ 支持 ai063 工作日内回写 01/02删除全部过渡方案对齐 contract.md v1.0 | ai06 |
| 002 | ✅ coord 批次 0 补全 events.protoARB-006 | coord |
| 003 | ✅ 统一 `edu.iam.*` 域名 + 聚合 topic 风格 | coord |
| 004 | ✅ DataScope 采用 ALL/SCHOOL/GRADE/CLASS/SUBJECT/SELFSUBJECT 替代 DISTRICT | coord + ai06 |
| 005 | ✅ coord 批次 0 补全 iam.proto 至 12 RPCARB-007 | coord |
| 006 | ✅ 与 ISSUE-001 一并回写,署名改 ai06 | ai06 |
| 007 | ✅ contract.md 已修正双入口ai06 回写 02 文档对齐 | ai06 |

View File

@@ -192,3 +192,23 @@
- matrix.md §4 L118`edu.notification.requested`(第三种命名)
- **建议方案**:待 ISSUE-008 仲裁 topic 命名约定后统一
- **状态**:待 coord 仲裁(依赖 ISSUE-008
---
## §2 仲裁结论2026-07-10 coord
> 详见 [coord.md §10 ARB-008](../coord.md#10-arb-008msg-模块-15-项-issue-仲裁)
| ISSUE | 仲裁结论 | 执行方 |
| ------- | ------------------------------------------------------------------------------------------------------------- | ------------ |
| 001~005 | ✅ 核查通过001/002/003004 待 coord 同步 events.protoARB-006005 待 coord 修正 004 §4.1 PushGW 方向 | coord |
| 006 | ✅ coord 补全 GradeEvent class_id + 全部事件 student_ids[]ARB-011 | coord |
| 007 | ✅ 统一 `next_edu_cloud.<domain>.v1`ARB-011 | coord |
| 008 | ✅ msg 采用具体动作 topicARB-013 | coord |
| 009 | ✅ 维持 13 RPC裁剪 4 RPC 降级 REST | ai10 |
| 010 | ✅ markAsRead 权限改为 `MSG_NOTIFICATION_READ` | ai10 |
| 011 | ✅ 双向降级ES 故障→DB LIKEDB 故障→ES 只读) | ai10 |
| 012 | ✅ 非阻塞ai10 补 DLQ + 三层幂等设计文档 | ai10 |
| 013 | ✅ coord 补全 events.protoARB-011NotificationEvent + MasteryEvent | coord |
| 014 | ✅ 统一 13 RPC两文档对齐 | ai10 |
| 015 | ✅ 统一 topic 命名ARB-013 | ai10 + coord |

View File

@@ -13,7 +13,7 @@
### 0.1 核查通过项(已正确执行)
| 仲裁 | 主题 | 核查结论 |
| --- | --- | --- |
| ---- | ------------------------------------------------------ | --------------------------------------------------------------------- |
| U2 | push-gateway 豁免 gRPCHTTP /internal/push | ✅ 02 §5.3/§7.1 已执行 HTTP 调用 push-gateway |
| C2 | 端口 3010不暴露 gRPC | ✅ 02 §7.2 + matrix.md §3 已执行 |
| C3 | core-edu 错误码 CORE_EDU_* | ✅ 02 §6.2 已执行 |
@@ -165,6 +165,25 @@
---
## §3 仲裁结论coord2026-07-10
> 详见 [coord.md](../coord.md) §20 ARB-018
| ISSUE | 仲裁结论 | 状态 |
| ------------------------------------ | -------------------------------------------------------------------------------------------------- | --------------------- |
| 00101 文档未同步) | ✅ 01 作为阶段 1 历史快照保留原样,以 02 为准02 已执行 U3/U4/C1 | 已裁决§20 ARB-018 |
| 002ChildGuard TTL 不一致) | ✅ 统一为 30s§3.1.1 表格改为 30s对齐 §9 #2 + §13 #7 | 已裁决§20 ARB-018 |
| 003引用 I3 → I6 错误) | ✅ 修正为 I6 裁决coord-final-decisions §1 I6家长-学生关联) | 已裁决§20 ARB-018 |
| 004004 §4 依赖图未同步 C6 | ✅ coord 补全 004 §4 服务依赖图 + matrix.md §1 依赖矩阵(加 PBFF → DataAna + PBFF → Msg | 已裁决§20 ARB-018 |
| 005parent-portal REST vs GraphQL | ✅ coord 协调 ai15 将 parent-portal 01/02 改为 GraphQL 消费POST /api/v1/parent/v1/graphql | 已裁决§20 ARB-018 |
| 006proto 包名缺前缀) | ✅ 统一补 next_edu_cloud. 前缀ARB-011 已裁决) | 已裁决§20 ARB-018 |
| 007Notification.childId 缺失) | ✅ coord 协调 ai10 在 msg.proto Notification 补 child_id = 9 字段(可选) | 已裁决§20 ARB-018 |
| 008ClassService 缺失) | ✅ coord 已在 ARB-007 补全 ClassService 4 RPC02 §7.1 状态改 ✅ 已有Grade.score 转换规则补 §3.3 | 已裁决§20 ARB-018 |
| 009ai02→ai06 责任方过时) | ✅ 修正为 ai06iam 现归属 ai06ai-allocation §3.2 确认) | 已裁决§20 ARB-018 |
| 01002 缺 ADR/NFR | ✅ P6 硬化阶段补全(当前不阻塞 P4 实施) | 已裁决§20 ARB-018 |
---
<!--
追加条目格式:

View File

@@ -13,7 +13,7 @@
### 0.1 ARB-001teacher-bff GraphQL schema 第一版)核查
| 核查项 | ARB-001 结论 | parent-portal 落地情况 | 状态 |
| ------ | ------------ | ---------------------- | ---- |
| ------------------------- | ----------------- | ------------------------------------------------------------------------ | --------- |
| BFF 用 GraphQL非 REST | ✅ 已裁决 GraphQL | 01-understanding §3.1 + 02-architecture-design §4.1 全部描述为 REST 消费 | ❌ 未落地 |
| ActionState 信封 | ✅ 已裁决 | 01 §3.2 已对齐 | ✅ |
| 错误码前缀路由 | ✅ 已裁决 | 01 §3.2 + 02 §6.2 已对齐 | ✅ |
@@ -23,7 +23,7 @@
### 0.2 ARB-002MF Shell 暴露清单)核查
| 核查项 | ARB-002 结论 | parent-portal 落地情况 | 状态 |
| ------ | ------------ | ---------------------- | ---- |
| ----------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------- | --------- |
| Shell 暴露 GraphQLProvider | ✅ 已裁决 | 01 §4 技术栈未列 urql/GraphQL client02 §4.1 用 `useApi()`REST ApiClient而非 `useGraphQLClient()` | ❌ 未落地 |
| MF shared 含 urql/graphql/@edu/* | ✅ 已裁决 | 02 §1.2 `shared` 仅列 react/react-dom/@tanstack/react-query/zustand/nuqs缺 urql/graphql/@edu/ui-tokens/@edu/ui-components/@edu/hooks | ❌ 未落地 |
| Shell 暴露 AppShell | ✅ 已裁决 | 01 §9.1 + 02 §7.1 已对齐 | ✅ |
@@ -208,4 +208,19 @@
## §1 已裁决问题
(暂无已裁决问题)
> 详见 [coord.md §22 ARB-020](../coord.md) 完整仲裁章节
### 1.1 仲裁结论汇总coord 2026-07-10
| ISSUE | 标题 | 仲裁结论摘要 | 执行方 |
| ----- | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------------ |
| 001 | 01/02 文档 REST 消费 parent-bff 与 ARB-001 冲突 | ✅ 统一 GraphQL 消费(对齐 ARB-018 ISSUE-005 跨模块裁决) | ai15 修 01/02 |
| 002 | MF shared 配置缺 urql/graphql/@edu/* | ✅ 补全 7 项 singletonreact/react-dom/urql/graphql/@edu/ui-tokens/@edu/ui-components/@edu/hooks | ai15 修 02 §1.2 |
| 003 | switch-child 端点在 01/02 不一致 | ✅ GraphQL Mutation `switchChild(childId: ID!): SwitchChildPayload!`(走 GraphQL对齐 ISSUE-001 | ai15 修 01/02 + ai05 补 schema |
| 004 | 登录端点三方不一致 | ✅ 统一为 `POST /api/v1/iam/login`(对齐 matrix.md §5登录走 REST其余走 GraphQL | ai15 修 contract §2.3 |
| 005 | 02 §11.3 未决决策 #2 已由 ARB-001 裁决 | ✅ 移除未决项,改为"已裁决:见 ARB-001" | ai15 修 02 §11.3 |
| 006 | contract §1.2 误标前端路由为 HTTP 端点 | ✅ §1.2 改为"无parent-portal 是前端 Remote不对外提供 HTTP API" | ai15 修 contract §1.2 |
| 007 | contract §1.6 MF 配置文件位置不一致 | ✅ 统一为 `apps/parent-portal/next.config.js`(对齐 02 + teacher-portal Shell | ai15 修 contract §1.6 |
| 008 | contract §2.3 GraphQL 路径缺 v1 | ✅ 统一为 `POST /api/v1/parent/graphql`(对齐 matrix.md §5 | ai15 修 contract §2.3 + §2.4 |
| 009 | parent-bff GraphQL schema 是否含 switchChild | ✅ parent-bff 提供 `switchChild` Mutation后端记录选中子女用于审计同时前端 Zustand + localStorage 缓存 | ai05 补 schema + ai15 前端实现 |
| 010 | iam GetChildrenByParent 缺失P0 阻塞) | ✅ ai06 P3 收尾前补全I6 裁决);补全前用 mock固定 2 个孩子 student-001 + student-002 | ai06 补全 + ai15 mock |

View File

@@ -16,7 +16,7 @@
### 核查矩阵
| 裁决编号 | 主题 | 裁决要求(摘要) | 02 文档现状 | 核查结论 | 状态 |
| -------- | ---- | ---------------- | ----------- | -------- | ---- |
| ------------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------- | --------- | ------------ |
| ISSUE-053 | Kafka topic 命名 | 02 §5.1 topic 改为 `edu.notification.requested`,禁止抽象名 `edu.*.events` | §5.1 仍写 `edu.notification.events` / `NotificationRequested` | ❌ 未回写 | 待 ai02 修复 |
| ISSUE-055 | /readyz 软失败 | push-gateway /readyz 对 Kafka 软失败(失败仅告警 + `degraded: true` + 返 200不返 503 | §6.7 仅 Redis PING 硬失败返 503无 Kafka 软失败逻辑 | ❌ 未回写 | 待 ai02 修复 |
| ISSUE-056 | 设计决策记录章节 | 02 §5.4 改名为"设计决策记录gRPC vs HTTP 协议选型coord 已采纳 P1",正文标注"coord 已采纳" | 02 无"设计决策记录"章节 | ❌ 未回写 | 待 ai02 修复 |
@@ -151,7 +151,7 @@
> 以下为 01-understanding.md 与现码不符的偏差ai02 在批次 0 自主修复
| # | 位置 | 偏差 | 修复方向 |
| - | ---- | ---- | -------- |
| --- | ---------- | ------------------------------------------------------------------------------ | -------------------------------------------------- |
| 1 | 01 §3.2 | `/readyz` 标"无(待实现)",实际已实现(仅未检查 Redis | 改为"已实现,仅返连接数,待补 Redis PING" |
| 2 | 01 §3.2 | `/metrics` 标"无(待实现)",实际已挂载 promhttp | 改为"已实现,待补自定义指标" |
| 3 | 01 §3.2 | `/internal/push` `/internal/broadcast` 标"待补鉴权",实际已实现 X-Internal-Key | 改为"已实现 X-Internal-Key 校验DevMode 跳过)" |
@@ -165,3 +165,19 @@
## §3 历史问题
(暂无)
---
## §4 仲裁结论coord2026-07-10
> 详见 [coord.md](../coord.md) §17 ARB-015
| ISSUE | 仲裁结论 | 状态 |
| -------------------- | --------------------------------------------------------------- | --------------------- |
| 001SSE 端点) | ✅ 不支持 SSE仅 WebSocketcoord 移除 contract/matrix 的 /sse | 已裁决§17 ARB-015 |
| 002鉴权命名 | ✅ 统一 `X-Internal-Token` + `INTERNAL_API_TOKEN`(总裁 §7.2 | 已裁决§17 ARB-015 |
| 003容量目标 | ✅ 统一 10w+(对齐 02 文档 + pending-features | 已裁决§17 ARB-015 |
| 004端点路径 | ✅ 统一 /internal/pushai02 已自行修复) | 已裁决§17 ARB-015 |
| 005审计表 | ✅ 方案 2审计由 msg 维护push-gateway 无 DB | 已裁决§17 ARB-015 |
| 006Redis /readyz | ✅ Redis 软失败仅告警不阻塞ISSUE-058 覆盖 ISSUE-055 | 已裁决§17 ARB-015 |
| 00702 缺 ADR/NFR | ✅ P5 批次 4 补全 02 §14-§17 四章节 | 已裁决§17 ARB-015 |

View File

@@ -12,7 +12,7 @@
> 本次审查对历史 issues.md 中 ai04 提请的 4 项问题ISSUE-028/029/030/031-ai04逐一核查总裁裁决落地情况。
| 编号 | 主题 | 总裁裁决章节 | 裁决要点 | 核查结果 |
| ---- | ---- | ------------ | -------- | -------- |
| -------------- | ----------------------------------------- | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------- |
| ISSUE-028-ai04 | 02 文档与 B1+B2 裁决冲突需回写 | president §3.4 | ai04 须在批次 2 启动前回写 student-bff 02B1 GraphQL + B2 gRPC + B8 DownstreamClient | ⚠️ **未执行**02-architecture-design.md 仍为 REST 设计§4 21 个 REST 端点 / §9.2 REST→GraphQL 演进 / §9.3 HTTP→gRPC 演进),违反 B1、B2 |
| ISSUE-029-ai04 | P3 启动前置依赖确认4 项强阻塞) | president §4.1 / §6.1 | 批次 0 完成信号机制 + 批次 2 启动条件:批次 1 P2.1 完成 + ai03 DownstreamClient 抽象就绪 | ✅ **已裁决**:批次时间线 §6.1 明确批次 2 启动条件;前置依赖检查清单机制已建立 |
| ISSUE-030-ai04 | student-bff GraphQL schema 第一版仲裁时机 | president §2.2 | ai04 起草 schema批次 1 等待期coord 在批次 2 启动前仲裁第一版;存放 `packages/shared-ts/contracts/graphql/student-bff.schema.graphql` | ✅ **已裁决**schema 仲裁机制已建立§2.2);但 schema 第一版尚未起草,需 ai04 在批次 1 等待期产出 |
@@ -66,7 +66,7 @@
- **描述**02-architecture-design.md §8.3"未决设计决策(待 coord 仲裁)"列出 12 项,但其中 8 项已被 coord-final-decisions §2 裁决:
| # | 决策点 | 02 文档建议 | 已裁决结论 | 裁决章节 |
| --- | ------ | ----------- | ---------- | -------- |
| --- | --------------------- | ---------------- | --------------------------------------------------------------- | --------------------------- |
| 1 | BFF API 风格 | AP3 REST | **B1P2 起直接 GraphQL** | coord-final-decisions §2 B1 |
| 2 | BFF 是否做权限校验 | A不校验 | **B3BFF 豁免 @RequirePermission** | coord-final-decisions §2 B3 |
| 3 | 自我越权防御 | B | **B4全部 BFF 强制自我越权防御** | coord-final-decisions §2 B4 |
@@ -77,6 +77,7 @@
| 9 | DownstreamClient 回写 | B回写 | **B8回写 teacher-bff3 个 BFF 统一** | coord-final-decisions §2 B8 |
仅剩 #7(端口 3009#10CQRS 不引入)、#11SSE 实现)、#12(熔断器引入)属合理的设计决策,但 #12 熔断器 president §2.4 已暗示按阶段评估。
- **建议方案**02 文档回写时删除已裁决项的"待仲裁"标注,改为"已裁决(见 coord-final-decisions §2 BX"
- **状态**:待 coord 确认(与 ISSUE-028-ai04 合并处理)
@@ -97,7 +98,7 @@
### 2.1 准确性问题
| 位置 | 问题 | 严重度 |
| ---- | ---- | ------ |
| -------------------- | ------------------------------------------------------------------------------------- | ------ |
| §1 通信方式(入/出) | 表述"HTTP REST当前阶段/ HTTP fetch当前阶段",实际 B1/B2 裁决为 GraphQL + gRPC | 高 |
| §3.1 表格 | 列"当前 REST 端点(实际可用)"列,暗示走 REST但 BFF 是新服务不存在"当前 REST 现状" | 高 |
| §3.2 端点表 | 14 个 REST 端点,违反 B1 GraphQL | 高 |
@@ -109,7 +110,7 @@
### 2.2 遗漏项
| 遗漏内容 | 应补充位置 | 依据 |
| -------- | ---------- | ---- |
| ----------------------------------------------------------------------------------------- | ---------- | ------------------- |
| GraphQL schema 设计意图Query/Mutation/Type | §3.2 | B1 + president §2.2 |
| gRPC 下游调用设计(@grpc/grpc-js + @bufbuild/protobuf | §3.1 / §4 | B2 |
| DataLoader 防 N+1 策略 | §4 | 004 §11.3 + B1 |
@@ -126,7 +127,7 @@
### 3.1 架构合理性评估
| 维度 | 评估 | 说明 |
| ---- | ---- | ---- |
| ---------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| 分层设计§1 | ✅ 合理 | Controller → Service → Aggregator → Cache → DownstreamClient 五层清晰DownstreamClient/Aggregator/Transformer 抽象优于 teacher-bff 现状,符合 B8 |
| 领域模型§2 | ✅ 合理 | "场景聚合视图"概念恰当BFF 无领域模型DataScope=SELF 强制实现§2.3)符合 B4 |
| 缓存设计§3 | ✅ 合理 | Redis Key 规范、TTL 分档、失效策略完整,符合 B6 |
@@ -144,7 +145,7 @@
### 3.2 长远性评估
| 长远性维度 | 评估 | 说明 |
| ---------- | ---- | ---- |
| -------------------- | ---- | ------------------------------------------------------------------------ |
| 多角色复用§9.5 | ✅ | 学习委员/课代表/走读生差异化通过视口扩展,无需改代码 |
| 多端适配§10.1 | ✅ | Transformer 层按 x-client-type 裁剪H5/小程序可扩展 |
| GraphQL 演进§9.2 | ❌ | 规划为"P6+ 可选",但 B1 已裁决 GraphQL 是起点非终点,须移除"可选" |
@@ -156,7 +157,7 @@
### 3.3 业界架构文档规范符合度
| 规范项 | 符合度 | 说明 |
| ------ | ------ | ---- |
| ----------------- | ------ | ----------------------------------------------- |
| 文档导航/导读 | ✅ | §0.3 文档结构清晰16 章覆盖完整 |
| 设计原则 | ✅ | §0.1 列 P1-P9 九项原则 |
| 架构图C4 模型) | ✅ | §1 物理分层图 + 调用链时序图,符合 C4 Level 2/3 |
@@ -169,7 +170,7 @@
### 3.4 关键遗漏
| 遗漏内容 | 应补充位置 | 依据 |
| -------- | ---------- | ---- |
| ------------------------------------------------------------ | ------------------- | ------------------------------------------------- |
| GraphQL Schema 完整定义Query/Mutation/Type/Enum | 新增 §4.2 或独立 §5 | B1 + president §2.2 |
| DataLoader 批量策略(哪些 Query 需要 DataLoader | §1.2 或 §6 | 004 §11.3 + B1 |
| gRPC client 设计channel 复用、interceptor、metadata 透传) | §1.2 或 §7 | B2 |
@@ -219,3 +220,17 @@
- **描述**issues.md ISSUE-024/025 编号冲突ai11 与 ai09 重复)
- **裁决**president §0.4 — 保留原始内容,用 `ISSUE-XXX-<提请AI>` 格式定位,不重新编号
- **状态**:✅ 已裁决
---
## §5 仲裁结论coord2026-07-10
> 详见 [coord.md](../coord.md) §19 ARB-017
| ISSUE | 仲裁结论 | 状态 |
| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| STU-00101 文档与 B1/B2/B5 冲突) | ✅ 与 ISSUE-028 合并处理01 文档随 02 文档一并回写(删除 REST 端点清单、改 GraphQL、错误码改 BFF_STUDENT_ | 已裁决§19 ARB-017 |
| STU-00202 引用不存在的 004 §11.4/§11.5 | ✅ coord 补全 004 §11.4(错误码前缀矩阵)+ §11.5ActionState 信封规范)章节 | 已裁决§19 ARB-017 |
| STU-00302 §8.3 八项已裁决决策) | ✅ 02 文档回写时删除已裁决项"待仲裁"标注,改为"已裁决(见 coord-final-decisions §2 BX" | 已裁决§19 ARB-017 |
| STU-004GraphQL schema 第一版未起草) | ✅ ai04 在批次 1 等待期产出 schema 草案,存放 `packages/shared-ts/contracts/graphql/student-bff.schema.graphql` | 已裁决§19 ARB-017 |
| ISSUE-02802 文档回写) | ✅ 回写范围确认(见 coord.md §19.4§4 REST→GraphQL、§9.2/9.3 删演进、§3.1 改 gRPC、§3.3 错误码改 BFF_STUDENT_、§8.3 标已裁决、01 同步回写 | 已裁决§19 ARB-017 |

View File

@@ -11,7 +11,7 @@
### 1.1 ARB-001teacher-bff GraphQL schema 第一版)对 student-portal 的影响核查
| 裁决点 | 对 student-portal 的适用性 | ai14 落实方案 | 状态 |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- | ------------ |
| ----------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- | ---------- |
| Schema 存放位置 | ✅ 适用原则一致。student-bff GraphQL schema 应存放于 `packages/shared-ts/contracts/graphql/student-bff.graphql`(集中管理,与 teacher-bff 同源) | ai14 在 contract.md §1.3 已标注预期路径;实际由 ai04 创建ai14 仅消费 | ⏳ 待 ai04 |
| P2 Query 范围 | ⚠️ 部分参考。ARB-001 是 teacher-bff 的 P2 范围student-portal 起步于 P3不在 P2因此 student-bff 直接以 P3 全量 Query 起步 | ai14 在 P3 直接消费 student-bff 全量 QuerycurrentUser/myClasses/myExams/myHomework/myGrades/myAttendance/studentDashboard | ✅ 已落实 |
| P2 Mutation 范围 | ⚠️ 部分参考。student-portal P3 起步即需要 submitHomework mutation作业提交是 P3 核心场景) | ai14 P3 即消费 submitHomework mutationai04 P3 必须提供 | ⏳ 待 ai04 |
@@ -28,7 +28,7 @@
### 1.2 ARB-002MF Shell 暴露清单)对 student-portal 的影响核查
| 裁决点 | 对 student-portal 的适用性 | ai14 落实方案 | 状态 |
| ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
| ------------------------------------ | --------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------- |
| Shell 身份 | ✅ 适用。teacher-portal 是 MF Shellstudent-portal 是 P3 首个 Remote | ai14 在 [02 §3.2 MF 配置](../../../apps/student-portal/docs/02-architecture-design.md) 已声明 `remotes: { teacher: 'teacher@http://localhost:4000/_next/static/chunks/remoteEntry.js' }` | ✅ 已落实 |
| P3 首个 Remote | ✅ 适用。ARB-002 §2.3 明确 P3 首个 Remote 是 student-portal | ai14 P3 任务启动即接入 MF Remote | ✅ 已落实 |
| GraphQL client 归属 | ✅ 适用。Shell 暴露 GraphQLProviderstudent-portal 复用,**不重复创建 client** | ai14 在 [02 §3.2 GraphQL 请求层](../../../apps/student-portal/docs/02-architecture-design.md) 已使用 `useGraphQLClient()``@edu/hooks` 获取 | ✅ 已落实 |
@@ -46,7 +46,7 @@
### 1.3 ARB-001 / ARB-002 核查总结
| 仲裁 | 对 student-portal 的影响 | ai14 落实情况 | 异议 |
| ------ | ------------------------ | ------------- | ---- |
| ------- | ------------------------------------------------ | ------------- | ---- |
| ARB-001 | 设计原则适用GraphQL + ActionState + 降级模式) | ✅ 已落实 | 无 |
| ARB-002 | 直接适用P3 首个 Remote + Shell 暴露清单) | ✅ 已落实 | 无 |
@@ -193,14 +193,30 @@
## §3 异议状态汇总
| 编号 | 类型 | 标题 | 状态 |
| ------------- | ------------ | -------------------------------------------------------- | ------------ |
| ISSUE-014-01 | 契约不明确 | GraphQL endpoint 路径不一致 | 待 coord 仲裁 |
| ISSUE-014-02 | 契约不明确 | student-bff GraphQL schema 存放位置不一致 | 待 coord 仲裁 |
| ISSUE-014-03 | 契约不明确 | 考试作答页全屏策略与防作弊检测边界 | 待 coord 仲裁 |
| ISSUE-014-04 | 契约不明确 | 主观题粘贴策略(防作弊 vs 学生体验) | 待 coord 仲裁 |
| ISSUE-014-05 | 契约不明确 | 作业附件上传协议GraphQL mutation vs REST multipart | 待 coord 仲裁 |
| ISSUE-014-06 | 契约不明确 | 考试延长/题目重排等实时事件命名未确认 | 待 coord 仲裁 |
| ISSUE-014-07 | 契约不明确 | 学生端 DataScope L0 边界的强制执行层 | 待 coord 仲裁 |
| ------------ | ---------- | ------------------------------------------------------ | ------------------------------------ |
| ISSUE-014-01 | 契约不明确 | GraphQL endpoint 路径不一致 | ✅ 已裁决(见 coord.md §21 ARB-019 |
| ISSUE-014-02 | 契约不明确 | student-bff GraphQL schema 存放位置不一致 | ✅ 已裁决(见 coord.md §21 ARB-019 |
| ISSUE-014-03 | 契约不明确 | 考试作答页全屏策略与防作弊检测边界 | ✅ 已裁决(见 coord.md §21 ARB-019 |
| ISSUE-014-04 | 契约不明确 | 主观题粘贴策略(防作弊 vs 学生体验) | ✅ 已裁决(见 coord.md §21 ARB-019 |
| ISSUE-014-05 | 契约不明确 | 作业附件上传协议GraphQL mutation vs REST multipart | ✅ 已裁决(见 coord.md §21 ARB-019 |
| ISSUE-014-06 | 契约不明确 | 考试延长/题目重排等实时事件命名未确认 | ✅ 已裁决(见 coord.md §21 ARB-019 |
| ISSUE-014-07 | 契约不明确 | 学生端 DataScope L0 边界的强制执行层 | ✅ 已裁决(见 coord.md §21 ARB-019 |
---
## §4 仲裁结论coord 2026-07-10
> 详见 [coord.md §21 ARB-019](../coord.md) 完整仲裁章节
| ISSUE | 仲裁结论摘要 | 执行方 |
| ------ | ---------------------------------------------------------------------------------------------- | -------------------------------- |
| 014-01 | 统一为 `POST /api/v1/student/graphql`(双 /v1 前缀,对齐 ARB-014 方案 A | ai14 修 contract + ai01 确认路由 |
| 014-02 | 统一为 `packages/shared-ts/contracts/graphql/student-bff.schema.graphql` | ai04 创建并维护 |
| 014-03 | P3 不强制全屏 + visibilitychange 仅记录 + 多标签警告不阻止 + recordExamViolation mutation | ai14 + ai04 + ai08 补 RPC |
| 014-04 | 客观题禁止 / 主观题允许记录 / 作文题允许不记录;复用 recordExamViolationtype=PASTE | ai14 + ai04 |
| 014-05 | 方案 Aapi-gateway REST `POST /api/v1/student/upload` → 对象存储 → GraphQL mutation 提交 URL | ai01 路由 + ai04 mutation |
| 014-06 | ExamExtended + ExamForceSubmittedai08 发布到 `edu.exam.events`);题目重排 P3 不实现 P4 评估 | ai08 发布 + ai10 推送 |
| 014-07 | 方案 Astudent-bff Resolver 从 JWT x-user-id 提取 studentId前端 query 不传 studentId | ai14 修 query 设计 + ai04 实现 |
---

View File

@@ -52,7 +52,18 @@
- president-final-rulings.md §2.17 第 1 条:`teacher-bff.schema.graphql`
ai03 创建文件时无法确定用哪个文件名。
- **建议方案**:以 president §2.17 为准(裁决优先级 president > coord统一为 `teacher-bff.schema.graphql`。coord 修正 ARB-001 §1.3/§1.4 文件名。
- **状态** coord 仲裁
- **状态**已裁决(见 coord.md §18 ARB-016
---
## §1 仲裁结论coord2026-07-10
> 详见 [coord.md](../coord.md) §18 ARB-016
| ISSUE | 仲裁结论 | 状态 |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
| 001admin 命名空间 P2 | ✅ 以总裁裁决为准P2 预留 schema 占位admin.* Query/Mutation 骨架Resolver 返 nullP6 实现coord 修正 ARB-001 §1.3 | 已裁决§18 ARB-016 |
| 002dashboard classes 数据来源) | ✅ 采纳 president §3.5P2 classes 数据从 iam gRPC 获取GetViewports/GetEffectiveAccess不调 classes 服务P3+ 切换为 core-edu.ClassService.GetClassesByTeacher | 已裁决§18 ARB-016 |
| 003schema 文件名) | ✅ 以总裁 §2.17 为准,统一 `teacher-bff.schema.graphql`coord 修正 ARB-001 §1.3/§1.4 | 已裁决§18 ARB-016 |

View File

@@ -0,0 +1,15 @@
{
"name": "@edu/contracts",
"version": "0.1.0",
"private": true,
"type": "module",
"main": "./src/index.ts",
"types": "./src/index.ts",
"scripts": {
"lint": "eslint src",
"typecheck": "tsc --noEmit"
},
"devDependencies": {
"typescript": "^5.6.0"
}
}

View File

@@ -0,0 +1 @@
export * from "./permissions.js";

View File

@@ -0,0 +1,108 @@
/**
* 全局权限点常量coord 维护)
*
* 命名规范F7 裁决):<RESOURCE>_<ACTION>[_<SCOPE>]
* - RESOURCE大写资源名USER/ROLE/CLASS/EXAM...
* - ACTION动作CREATE/READ/UPDATE/DELETE/MANAGE...
* - SCOPE可选作用域OWN/CLASS/GRADE/SCHOOL...
*
* 维护方:
* - ADMIN_* → coord 维护(本文件)
* - IAM_* → iam 服务维护
* - ORG_* → iam 服务维护
* - CORE_EDU_* → core-edu 服务维护
* - CONTENT_* → content 服务维护
* - MSG_* → msg 服务维护
*
* 引用:
* - admin-portal_contract.md §1.2admin-portal 路由权限点
* - ARB-021 §23.4admin 命名空间 schema
* - coord-final-decisions F7权限点命名规范
*/
// ============ ADMIN_* 权限点admin-portal 专用) ============
// 来源admin-portal_contract.md §1.2 + ARB-021 §23.4
// 维护方coord
export const ADMIN_PERMISSIONS = {
/** 管理员仪表盘查看 */
ADMIN_DASHBOARD_VIEW: "ADMIN_DASHBOARD_VIEW",
/** 学校设置管理L5 校级) */
ADMIN_SYSTEM_MANAGE: "ADMIN_SYSTEM_MANAGE",
/** 班级管理-全局查看(跨班级) */
ADMIN_CLASS_READ: "ADMIN_CLASS_READ",
/** 班级管理-全局编辑(跨班级) */
ADMIN_CLASS_MANAGE: "ADMIN_CLASS_MANAGE",
/** 教师管理-查看 */
ADMIN_TEACHER_READ: "ADMIN_TEACHER_READ",
/** 教师管理-编辑 */
ADMIN_TEACHER_MANAGE: "ADMIN_TEACHER_MANAGE",
/** 学生管理-查看 */
ADMIN_STUDENT_READ: "ADMIN_STUDENT_READ",
/** 学生管理-编辑 */
ADMIN_STUDENT_MANAGE: "ADMIN_STUDENT_MANAGE",
/** 审计日志查看L5 校级) */
ADMIN_AUDIT_READ: "ADMIN_AUDIT_READ",
/** 审计日志导出 */
ADMIN_AUDIT_EXPORT: "ADMIN_AUDIT_EXPORT",
} as const;
export type AdminPermission = keyof typeof ADMIN_PERMISSIONS;
export const ADMIN_PERMISSION_VALUES: readonly string[] =
Object.values(ADMIN_PERMISSIONS);
/** admin 角色全权限通配符 */
export const ADMIN_WILDCARD = "*";
/** admin-portal 所有路由权限点映射 */
export const ADMIN_ROUTE_PERMISSIONS: Record<string, string> = {
"/admin/dashboard": ADMIN_PERMISSIONS.ADMIN_DASHBOARD_VIEW,
"/admin/users": "IAM_USER_READ", // 复用 iam 权限点
"/admin/roles": "IAM_ROLE_READ", // 复用 iam 权限点
"/admin/permissions": "IAM_PERMISSION_READ", // 复用 iam 权限点
"/admin/viewports": "IAM_VIEWPORT_READ", // 复用 iam 权限点
"/admin/organization": "ORG_MANAGE", // 复用 iam 权限点
"/admin/system": ADMIN_PERMISSIONS.ADMIN_SYSTEM_MANAGE,
"/admin/classes": ADMIN_PERMISSIONS.ADMIN_CLASS_READ,
"/admin/teachers": ADMIN_PERMISSIONS.ADMIN_TEACHER_READ,
"/admin/students": ADMIN_PERMISSIONS.ADMIN_STUDENT_READ,
"/admin/audit-logs": ADMIN_PERMISSIONS.ADMIN_AUDIT_READ,
} as const;
// ============ 权限点分组admin-portal §2.4 GraphQL adminPermissions Query 用) ============
export interface PermissionGroup {
resource: string;
label: string;
permissions: string[];
}
/** 全量权限点分组admin-portal GraphQL adminPermissions Query 返回) */
export const PERMISSION_GROUPS: PermissionGroup[] = [
{
resource: "ADMIN",
label: "管理员",
permissions: [...ADMIN_PERMISSION_VALUES],
},
{
resource: "IAM",
label: "身份与访问",
permissions: [
"IAM_USER_READ",
"IAM_USER_CREATE",
"IAM_USER_UPDATE",
"IAM_USER_DELETE",
"IAM_ROLE_READ",
"IAM_ROLE_MANAGE",
"IAM_PERMISSION_READ",
"IAM_VIEWPORT_READ",
"IAM_VIEWPORT_MANAGE",
],
},
{
resource: "ORG",
label: "组织",
permissions: ["ORG_MANAGE"],
},
];

View File

@@ -0,0 +1,14 @@
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"module": "NodeNext",
"moduleResolution": "NodeNext",
"target": "ES2022",
"outDir": "./dist",
"rootDir": "./src",
"incremental": false,
"types": ["node"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}

99
pnpm-lock.yaml generated
View File

@@ -82,8 +82,94 @@ importers:
specifier: ^5.6.0
version: 5.9.3
packages/contracts:
devDependencies:
typescript:
specifier: ^5.6.0
version: 5.9.3
packages/hooks:
dependencies:
'@edu/ui-components':
specifier: workspace:*
version: link:../ui-components
react:
specifier: ^18.3.0
version: 18.3.1
react-dom:
specifier: ^18.3.0
version: 18.3.1(react@18.3.1)
devDependencies:
'@types/react':
specifier: ^18.3.0
version: 18.3.31
'@types/react-dom':
specifier: ^18.3.0
version: 18.3.7(@types/react@18.3.31)
typescript:
specifier: ^5.6.0
version: 5.9.3
packages/shared-proto: {}
packages/shared-ts:
dependencies:
'@nestjs/common':
specifier: ^10.4.0
version: 10.4.22(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@nestjs/core':
specifier: ^10.4.0
version: 10.4.22(@nestjs/common@10.4.22(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/platform-express@10.4.22)(reflect-metadata@0.2.2)(rxjs@7.8.2)
'@paralleldrive/cuid2':
specifier: ^2.2.2
version: 2.3.1
drizzle-orm:
specifier: ^0.31.0
version: 0.31.4(@opentelemetry/api@1.9.1)(@types/better-sqlite3@7.6.13)(@types/pg@8.6.1)(@types/react@18.3.31)(better-sqlite3@11.10.0)(mysql2@3.22.6(@types/node@22.20.0))(react@18.3.1)
kafkajs:
specifier: ^2.2.0
version: 2.2.4
pino:
specifier: ^9.4.0
version: 9.14.0
reflect-metadata:
specifier: ^0.2.2
version: 0.2.2
rxjs:
specifier: ^7.8.0
version: 7.8.2
devDependencies:
'@types/node':
specifier: ^22.0.0
version: 22.20.0
typescript:
specifier: ^5.6.0
version: 5.9.3
packages/ui-components:
dependencies:
'@edu/ui-tokens':
specifier: workspace:*
version: link:../ui-tokens
react:
specifier: ^18.3.0
version: 18.3.1
react-dom:
specifier: ^18.3.0
version: 18.3.1(react@18.3.1)
devDependencies:
'@types/react':
specifier: ^18.3.0
version: 18.3.31
'@types/react-dom':
specifier: ^18.3.0
version: 18.3.7(@types/react@18.3.31)
typescript:
specifier: ^5.6.0
version: 5.9.3
packages/ui-tokens: {}
scripts/arch-scan:
dependencies:
better-sqlite3:
@@ -1494,6 +1580,10 @@ packages:
cpu: [x64]
os: [win32]
'@noble/hashes@1.8.0':
resolution: {integrity: sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==}
engines: {node: ^14.21.3 || >=16}
'@nodelib/fs.scandir@2.1.5':
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@@ -2503,6 +2593,9 @@ packages:
peerDependencies:
'@opentelemetry/api': ^1.1.0
'@paralleldrive/cuid2@2.3.1':
resolution: {integrity: sha512-XO7cAxhnTZl0Yggq6jOgjiOHhbgcO4NqFqwSmQpjK3b6TEE6Uj/jfSk6wzYyemh3+I0sHirKSetjQwn5cZktFw==}
'@pinojs/redact@0.4.0':
resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==}
@@ -6642,6 +6735,8 @@ snapshots:
'@next/swc-win32-x64-msvc@14.2.33':
optional: true
'@noble/hashes@1.8.0': {}
'@nodelib/fs.scandir@2.1.5':
dependencies:
'@nodelib/fs.stat': 2.0.5
@@ -8135,6 +8230,10 @@ snapshots:
'@opentelemetry/api': 1.9.1
'@opentelemetry/core': 1.30.1(@opentelemetry/api@1.9.1)
'@paralleldrive/cuid2@2.3.1':
dependencies:
'@noble/hashes': 1.8.0
'@pinojs/redact@0.4.0': {}
'@pkgjs/parseargs@0.11.0':