# parent-portal 问题记录 > 负责人:ai15 > 关联:[coord.md](../coord.md)、[contracts/parent-portal_contract.md](../contracts/parent-portal_contract.md) > 规则:AI 遇到问题时在此追加条目,coord 仲裁后更新状态 --- ## §0 已有仲裁核查(ai15 复核 ARB-001 / ARB-002 落地情况) > ai15 接管 parent-portal 后,核查 coord 已发布的两项仲裁(ARB-001 teacher-bff GraphQL schema、ARB-002 MF Shell 暴露清单)在 parent-portal 文档中的落地情况。 ### 0.1 ARB-001(teacher-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 已对齐 | ✅ | **结论**:ARB-001 的核心裁决(BFF = GraphQL)在 parent-portal 的 01/02 文档中**未落地**,01 §3.1 与 02 §4.1 仍按 REST 编写,与 [parent-bff_contract.md](../contracts/parent-bff_contract.md) §1.3(GraphQL 端点 :3010)和 [matrix.md](../matrix.md) §3(parent-bff GraphQL)直接冲突。提请 ISSUE-001。 ### 0.2 ARB-002(MF Shell 暴露清单)核查 | 核查项 | ARB-002 结论 | parent-portal 落地情况 | 状态 | | ----------------------------------- | ------------ | -------------------------------------------------------------------------------------------------------------------------------------- | --------- | | Shell 暴露 GraphQLProvider | ✅ 已裁决 | 01 §4 技术栈未列 urql/GraphQL client;02 §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 已对齐 | ✅ | | feature flag NEXT_PUBLIC_MF_ENABLED | ✅ 已裁决 | 01/02 均未提及 | ❌ 未落地 | **结论**:ARB-002 关于 GraphQL client 与 MF shared 的裁决在 parent-portal 文档中**部分未落地**。提请 ISSUE-002。 --- ## 问题列表 ### ISSUE-001-ai15:01/02 文档 REST 消费 parent-bff 与 ARB-001 GraphQL 裁决冲突 - **提请方**:ai15 - **日期**:2026-07-10 - **类型**:契约不明确(文档与已裁决架构冲突) - **描述**: - 01-understanding.md §3.1 列出 parent-portal 经 REST 消费 parent-bff:`GET /parent/viewports`、`GET /parent/children`、`POST /parent/children/:childId/select`、`GET /parent/notifications`、`PUT /parent/notification-preferences` 等 - 02-architecture-design.md §4.1 `useParentApi` 实现全部基于 `api.get()`/`api.post()` REST 调用 - 但 ARB-001(coord.md §1)已裁决 BFF 用 GraphQL;[parent-bff_contract.md](../contracts/parent-bff_contract.md) §1.3 明确 parent-bff 提供 `POST /graphql`(:3010);[matrix.md](../matrix.md) §3 确认 parent-bff = GraphQL - parent-portal 自己的 [contract.md](../contracts/parent-portal_contract.md) §2.3-2.4 也写明消费 GraphQL(`POST /api/parent/graphql`,Query 域:currentUser/myChildren/childSummary/childGrades 等) - **文档内部自相矛盾**:01/02 用 REST,contract.md 用 GraphQL - **建议方案**: 1. coord 确认 parent-portal 消费 parent-bff **统一用 GraphQL**(与 ARB-001、parent-bff contract、matrix.md 一致) 2. ai15 据此修订 01 §3.1(改为 GraphQL Query/Mutation 域)、§3.1.1(X-Fields 字段裁剪改为 GraphQL query 字段选择)、02 §4.1(`useParentApi` 改为 GraphQL hooks)、§4.2(TanStack Query 约定配合 GraphQL operations)、§11.3 未决设计决策 #2(移除,已裁决) 3. 若 coord 另有裁决(如 parent-portal 特殊走 REST),以 coord 裁决为准 - **状态**:待 coord 仲裁 ### ISSUE-002-ai15:MF shared 配置缺 urql/graphql/@edu/* 与 ARB-002 冲突 - **提请方**:ai15 - **日期**:2026-07-10 - **类型**:契约不明确(文档与已裁决 MF 配置冲突) - **描述**: - 02-architecture-design.md §1.2 MF `shared` 配置仅列:`react`、`react-dom`、`@tanstack/react-query`、`zustand`、`nuqs` - ARB-002(coord.md §2)裁决的 `shared` 应包含:`react`、`react-dom`、`urql`、`graphql`、`@edu/ui-tokens`、`@edu/ui-components`、`@edu/hooks` - 缺失 `urql`/`graphql` 会导致 Remote 与 Shell 各加载一份 GraphQL client 实例,破坏单例,引发缓存不一致与重复请求 - 缺失 `@edu/*` 会导致设计令牌/UI 组件/Hooks 各加载一份 - 同时 01 §4 技术栈表未列 GraphQL client(urql),与 ARB-002 Shell 暴露 GraphQLProvider 矛盾 - **建议方案**: 1. coord 确认 parent-portal MF `shared` 必须包含 ARB-002 全部 7 项(react/react-dom/urql/graphql/@edu/ui-tokens/@edu/ui-components/@edu/hooks) 2. ai15 修订 02 §1.2 `shared` 配置 + 01 §4 技术栈表(新增 urql + GraphQL client 行) 3. 02 §4.1 `useParentApi` 改为从 Shell 暴露的 `useGraphQLClient()` 获取 urql client,不再用 REST ApiClient - **状态**:待 coord 仲裁 ### ISSUE-003-ai15:switch-child 端点在 01/02 文档间不一致 - **提请方**:ai15 - **日期**:2026-07-10 - **类型**:契约不明确(文档内部不一致) - **描述**: - 01-understanding.md §3.1 列 `POST /parent/children/:childId/select` - 02-architecture-design.md §2.2 + §4.1 用 `POST /api/v1/parent/switch-child`(body 携带 childId) - 两处路径与语义均不一致(URL param vs body param) - parent-bff contract.md 未列 switch-child(其 §1.3 仅列 Query/Mutation 域,未细到 switch-child) - **建议方案**: 1. 若走 GraphQL(依 ISSUE-001 裁决):switch-child 应为 `mutation switchChild(childId: ID!): SwitchChildPayload!`,不存在 REST 路径 2. 若走 REST:统一为 `POST /api/v1/parent/switch-child`(body 携带 childId,与 02 一致),修订 01 §3.1 3. 请 coord 一并明确 parent-bff GraphQL schema 是否包含 `switchChild` Mutation(当前 parent-bff contract.md 未列) - **状态**:待 coord 仲裁 ### ISSUE-004-ai15:登录端点在 01 / contract.md / matrix.md 间三方不一致 - **提请方**:ai15 - **日期**:2026-07-10 - **类型**:契约不明确(跨文档不一致) - **描述**: - 01-understanding.md §3.1 列 `POST /iam/login` - parent-portal_contract.md §2.3 列 `POST /api/auth/login` - matrix.md §5 规范 iam 经 api-gateway 代理路径为 `/api/v1/iam/*` - 三处不一致,且 contract.md 的 `/api/auth/login` 路径在 matrix.md 中不存在 - **建议方案**: 1. 统一为 `POST /api/v1/iam/login`(与 matrix.md §5 + 01 §3.1 的 `/api/v1/iam/*` 前缀一致) 2. ai15 修订 contract.md §2.3 路径 3. 注意:登录是 parent-portal 唯一可能走 REST(非 GraphQL)的端点,因登录前无 JWT,GraphQL endpoint 需鉴权。请 coord 确认登录是否走 REST `/api/v1/iam/login`,其余走 GraphQL - **状态**:待 coord 仲裁 ### ISSUE-005-ai15:02 §11.3 未决设计决策 #2 "GraphQL vs REST" 已由 ARB-001 裁决,应移除 - **提请方**:ai15 - **日期**:2026-07-10 - **类型**:其他(文档过时) - **描述**: - 02-architecture-design.md §11.3 第 2 项将 "GraphQL vs REST" 列为未决设计决策,建议 "P4 用 REST,后续若 BFF 切 GraphQL 再引入 urql" - 但 ARB-001(coord.md §1)已于 2026-07-09 裁决 BFF 用 GraphQL,且 parent-bff contract.md 确认 GraphQL - 此项已过时,会误导后续开发 - **建议方案**: 1. coord 确认 ARB-001 适用于 parent-portal(即 parent-portal P4 起必须用 GraphQL 消费 parent-bff) 2. ai15 移除 02 §11.3 第 2 项,改为 "已裁决:见 ARB-001,parent-portal 用 GraphQL 消费 parent-bff" - **状态**:待 coord 仲裁 ### ISSUE-006-ai15:contract.md §1.2 将前端页面路由误标为 HTTP 端点 - **提请方**:ai15 - **日期**:2026-07-10 - **类型**:其他(文档分类错误) - **描述**: - parent-portal_contract.md §1.2 "HTTP 端点" 列出:`GET /`、`GET /children`、`GET /child/:id/summary`、`GET /child/:id/grades` 等 - 但 parent-portal 是 Next.js 前端应用,这些是**前端页面路由**(SSR/CSR 路由),不是对外 HTTP API 端点 - 将页面路由放在 "HTTP 端点" 表中会误导下游消费方以为这些是 REST API - 且这些路由与 01 §8 L2 路由表(`/parent/dashboard`、`/parent/children` 等)路径还不一致(contract 用 `/children`,01 用 `/parent/children`) - **建议方案**: 1. coord 确认 parent-portal 作为前端 Remote,不对外提供 HTTP API 端点(§1.2 应为"无") 2. ai15 将 contract.md §1.2 改为 "无(parent-portal 是前端 Remote,不对外提供 HTTP API)",页面路由信息保留在 01 §8 L2 路由表中,不进 contract.md 3. 若需保留 MF 暴露信息,归入 §1.6 微前端架构(已有) - **状态**:待 coord 仲裁 ### ISSUE-007-ai15:contract.md §1.6 module-federation.config.ts 与 02 next.config.js 不一致 - **提请方**:ai15 - **日期**:2026-07-10 - **类型**:其他(文档内部不一致) - **描述**: - parent-portal_contract.md §1.6 列 MF 配置文件为 `apps/parent-portal/module-federation.config.ts` - 02-architecture-design.md §1.2 MF 配置写在 `next.config.js` 中(用 `NextFederationPlugin`) - 两处文件名与位置不一致 - **建议方案**: 1. 统一为 `apps/parent-portal/next.config.js`(与 02 + teacher-portal Shell 一致,Next.js 项目 MF 配置应在 next.config.js) 2. ai15 修订 contract.md §1.6 - **状态**:待 coord 仲裁 ### ISSUE-008-ai15:contract.md §2.3 GraphQL 路径前缀与 matrix.md 不一致 - **提请方**:ai15 - **日期**:2026-07-10 - **类型**:契约不明确(跨文档不一致) - **描述**: - parent-portal_contract.md §2.3 列 `POST /api/parent/graphql` - matrix.md §5 规范 api-gateway 代理 parent-bff 路径为 `/api/v1/parent/*` - 缺 `v1` 版本号 - **建议方案**: 1. 统一为 `POST /api/v1/parent/graphql`(与 matrix.md §5 一致) 2. ai15 修订 contract.md §2.3 + §2.4 - **状态**:待 coord 仲裁 ### ISSUE-009-ai15:parent-bff GraphQL schema 是否包含 switchChild Mutation 未明确 - **提请方**:ai15 - **日期**:2026-07-10 - **类型**:前置依赖缺失(上游契约不全) - **描述**: - parent-bff_contract.md §1.3 列出的 Query/Mutation 域未包含 "switchChild"(切换当前选中子女) - 01-understanding.md §2.2 + 02 §2.2 描述 parent-portal 需调用 `POST /parent/switch-child` 切换子女 - 若走 GraphQL(依 ISSUE-001),parent-bff 需提供 `mutation switchChild(childId: ID!): SwitchChildPayload!` - 但 parent-bff contract 未列此 Mutation,且 iam.GetChildrenByParent 已返回子女列表,切换子女是否需后端记录(还是纯前端 localStorage)需明确 - **建议方案**: 1. 请 coord 协调 ai05(parent-bff)确认:switchChild 是 GraphQL Mutation 还是纯前端状态(localStorage + Zustand) 2. 若纯前端:01/02 移除 `POST /parent/switch-child` 调用,改为 `useChildSwitcher` 直接写 Zustand + localStorage 3. 若需后端记录:请 ai05 在 parent-bff contract.md §1.3 补充 `switchChild` Mutation - **状态**:待 coord 仲裁 ### ISSUE-010-ai15:iam GetChildrenByParent 接口缺失(P0 阻塞,跨模块) - **提请方**:ai15 - **日期**:2026-07-10 - **类型**:前置依赖缺失(跨模块,承自 parent-bff §7.1) - **描述**: - 01-understanding.md §3.1 注明:iam 缺失 "家长-学生关联查询" 接口(`GetChildrenByParent` proto + `GET /iam/children` REST + `iam_student_guardians` 表三缺失) - parent-bff_contract.md §2.1 也标注 "核心依赖 I3/ISSUE-047 裁决" - parent-bff_contract.md §3.1 标注 "iam gRPC 50052 启用(ai06)—— 核心依赖 GetChildrenByParent(I3/ISSUE-047 裁决)" - 此为 parent-portal 多子女场景的 P0 阻塞项,ai06(iam)需在 P3 收尾前补全 - ai15 在此提请,请 coord 跟踪 ai06 进度并确认补全时间点 - **建议方案**: 1. coord 确认 ai06 补全 `GetChildrenByParent` 的时间点(应在 P4 启动前) 2. 在补全前,parent-portal 用 mock(固定 2 个子女)开发,mock 数据与 parent-bff mock 一致(student-001 + student-002) - **状态**:待 coord 仲裁 --- ## §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 项 singleton(react/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 |