fix: code compliance audit and fix across all services
Some checks failed
CI / quality-ts (push) Failing after 48s
CI / quality-go (push) Failing after 4s
CI / quality-proto (push) Failing after 2s
CI / deploy (push) Has been skipped

NestJS (6 services): implement @RequirePermission decorator with
SetMetadata+Reflector, register APP_GUARD globally, fix as assertions
to type guards, add explicit return types, fix import type for express,
fix /metrics implicit any, replace native Error with ApplicationError,
remove typeorm remnants, register LifecycleService.

teacher-bff: add logger, ApplicationError, GlobalErrorFilter, forward
real userId to downstream, log downstream failures, migrate health
controller to shared/health.

Go (2 services): interface to any, doc comments, CORS dev whitelist,
JWT secret fail-fast, push-gateway internal API auth, metrics and
readyz endpoints, remove dead code.

Python (2 services): lifespan return type, dev_mode to bool, data-ana
APIRouter, ai POST body model, ClickHouse async wrapping.
This commit is contained in:
SpecialX
2026-07-09 17:28:27 +08:00
parent b53a486c6e
commit 0a71b02e04
93 changed files with 5775 additions and 608 deletions

View File

@@ -0,0 +1,346 @@
# 模块理解确认书 — parent-bff
> AI 标识ai04
> 阶段:阶段 1全局理解
> 日期2026-07-09
> 状态:待 coord 审核
> 关联文档:[ai-allocation §6 模板](../../docs/architecture/ai-allocation.md)、[004 架构影响地图](../../docs/architecture/004_architecture_impact_map.md)、[pending-features P4](../../docs/architecture/roadmap/pending-features.md)
---
## 1. 我在架构中的位置
| 维度 | 内容 |
| -------------- | ---------------------------------------------------------------------------- |
| 层级 | **L4 BFF 聚合层**004 §3.1 六层架构) |
| 上游调用方 | api-gatewayGo Gin反向代理 `/api/v1/parent/*` → parent-bff:3010 |
| 下游被调用方 | iam、core-edu按 004 §4 服务依赖图parent-bff 依赖最少) |
| 通信方式(入) | HTTP RESTapi-gateway → parent-bff当前阶段设计意图为 gRPC004 §4.1 |
| 通信方式(出) | HTTP fetch当前阶段对齐 teacher-bff 模式);设计意图为 gRPC004 §4.1 |
| 微前端对接 | parent-portalai07 负责P4 阶段)通过 api-gateway 调用 parent-bff |
| 推送通道 | push-gatewayP5 阶段WebSocket/SSE 推送孩子成绩发布、作业批改等通知) |
**架构定位**004 §1.1a + §5.4
- 按"使用场景域"分 BFFparent-bff 服务于**家长场景域**,复用角色:家长
- 不按角色分 BFF新角色复用现有 BFF 通过视口差异化
- DataScope = **CHILDREN自定义级**家长只能看自己绑定孩子的数据004 §5.3 的 L0 SELF 变体dataScope 枚举值含 `children`,见 004 §5.4 iam 服务职责)
**004 §4 服务依赖图明确**
```
PBFF --> IAM
PBFF --> CoreEdu
```
parent-bff 仅依赖 iam + core-edu**不直接依赖 content / data-ana / msg / ai**。这是设计意图:家长场景的核心是"查看孩子的教学数据",教学数据由 core-edu 提供。但 ai-allocation.md §5 ai04 设计重点提到"家长通知偏好配置",意味着 parent-bff 可能需要调用 msg 服务。**此差异需 coord 仲裁**(见 §7.2)。
---
## 2. 我的限界上下文
### 2.1 我负责什么
parent-bff 是**纯聚合层**,不持有业务状态、不直接访问 DB对齐 teacher-bff 模式)。职责:
1. **多子女账户切换**家长账号可绑定多个孩子parent-bff 维护"当前选中孩子"上下文
2. **聚合**:并行调用 iam查家长信息 + 孩子列表)+ core-edu查孩子的教学数据
3. **裁剪**:将下游返回的领域数据裁剪为家长端所需的最小字段集
4. **协议转换**:对外暴露场景化 HTTP/GraphQL 端点,对内调用下游 REST/gRPC
5. **缓存**:聚合结果 Redis 短缓存 5-30s004 §6.2 BFF 混合读策略)
6. **通知偏好**:家长可配置通知偏好(哪些事件推送、哪些不推送),存于 msg 服务或 iam 服务
### 2.2 我的聚合场景(家长视角)
| 场景 | 聚合的下游服务 | 用途 |
| ------------------ | --------------------------------------------------------------------------------- | ---------------------------------- |
| 家长首页 Dashboard | iam `/iam/me` + iam `/iam/children`(缺失) + core-edu `/grades/student/:childId` | 个人信息 + 孩子列表 + 孩子近期成绩 |
| 切换当前孩子 | iam `/iam/children`(缺失) + core-edu `/homework/class/:classId` | 切换上下文后加载孩子数据 |
| 孩子的考试成绩 | core-edu `/exams/class/:classId` + `/grades/student/:childId` | 孩子所在班级考试 + 孩子成绩 |
| 孩子的作业情况 | core-edu `/homework/class/:classId` | 孩子作业列表 + 提交状态 |
| 孩子的成绩趋势 | data-ana `/analytics/student/:childId/trend`004 未列入依赖,待仲裁) | 历史成绩曲线 |
| 孩子的学情诊断 | data-ana `/analytics/student/:childId/weakness`(待仲裁) | 薄弱知识点 |
| 班级学情对比 | data-ana `/analytics/class/:classId/performance`(待仲裁) | 孩子相对班级的位置 |
| 消息中心 | msg `/notifications`004 未列入依赖,待仲裁) | 家长通知列表 |
| 通知偏好配置 | msg 或 iam缺失 | 配置哪些事件推送 |
| 孩子的出勤 | core-edu `/attendance/student/:childId`(缺失) | 出勤记录 |
### 2.3 我不负责什么(明确边界外)
| 不负责项 | 归属服务 | 说明 |
| ----------------- | -------------------------- | ----------------------------------------------------------------- |
| 业务数据持久化 | core-edu / iam | BFF 不写 DB |
| 权限校验 | 下游业务服务 + iam | BFF 不做权限校验(对齐 teacher-bff透传 `x-user-id` 让下游校验 |
| 用户认证 | iam + api-gateway | JWT 校验在 GatewayBFF 只读 `x-user-id` 头 |
| 学生-家长关系维护 | iam 或 core-edu缺失 | parent-bff 只读取关系,不维护 |
| 领域事件发布 | core-edu | BFF 不发布事件,仅可选订阅事件用于实时推送 |
| 数据范围过滤 | 下游业务服务 Repository 层 | BFF 透传 userId + childId下游按 DataScope=CHILDREN 过滤 |
| 考试批改 | core-edu | 家长不能批改,只能查看孩子成绩 |
| 孩子的作业提交 | core-edu学生端职责 | 家长不能代孩子提交作业 |
---
## 3. 我与外部的契约
### 3.1 我消费的 proto message / 下游接口
> ⚠️ **重要差距**:当前阶段 BFF→Service 走 HTTP fetch对齐 teacher-bff 现状proto 仅作"契约文档"。gRPC 落地需 coord 在 buf.gen.yaml 补 gRPC 插件。
> ⚠️ **核心依赖缺失**iam 没有"家长-学生关联查询"接口parent-bff 无法实现核心场景。
| 下游服务 | proto service设计意图 | 当前 REST 端点(实际可用) | 用途 |
| ------------------- | ---------------------------------------------------------------------------------- | ----------------------------------------------------------- | ---------------------------------- |
| iam | `IamService.GetUserInfo` | `GET /iam/me` | 获取家长个人信息 |
| iam | `IamService.GetViewports`proto 缺失) | `GET /iam/viewports` | 获取家长端导航视口 |
| iam | `IamService.GetEffectivePermissions`proto 缺失) | `GET /iam/permissions/effective` | 获取有效权限列表 |
| iam | **`GetChildrenByParent`proto + REST 双缺失)** | **无** | 查询家长绑定的孩子列表(核心缺失) |
| iam | **`GetParentsByStudent`proto + REST 双缺失)** | **无** | 反向查询(可选) |
| classescore-edu | `ClassService.GetClass` | `GET /classes/:id` | 查孩子所在班级信息 |
| core-edu | `ExamService.GetExam` / `ListExamsByClass` | `GET /exams/class/:classId` | 查孩子班级考试 |
| core-edu | `HomeworkService.ListHomeworkByClass` | `GET /homework/class/:classId` | 查孩子作业 |
| core-edu | `GradeService.GetGrade` / `ListGradesByStudent` / `ListGradesByExam` | `GET /grades/student/:childId` / `GET /grades/exam/:examId` | 查孩子成绩 |
| core-edu | **`AttendanceService`proto + REST 双缺失)** | **无** | 查孩子出勤(全局缺失) |
| data-ana | `AnalyticsService.GetClassPerformance` / `GetStudentWeakness` / `GetLearningTrend` | **REST 未实现** | 学情分析004 未列入依赖,待仲裁) |
| msg | `NotificationService.ListNotifications` / `MarkAsRead` | `GET /notifications`msg 服务 P5 才落地) | 家长通知004 未列入依赖,待仲裁) |
| msg 或 iam | **通知偏好配置proto + REST 双缺失)** | **无** | 配置推送偏好 |
### 3.2 我暴露的 API 端点parent-bff 对外)
> 路由前缀:`/parent`(对齐 teacher-bff 用 `/teacher` 的命名规律)
> 网关路径:`/api/v1/parent/*` → api-gateway 剥离 `/api/v1` 后代理到 parent-bff:3010
| method | path | 聚合下游 | 权限(透传给下游校验) | 说明 |
| ------ | ---------------------------------------------- | ------------------ | ------------------------ | --------------------------------------- |
| GET | `/parent/dashboard` | iam + core-edu | PARENT_DASHBOARD_READ | 家长首页(含孩子列表 + 近期成绩) |
| GET | `/parent/children` | iam | PARENT_CHILDREN_READ | 我的孩子列表 |
| POST | `/parent/children/:childId/select` | BFF 内部状态) | PARENT_CHILDREN_READ | 切换当前选中孩子sessionId 或 cookie |
| GET | `/parent/children/:childId/exams` | core-edu | PARENT_EXAM_READ | 孩子的考试列表 |
| GET | `/parent/children/:childId/homework` | core-edu | PARENT_HOMEWORK_READ | 孩子的作业列表 |
| GET | `/parent/children/:childId/grades` | core-edu | PARENT_GRADE_READ | 孩子的成绩列表 |
| GET | `/parent/children/:childId/analytics/trend` | data-ana待仲裁 | PARENT_ANALYTICS_READ | 孩子成绩趋势 |
| GET | `/parent/children/:childId/analytics/weakness` | data-ana待仲裁 | PARENT_ANALYTICS_READ | 孩子薄弱知识点 |
| GET | `/parent/notifications` | msg待仲裁 | PARENT_NOTIFICATION_READ | 家长通知列表 |
| POST | `/parent/notifications/:id/read` | msg待仲裁 | PARENT_NOTIFICATION_READ | 标记已读 |
| GET | `/parent/notification-preferences` | msg 或 iam缺失 | PARENT_PREFERENCE_READ | 通知偏好配置 |
| PUT | `/parent/notification-preferences` | msg 或 iam缺失 | PARENT_PREFERENCE_UPDATE | 更新通知偏好 |
### 3.3 错误码前缀
| 前缀 | 用途 | 示例 |
| ------------- | ---------------------- | --------------------------------------------------------------------------------- |
| `PARENT_BFF_` | parent-bff 自身错误 | `PARENT_BFF_UNAUTHORIZED``PARENT_BFF_BAD_GATEWAY``PARENT_BFF_CHILD_NOT_BOUND` |
| 下游错误透传 | 下游服务错误码原样返回 | `IAM_USER_NOT_FOUND``CORE_EDU_GRADE_NOT_FOUND` |
错误类清单(对齐 teacher-bff application-error.ts + 新增家长特有错误):
- `UnauthorizedError(401)` — 缺失 `x-user-id`
- `BadGatewayError(502)` — 下游服务返回非 ok 或 fetch rejected
- `ValidationError(400)` — 入参校验失败BFF 层 Zod 校验)
- `BusinessError(422)` — 业务校验失败(如家长查询的 childId 不在自己绑定列表内)
- `NotFoundError(404)` — 资源不存在
- `InternalError(500)` — 未捕获异常
**家长特有错误**
- `PARENT_BFF_CHILD_NOT_BOUND(403)` — 家长查询的 childId 未在自己绑定的孩子列表内DataScope=CHILDREN 越权)
### 3.4 我订阅的 Kafka 事件(可选,用于实时推送)
| Topic | 事件 | 消费动作 |
| --------------------- | ----------------- | ------------------------------ |
| `edu.grade.events` | `grade.recorded` | 推送给家长(孩子成绩发布) |
| `edu.homework.events` | `homework.graded` | 推送给家长(孩子作业批改完成) |
| `edu.exam.events` | `exam.published` | 推送给家长(考试提醒) |
> ⚠️ Kafka 订阅在 P5 阶段 push-gateway 落地后才有意义P4 阶段 parent-bff 可不消费事件,仅做同步聚合。
> ⚠️ 家长通知偏好配置生效后BFF 在订阅事件时应过滤:若家长关闭了"成绩推送"偏好,则不推送该类事件。
---
## 4. 我的技术栈
| 维度 | 选型 | 依据 |
| ------------ | ------------------------------------ | ----------------------------------------------------------------------------- |
| 语言 | TypeScript 5.5+ | 004 §2.1 |
| 框架 | NestJS 10 | 004 §2.1,对齐 teacher-bff 模板 |
| ORM | **无**BFF 不访问 DB | 对齐 teacher-bff无 repository/schema/dto |
| 缓存 | Redis 7短缓存 5-30s | 004 §6.2 BFF 混合读策略 |
| 会话状态 | Redis当前选中孩子 childId | 多子女账户切换,不持久化在 BFF 内存 |
| 可观测性日志 | pino | 对齐 classes/teacher-bff |
| 可观测性指标 | prom-client`/metrics` 端点) | 对齐 teacher-bff main.ts |
| 可观测性链路 | OpenTelemetry SDK + OTLP exporter | 对齐 teacher-bff tracer.ts |
| API 风格 | **HTTP REST**(当前阶段) | 对齐 teacher-bff 现状;与 student-bff 一致,需 coord 仲裁是否统一升级 GraphQL |
| 输入校验 | Zod | 对齐 classes/teacher-bff |
| 错误处理 | GlobalErrorFilter + ApplicationError | 对齐 classes/teacher-bff |
| ESM 模式 | NodeNext + `.js` 后缀 import | 对齐 teacher-bff tsconfig |
| 测试框架 | Jest待定对齐 classes | 黄金模板要求测试覆盖率 ≥ 80% |
### 4.1 关于 GraphQL 的设计决策(待 coord 仲裁)
与 student-bff §4.1 相同的矛盾ai04 建议 P4 阶段 parent-bff **先对齐 teacher-bff 现状REST + fetch + Promise.allSettled**,与 student-bff 保持一致。此决策需 coord 仲裁。
### 4.2 关于多子女账户切换的设计
**问题**:家长账号绑定多个孩子,前端需要知道"当前选中的孩子"。
**方案对比**
| 方案 | 实现 | 优点 | 缺点 |
| -------------- | --------------------------------------------------------- | ---------------- | --------------------------------------------------- |
| A. 前端管理 | 前端在 URL query 或 localStorage 存 childId每次请求带上 | BFF 无状态,简单 | 切换后页面状态丢失风险 |
| B. BFF Session | Redis 存 `parent:userId:currentChildId`BFF 读取 | 切换全局生效 | BFF 引入会话状态,违反"无状态服务"约束004 §12.1 |
| C. JWT Claims | iam 在 JWT 中注入 `currentChildId` claim | 与认证一体化 | 切换孩子需重签 JWT成本高 |
**ai04 建议****方案 A**(前端管理 childIdBFF 无状态),符合 004 §12.1"无状态服务"约束。`POST /parent/children/:childId/select` 端点可选,仅用于记录切换日志(审计),不持久化会话。
---
## 5. 我的阶段归属
| 维度 | 内容 |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |
| 阶段 | **P4 内容分析阶段**M11-M13 |
| 退出标准pending-features P4 | 教师查看知识图谱前置依赖Neo4j 秒级返回)→ 学生查看学情诊断ClickHouse 宽表 5s 内返回)→ CDC 链路延迟 < 5s |
| parent-bff 在 P4 的最小交付 | 家长查看孩子成绩 + 学情诊断(双轨读:实时查 core-edu 主库 + 聚合查 data-ana ClickHouse 宽表) |
| 依赖上游阶段产出 | P1api-gateway + classes 黄金模板 + shared-proto、P2iam 认证 + teacher-bff BFF 模板、P3core-edu 考试/作业/成绩 + student-bff BFF 模式验证) |
| P4 同阶段依赖 | contentP4 落地、data-anaP4 落地,学情诊断 API |
| P5 阶段扩展 | msg 通知 + push-gateway 推送 + 通知偏好配置 |
| 前置阻塞 | iam 必须先补"家长-学生关联查询"接口(见 §7.1 |
### 5.1 P4 阶段最小可行集合MVP
parent-bff 在 P4 阶段优先级:
| 优先级 | 端点 | P4 必需 | 说明 |
| ------ | -------------------------------------------------- | ------- | ------------------------------------------- |
| P0 | `/parent/children` GET | ✅ | 家长核心场景:查孩子列表(依赖 iam 补接口) |
| P0 | `/parent/children/:childId/grades` GET | ✅ | 查孩子成绩 |
| P0 | `/parent/dashboard` GET | ✅ | 家长首页 |
| P1 | `/parent/children/:childId/exams` GET | ✅ | 孩子考试 |
| P1 | `/parent/children/:childId/homework` GET | ✅ | 孩子作业 |
| P1 | `/parent/children/:childId/analytics/trend` GET | ✅ | 学情趋势(依赖 data-ana P4 落地) |
| P1 | `/parent/children/:childId/analytics/weakness` GET | ✅ | 薄弱知识点 |
| P2 | `/parent/notifications` GET | ⚠️ 可选 | P5 msg 服务落地后才有意义 |
| P2 | `/parent/notification-preferences` GET/PUT | ⚠️ 可选 | P5 落地 |
### 5.2 与 student-bff 的协同
parent-bff 与 student-bff 同属 ai04 负责,技术栈完全一致(同语言、同框架、同 BFF 模式)。两者共享:
- **teacher-bff 克隆模板**shared/ 目录结构、main.ts、env.ts、health.controller.ts 等基础代码
- **聚合模式**Promise.allSettled 并行调用 + BadGatewayError 错误处理
- **可观测性**pino + prom-client + OTel 三支柱
- **错误码前缀**`PARENT_BFF_` / `STUDENT_BFF_` 仅前缀不同
**差异点**
- parent-bff 多了"多子女账户切换"上下文
- parent-bff 多了"DataScope=CHILDREN 越权校验"(家长查询的 childId 必须在自己绑定列表内)
- parent-bff 不直接依赖 content / msg / ai按 004 §4但实际场景可能需要待 coord 仲裁)
---
## 6. 我需要对齐的黄金模板项(对照 classes 服务)
> 对照 ai-allocation.md §6 模板第 6 节 + §10 审计模板
| 对齐项 | classes 黄金模板 | parent-bff 计划 | 备注 |
| ------------------------------- | ---------------------------------------- | ------------------------------------------------------------ | ----------------------------------------------------------------- |
| 权限装饰器 `@RequirePermission` | ✅ 全部 Controller 方法 | ⚠️ **不对齐** | BFF 不做权限校验(对齐 teacher-bff透传 `x-user-id` 给下游校验 |
| 错误码前缀统一 | ✅ `CLASSES_` | ✅ `PARENT_BFF_` | 对齐 teacher-bff 的 `TEACHER_BFF_` 模式 |
| loggerpino | ✅ `shared/observability/logger.ts` | ✅ 复制 teacher-bff 实现 | service 名改 `parent-bff` |
| metricsprom-client | ✅ `/metrics` 端点 | ✅ 复制 teacher-bff main.ts 注册方式 | 指标名前缀 `parent_bff_` |
| tracerOpenTelemetry | ✅ OTLP exporter + auto-instrumentations | ✅ 复制 teacher-bff tracer.ts | serviceName 改 `parent-bff` |
| `/healthz` 健康检查 | ✅ liveness | ✅ 复制 teacher-bff | BFF 不查 DB直接返回 ok |
| `/readyz` 健康检查 | ✅ Drizzle `SELECT 1` | ✅ 复制 teacher-bff | BFF 不查 DB直接返回 ok |
| 优雅关闭SIGTERM | ✅ LifecycleService 关闭 DB 连接池 | ✅ main.ts 注册 SIGTERM → `app.close()` + `shutdownTracer()` | BFF 无 DB 连接 |
| 测试覆盖率 ≥ 80% | ✅ Jest | ⚠️ **待补** | BFF 测试重点是 Service 层聚合逻辑 + DataScope 越权校验 |
| Dockerfile 多阶段构建 | ✅ builder + runtime | ✅ 复制 teacher-bff Dockerfile | EXPOSE 改 3010 |
| Zod 输入验证 | ✅ Controller 层 `schema.parse(body)` | ✅ Controller 层校验 | 通知偏好更新 body 需 Zod 校验 |
| GlobalErrorFilter | ✅ `@Catch()` 全局过滤器 | ✅ 复制 teacher-bff | 注册到 main.ts |
| ESM `.js` 后缀 import | ✅ tsconfig NodeNext | ✅ 复制 teacher-bff tsconfig | 所有相对 import 带 `.js` |
| `import type` 纯类型导入 | ✅ | ✅ | 对齐 classes 规范 |
| 环境变量 Zod 校验 | ✅ `config/env.ts` | ✅ 复制 teacher-bff env.ts | 下游 URL 配置项扩展 |
### 6.1 与 teacher-bff 模板的差异点(克隆时必须改)
| 文件 | teacher-bff 现值 | parent-bff 应改为 |
| ------------------------------------- | ----------------------------------------------------- | ---------------------------------------------------- |
| `package.json` name | `@edu/teacher-bff` | `@edu/parent-bff` |
| `src/config/env.ts` `PORT` default | `"3003"` | `"3010"` |
| `src/config/env.ts` 下游 URL | IamServiceUrl / ClassesServiceUrl / CoreEduServiceUrl | + DataAnaServiceUrl / MsgServiceUrl按仲裁结果 |
| `src/teacher/` 目录名 | `teacher/` | `parent/` |
| `@Controller("teacher")` | `"teacher"` | `"parent"` |
| `health.controller.ts` `SERVICE_NAME` | `"teacher-bff"` | `"parent-bff"` |
| `application-error.ts` 错误码前缀 | `TEACHER_BFF_` | `PARENT_BFF_` |
| `application-error.ts` 新增错误类 | — | `ChildNotBoundError(403)`DataScope=CHILDREN 越权) |
| `metrics.ts` 指标名前缀 | `teacher_bff_` | `parent_bff_` |
| `tracer.ts` serviceName | `"teacher-bff"` | `"parent-bff"` |
| `logger.ts` service | `"teacher-bff"` | `"parent-bff"` |
| `main.ts` 启动日志 | `"Teacher BFF started"` | `"Parent BFF started"` |
| `Dockerfile` `EXPOSE` | `3003` | `3010` |
---
## 7. 风险与依赖(待 coord 仲裁)
### 7.1 上游依赖缺口(核心阻塞)
| 风险 | 影响 | 缓解措施 |
| ------------------------------------------------------------------------------- | ---------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **iam 缺失"家长-学生关联查询"接口**proto + REST + schema 三缺失) | **P0 阻塞**parent-bff 核心场景无法实现 | 推动 coord 协调 ai02 在 iam 补1) `iam_student_guardians`2) Repository 查询方法3) `GET /iam/children` REST 端点4) proto `GetChildrenByParent` RPC |
| pending-features P2 提到 `parent_student_relations` 表,但 iam.schema.ts 未实现 | 表缺失 | 同上,推动 ai02 补表 |
| data-ana 服务未实现查询 APIanalytics.proto 3 个 method 无 REST 端点) | P4 学情诊断端点无法实现 | 推动 ai06 在 P4 实现 data-ana 查询 API |
| content.proto 缺 Chapter/Question 域 | parent-bff 不直接依赖 content影响较小 | 推动 coord 在 shared-proto 补全P4 content 服务落地前) |
| iam.proto 缺 Viewport/EffectivePermissions | 家长端导航视口 proto 契约不全 | 当前走 REST `/iam/viewports`proto 补全后切换 |
| 出勤attendance全局缺失 | 家长无法查孩子出勤 | 推动 coord 在 core_edu.proto 补 Attendance 域P4 或后续) |
| msg 通知偏好配置接口缺失 | 家长通知偏好无法配置 | 推动 ai05 在 msg 服务补接口P5 阶段) |
### 7.2 设计决策待仲裁
| 决策点 | 选项 | ai04 建议 |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------- |
| BFF API 风格 | A. REST对齐 teacher-bff 现状)<br/>B. GraphQL对齐 004 §11.3 设计意图) | **A**(与 student-bff 保持一致) |
| BFF 是否做权限校验 | A. 不校验(对齐 teacher-bff透传 x-user-id<br/>B. 加 `@RequirePermission` 装饰器 | **A**BFF 是聚合层,权限由下游服务校验) |
| **DataScope=CHILDREN 越权校验位置** | A. BFF 校验(家长查询的 childId 必须在绑定列表内)<br/>B. 下游服务校验core-edu 接收 childId 时校验) | **A**BFF 层校验更早失败,减少下游调用;但需 iam 提供"查询家长绑定孩子列表"接口) |
| 多子女账户切换方案 | A. 前端管理 childIdBFF 无状态)<br/>B. BFF SessionRedis 存当前 childId<br/>C. JWT Claims | **A**(符合 004 §12.1 无状态约束) |
| **004 §4 依赖图与实际场景的偏差** | 004 列 parent-bff 仅依赖 iam + core-edu但家长通知、学情诊断需要 msg + data-ana | **建议扩展依赖**parent-bff → iam + core-edu + data-ana + msg与 student-bff 对齐),需 coord 仲裁并更新 004 §4 |
| Kafka 事件订阅 | A. P4 不订阅(仅同步聚合)<br/>B. P4 订阅事件推送 | **A**push-gateway P5 才落地) |
| 通知偏好存储位置 | A. msg 服务(通知域内)<br/>B. iam 服务(用户偏好域内) | **A**(通知偏好与通知发送强相关,归 msg 服务) |
| 端口分配 | 3010 | 对齐 full-stack-runbook 端口矩阵3001-3009 已用/将用) |
### 7.3 跨模块协作需求(需提交 coord 协调)
| 需求 | 涉及 AI | 协调内容 |
| ---------------------------------------------------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------- |
| **iam 新增家长-学生关联接口**P0 阻塞) | ai02 | 补 `iam_student_guardians` 表 + Repository + `GET /iam/children` 端点 + proto `GetChildrenByParent` RPC |
| api-gateway 新增 `/parent` 路由 | ai01 | 在 main.go + config.go 新增 `ParentBffURL` 字段 + 路由块 |
| docker-compose.deploy.yml 新增 parent-bff 服务定义 | coordinfra | 端口 3010加入 edu-net + edu-shared 网络 |
| full-stack-runbook 端口矩阵更新 | coorddocs | 追加 3010 行 |
| 004 架构图状态更新 + 依赖图仲裁 | coorddocs | parent-bff 状态从"📐 需设计"改为"✅ 已实现";仲裁是否扩展 parent-bff 依赖到 data-ana + msg |
| shared-proto 补全 iam.protoViewport/EffectivePermissions/StudentParentRelation | coord | 推动 ai02 补 proto |
| shared-proto 补全 core_edu.protoAttendance 域) | coord | 推动 ai03 补 proto |
| data-ana 实现 analytics.proto 查询 API | ai06 | P4 阶段落地 |
| buf.gen.yaml 补 gRPC 插件 | coord | 决定是否在 P4 升级到 gRPC 通信 |
---
## 8. 阶段 1 自检结论
| 检查项 | 状态 |
| ------------------------------------ | ------------------------------- |
| 已读必读文档清单ai-allocation §4 | ✅ |
| 已运行 arch:scan 更新 arch.db | ✅ |
| 已查 arch:query modules / stats | ✅ |
| 已读 classes 黄金模板源码 | ✅ |
| 已读 teacher-bff BFF 模板源码 | ✅ |
| 已读 iam 认证服务源码 | ✅ |
| 已读 shared-proto 全部 .proto | ✅ |
| 已识别 proto 契约缺口 | ✅(见 §7.1 |
| 已识别端口/路由预留情况 | ✅3010 可用,路由未预留) |
| 已识别设计决策待仲裁项 | ✅(见 §7.2 |
| 已识别跨模块协作需求 | ✅(见 §7.3 |
| 已识别 P0 阻塞项 | ✅iam 家长-学生关联接口缺失) |
**ai04 阶段 1 交付完成,请 coord 审核。审核通过后进入阶段 2模块架构设计文档**
**特别提示 coord**parent-bff 存在 P0 阻塞项——iam 缺失"家长-学生关联查询"接口。建议 coord 优先协调 ai02 在 P3 阶段parent-bff P4 落地前)补全此接口,否则 P4 阶段 parent-bff 无法启动实施。