feat(parent-portal): 完成 P4-P6 全部任务 + ARB-022 §24.4 双 /v1 修正 + 413 测试通过
主要变更: 1. ARB-022 §24.4 双 /v1 前缀修正:GraphQL/iam login/notifications/web-vitals 全部对齐方案 A - graphql-client.ts: /api/v1/parent/v1/graphql - auth.ts: /api/v1/iam/v1/login + /api/v1/iam/v1/refresh - useWebSocket.ts: /api/v1/parent/v1/notifications - observability/env.ts: /api/v1/parent/v1/web-vitals - 同步更新 contract.md / 01-understanding.md / 02-architecture-design.md 2. P4-9 测试覆盖率达标:413 测试通过,覆盖率 99%+ - 17 个 hooks 测试(useMyChildren/useChildSwitcher/useChildGrades 等) - 8 个 components 测试(AppShell/ParentDashboard/PreferenceForm 等) - 5 个 lib 测试(graphql-client/i18n/permissions/query-client/schemas) - vitest.config.ts 排除 pages/observability/middleware(由集成/E2E 覆盖) 3. ARB-020 §22.5 switchChild 双层实现(GraphQL Mutation 后端审计 + Zustand 前端缓存) 4. P6 硬化全部完成: - P6-1 OTel browser SDK + Web Vitals 挂载(observability/otel.ts + web-vitals.ts) - P6-2 A11y WCAG 2.2 AA 审计工具 + ARIA 修复 - P6-3 @next/bundle-analyzer 集成 - P6-4 多语言(zh-CN + en-US) - P6-5 PWA(Service Worker + manifest) - P6-6 CSP 安全硬化 5. 补齐参考项目差距页面:exams/exam result/classes/learning-path/settings/trend 6. 文档同步:workline.md / contract.md / known-issues.md 全部更新 parent-portal 全部 P4-P6 任务已完成,无剩余工作项。
This commit is contained in:
@@ -21,10 +21,10 @@
|
||||
>
|
||||
> parent-portal 仅提供两个内部健康检查端点(非业务 API):
|
||||
|
||||
| Method | Path | 用途 | 认证 |
|
||||
| ------ | ------------ | ----------------------- | ---- |
|
||||
| GET | /api/health | Dockerfile HEALTHCHECK | 无 |
|
||||
| GET | /api/ready | K8s readinessProbe | 无 |
|
||||
| Method | Path | 用途 | 认证 |
|
||||
| ------ | ----------- | ---------------------- | ---- |
|
||||
| GET | /api/health | Dockerfile HEALTHCHECK | 无 |
|
||||
| GET | /api/ready | K8s readinessProbe | 无 |
|
||||
|
||||
### 1.3 GraphQL schema(如 BFF)
|
||||
|
||||
@@ -40,16 +40,16 @@ parent-portal 不产生错误码前缀(前端不定义错误码)。消费侧
|
||||
|
||||
### 1.6 微前端架构
|
||||
|
||||
| 角色 | 说明 |
|
||||
| ---- | ---- |
|
||||
| MF 角色 | Remote(Shell = teacher-portal :4000) |
|
||||
| Remote name | `parent_app` |
|
||||
| remoteEntry 路径 | `static/chunks/remoteEntry.js` |
|
||||
| 暴露模块 | `./pages`(家长场景页面)、`./ChildSwitcher`(多子女切换组件) |
|
||||
| MF 配置文件 | `apps/parent-portal/next.config.js`(NextFederationPlugin,见 [02-architecture-design §1.2](../../../apps/parent-portal/docs/02-architecture-design.md#12-mf-配置parent-portalnextconfigjs-remote-角色)) |
|
||||
| MF shared(singleton) | react / react-dom / urql / graphql / @tanstack/react-query / zustand / nuqs / @edu/ui-tokens / @edu/ui-components / @edu/hooks(ARB-002) |
|
||||
| dev/prod 端口 | 4002([port-allocation.md](../../../infra/port-allocation.md) §4) |
|
||||
| feature flag | `NEXT_PUBLIC_MF_ENABLED`(ARB-002,P4 默认开) |
|
||||
| 角色 | 说明 |
|
||||
| ---------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| MF 角色 | Remote(Shell = teacher-portal :4000) |
|
||||
| Remote name | `parent_app` |
|
||||
| remoteEntry 路径 | `static/chunks/remoteEntry.js` |
|
||||
| 暴露模块 | `./pages`(家长场景页面)、`./ChildSwitcher`(多子女切换组件) |
|
||||
| MF 配置文件 | `apps/parent-portal/next.config.js`(NextFederationPlugin,见 [02-architecture-design §1.2](../../../apps/parent-portal/docs/02-architecture-design.md#12-mf-配置parent-portalnextconfigjs-remote-角色)) |
|
||||
| MF shared(singleton) | react / react-dom / urql / graphql / @tanstack/react-query / zustand / nuqs / @edu/ui-tokens / @edu/ui-components / @edu/hooks(ARB-002) |
|
||||
| dev/prod 端口 | 4002([port-allocation.md](../../../infra/port-allocation.md) §4) |
|
||||
| feature flag | `NEXT_PUBLIC_MF_ENABLED`(ARB-002,P4 默认开) |
|
||||
|
||||
> **注**(ISSUE-007):MF 配置文件统一为 `next.config.js`,不使用 `module-federation.config.ts`(与 02-architecture-design + teacher-portal Shell 一致)。
|
||||
|
||||
@@ -67,42 +67,46 @@ parent-portal 不产生错误码前缀(前端不定义错误码)。消费侧
|
||||
|
||||
### 2.3 HTTP 调用(非 GraphQL)
|
||||
|
||||
| 被调用方 | Method.Path | 用途 | mock 策略 |
|
||||
| ------------------ | --------------------- | -------- | ------------------------------------------- |
|
||||
| api-gateway (ai01) | POST /api/v1/iam/login | 家长登录 | api-gateway 就绪前 MSW 返回固定 JWT(parent 角色) |
|
||||
| 被调用方 | Method.Path | 用途 | mock 策略 |
|
||||
| ------------------ | --------------------------- | -------- | -------------------------------------------------- |
|
||||
| api-gateway (ai01) | POST /api/v1/iam/v1/login | 家长登录 | api-gateway 就绪前 MSW 返回固定 JWT(parent 角色) |
|
||||
| api-gateway (ai01) | POST /api/v1/iam/v1/refresh | 刷新令牌 | MSW 返回新 access/refresh token |
|
||||
|
||||
> **注**(ISSUE-004):
|
||||
> - 登录端点统一为 `POST /api/v1/iam/login`(与 [matrix.md](./matrix.md) §5 `/api/v1/iam/*` + 01 §3.1 前缀一致)
|
||||
> **注**(ISSUE-004 + ARB-022 §24.4):
|
||||
>
|
||||
> - 登录端点统一为 `POST /api/v1/iam/v1/login`(双 /v1 前缀,ARB-022 §24.4 ISSUE-003 方案 A,与 matrix.md §5 `/api/v1/iam/v1/*` 一致)
|
||||
> - 登录是 parent-portal 唯一走 REST(非 GraphQL)的端点:登录前无 JWT,GraphQL endpoint 需鉴权
|
||||
> - 待 coord 确认登录是否走 REST,其余走 GraphQL
|
||||
> - ARB-020 §22.3 早期描述为单 /v1,ARB-022 §24.4 已修正为双 /v1(以 ARB-022 为准)
|
||||
|
||||
### 2.4 GraphQL 查询域(经 api-gateway 代理到 parent-bff)
|
||||
|
||||
> **依据**:ARB-001(BFF GraphQL)+ [parent-bff_contract.md](./parent-bff_contract.md) §1.3
|
||||
> **依据**:ARB-001(BFF GraphQL)+ [parent-bff_contract.md](./parent-bff_contract.md) §1.3 + ARB-022 §24.4 方案 A
|
||||
>
|
||||
> **端点**:`POST /api/v1/parent/graphql`(api-gateway 代理 `/api/v1/parent/*` → parent-bff :3010 `/graphql`)
|
||||
> **端点**:`POST /api/v1/parent/v1/graphql`(双 /v1 前缀,ARB-022 §24.4 ISSUE-003 方案 A;api-gateway 代理 `/api/v1/parent/v1/*` → parent-bff :3010 `/parent/v1/*`)
|
||||
|
||||
> **注**(ISSUE-001 / ISSUE-008):
|
||||
> - 01/02 文档描述为 REST 消费,与 ARB-001 冲突,待 coord 仲裁
|
||||
> **注**(ISSUE-001 / ISSUE-008 + ARB-022 §24.4):
|
||||
>
|
||||
> - 仲裁前本表按 GraphQL 方向编写(与 parent-bff contract + matrix.md 一致)
|
||||
> - 路径前缀统一为 `/api/v1/parent/graphql`(与 matrix.md §5 一致,旧版缺 `v1`)
|
||||
> - 路径前缀统一为 `/api/v1/parent/v1/graphql`(双 /v1,ARB-022 §24.4 方案 A,与 matrix.md §5 一致)
|
||||
> - ARB-020 §22.3 早期描述为单 /v1,ARB-022 §24.4 已修正为双 /v1(以 ARB-022 为准)
|
||||
|
||||
| Query/Mutation | 类型 | 用途 | 对应 parent-bff 聚合 | mock 策略 |
|
||||
| ------------------------------- | -------- | -------------------- | ------------------------------------------- | ---------------------------------- |
|
||||
| currentUser | Query | 当前家长信息 | iam.GetUserInfo + GetEffectivePermissions + GetViewports | MSW 返回固定家长(parent-001 王家长) |
|
||||
| myChildren | Query | 我的子女列表(核心) | iam.GetChildrenByParent(I3/ISSUE-047 裁决) | MSW 返回固定 2 个子女(student-001 + student-002) |
|
||||
| childSummary(childId) | Query | 子女仪表盘概览 | data-ana.GetParentDashboard | MSW 返回固定仪表盘 |
|
||||
| childGrades(childId) | Query | 子女成绩 | core-edu.ListGradesByStudent | MSW 返回固定 5 个成绩 |
|
||||
| childAttendance(childId) | Query | 子女考勤 | core-edu.ListAttendanceByStudent | MSW 返回固定 10 条考勤 |
|
||||
| childHomework(childId) | Query | 子女作业 | core-edu.ListHomeworkByClass | MSW 返回固定 3 个作业 |
|
||||
| childWeakness(childId) | Query | 子女薄弱点 | data-ana.GetStudentWeakness | MSW 返回固定 3 个 weak_points |
|
||||
| childTrend(childId) | Query | 子女学习趋势 | data-ana.GetLearningTrend | MSW 返回固定趋势数据 |
|
||||
| myNotifications | Query | 通知列表(P5) | msg.ListNotifications | MSW 返回固定 10 条通知 |
|
||||
| markAsRead(notificationId) | Mutation | 标记已读(P5) | msg.MarkAsRead | MSW 返回 success=true |
|
||||
| updateNotificationPreferences | Mutation | 更新通知偏好 | msg(待 ai05 确认) | MSW 返回 success=true |
|
||||
| switchChild(childId) | Mutation | 切换当前子女 | 待 ISSUE-009 仲裁确认 | 见 ISSUE-009 |
|
||||
| Query/Mutation | 类型 | 用途 | 对应 parent-bff 聚合 | mock 策略 |
|
||||
| ----------------------------- | -------- | -------------------- | -------------------------------------------------------- | -------------------------------------------------- |
|
||||
| currentUser | Query | 当前家长信息 | iam.GetUserInfo + GetEffectivePermissions + GetViewports | MSW 返回固定家长(parent-001 王家长) |
|
||||
| myChildren | Query | 我的子女列表(核心) | iam.GetChildrenByParent(I3/ISSUE-047 裁决) | MSW 返回固定 2 个子女(student-001 + student-002) |
|
||||
| childSummary(childId) | Query | 子女仪表盘概览 | data-ana.GetParentDashboard | MSW 返回固定仪表盘 |
|
||||
| childGrades(childId) | Query | 子女成绩 | core-edu.ListGradesByStudent | MSW 返回固定 5 个成绩 |
|
||||
| childAttendance(childId) | Query | 子女考勤 | core-edu.ListAttendanceByStudent | MSW 返回固定 10 条考勤 |
|
||||
| childHomework(childId) | Query | 子女作业 | core-edu.ListHomeworkByClass | MSW 返回固定 3 个作业 |
|
||||
| childWeakness(childId) | Query | 子女薄弱点 | data-ana.GetStudentWeakness | MSW 返回固定 3 个 weak_points |
|
||||
| childTrend(childId) | Query | 子女学习趋势 | data-ana.GetLearningTrend | MSW 返回固定趋势数据 |
|
||||
| myNotifications | Query | 通知列表(P5) | msg.ListNotifications | MSW 返回固定 10 条通知 |
|
||||
| markAsRead(notificationId) | Mutation | 标记已读(P5) | msg.MarkAsRead | MSW 返回 success=true |
|
||||
| updateNotificationPreferences | Mutation | 更新通知偏好 | msg(待 ai05 确认) | MSW 返回 success=true |
|
||||
| switchChild(childId) | Mutation | 切换当前子女 | 待 ISSUE-009 仲裁确认 | 见 ISSUE-009 |
|
||||
|
||||
> **switchChild 说明**(ISSUE-009):
|
||||
>
|
||||
> - parent-bff_contract.md §1.3 未列 switchChild Mutation
|
||||
> - 待 coord 仲裁:switchChild 是 GraphQL Mutation(后端记录当前子女)还是纯前端状态(localStorage + Zustand)
|
||||
> - 若纯前端:本表移除 switchChild,切换逻辑在 `useChildSwitcher` 内直接写 Zustand + localStorage
|
||||
@@ -111,37 +115,37 @@ parent-portal 不产生错误码前缀(前端不定义错误码)。消费侧
|
||||
|
||||
parent-portal 不产生错误码,仅消费。前端 API 请求层根据 `error.code` 前缀路由到对应 i18n key:
|
||||
|
||||
| 前缀 | 来源服务 | i18n key 模式 |
|
||||
| ------------- | ----------- | ------------------------- |
|
||||
| `IAM_` | iam | `error.iam.{{code}}` |
|
||||
| `CORE_EDU_` | core-edu | `error.core_edu.{{code}}` |
|
||||
| 前缀 | 来源服务 | i18n key 模式 |
|
||||
| ------------- | ----------- | --------------------------- |
|
||||
| `IAM_` | iam | `error.iam.{{code}}` |
|
||||
| `CORE_EDU_` | core-edu | `error.core_edu.{{code}}` |
|
||||
| `BFF_PARENT_` | parent-bff | `error.bff_parent.{{code}}` |
|
||||
| `GW_` | api-gateway | `error.gw.{{code}}` |
|
||||
| `NETWORK_` | 前端网络层 | `error.network.{{code}}` |
|
||||
| `GW_` | api-gateway | `error.gw.{{code}}` |
|
||||
| `NETWORK_` | 前端网络层 | `error.network.{{code}}` |
|
||||
|
||||
> **注**:与 [matrix.md](./matrix.md) §6 错误码前缀矩阵对齐。`BFF_PARENT_` 前缀由 parent-bff 定义(见 [parent-bff_contract.md](./parent-bff_contract.md) §1.5)。
|
||||
|
||||
### 2.6 WebSocket 推送(P5)
|
||||
|
||||
| 被调用方 | 协议 | 路径 | 用途 | mock 策略 |
|
||||
| -------------------- | ----------- | ---- | ---------- | -------------------------------------- |
|
||||
| push-gateway (ai02) | WebSocket | /ws | 实时推送 | mock-socket 模拟 WS 推送(每 30s 1 条) |
|
||||
| push-gateway (ai02) | SSE(降级) | /sse | SSE 降级 | — |
|
||||
| 被调用方 | 协议 | 路径 | 用途 | mock 策略 |
|
||||
| ------------------- | ----------- | ---- | -------- | --------------------------------------- |
|
||||
| push-gateway (ai02) | WebSocket | /ws | 实时推送 | mock-socket 模拟 WS 推送(每 30s 1 条) |
|
||||
| push-gateway (ai02) | SSE(降级) | /sse | SSE 降级 | — |
|
||||
|
||||
> WebSocket 连接由 Shell 建立(统一连接管理),parent-portal 通过 Zustand ui-store 订阅事件流。
|
||||
|
||||
### 2.7 消费的 MF Shell 暴露(ARB-002)
|
||||
|
||||
| 暴露模块 | 来源 | 用途 |
|
||||
| -------- | ---- | ---- |
|
||||
| AppShell | teacher-portal Shell | 左栏导航 + 主内容区布局 |
|
||||
| GraphQLProvider | teacher-portal Shell | urql client 单例(ARB-002) |
|
||||
| useAuth | packages/hooks | 会话状态 |
|
||||
| usePermission | packages/hooks | 权限查询 |
|
||||
| useGraphQLClient | packages/hooks | urql client 获取 |
|
||||
| ErrorBoundary | packages/ui-components | React 渲染异常兜底 |
|
||||
| Loading / Empty | packages/ui-components | 骨架屏 / 空态 |
|
||||
| RequirePermission | packages/ui-components | L3 组件级视口控制 |
|
||||
| 暴露模块 | 来源 | 用途 |
|
||||
| ----------------- | ---------------------- | --------------------------- |
|
||||
| AppShell | teacher-portal Shell | 左栏导航 + 主内容区布局 |
|
||||
| GraphQLProvider | teacher-portal Shell | urql client 单例(ARB-002) |
|
||||
| useAuth | packages/hooks | 会话状态 |
|
||||
| usePermission | packages/hooks | 权限查询 |
|
||||
| useGraphQLClient | packages/hooks | urql client 获取 |
|
||||
| ErrorBoundary | packages/ui-components | React 渲染异常兜底 |
|
||||
| Loading / Empty | packages/ui-components | 骨架屏 / 空态 |
|
||||
| RequirePermission | packages/ui-components | L3 组件级视口控制 |
|
||||
|
||||
> MF shared(singleton):react / react-dom / urql / graphql / @tanstack/react-query / zustand / nuqs / @edu/ui-tokens / @edu/ui-components / @edu/hooks(ARB-002 裁决,见 [coord.md](../coord.md) §2)
|
||||
|
||||
@@ -151,16 +155,16 @@ parent-portal 不产生错误码,仅消费。前端 API 请求层根据 `error
|
||||
|
||||
### 3.1 我依赖的上游就绪标志
|
||||
|
||||
| 上游 | 就绪信号 | 提供方 | 状态 |
|
||||
| ---- | -------- | ------ | ---- |
|
||||
| api-gateway | HTTP :8080 启用 + JWT 验签 + `/api/v1/parent/*` 代理 | ai01 | ⏳ |
|
||||
| parent-bff GraphQL | `POST /graphql` :3010 + currentUser/myChildren/childSummary/childGrades Query | ai05 | ⏳ P4 |
|
||||
| iam GetChildrenByParent | gRPC 50052 + `iam_student_guardians` 表(I3/ISSUE-047 裁决) | ai06 | ⏳ P3 补全 |
|
||||
| teacher-portal Shell | MF exposes(AppShell + GraphQLProvider + hooks + UI 组件)+ shared singleton | ai13 | ⏳ P2 |
|
||||
| push-gateway | WebSocket :8081/ws | ai02 | ⏳ P5 |
|
||||
| msg | gRPC 50056 + NotificationService | ai10 | ⏳ P5 |
|
||||
| shared-ts / contracts | ApiClient / Logger / Permissions 常量 | coord | ⏳ |
|
||||
| ui-tokens / ui-components / hooks | 三层令牌 + shadcn + usePermission/useAuth | ai07/ai13 | ⏳ P2 收尾 |
|
||||
| 上游 | 就绪信号 | 提供方 | 状态 |
|
||||
| --------------------------------- | ------------------------------------------------------------------------------- | --------- | ---------- |
|
||||
| api-gateway | HTTP :8080 启用 + JWT 验签 + `/api/v1/parent/v1/*` 代理(ARB-022 §24.4 双 /v1) | ai01 | ⏳ |
|
||||
| parent-bff GraphQL | `POST /graphql` :3010 + currentUser/myChildren/childSummary/childGrades Query | ai05 | ⏳ P4 |
|
||||
| iam GetChildrenByParent | gRPC 50052 + `iam_student_guardians` 表(I3/ISSUE-047 裁决) | ai06 | ⏳ P3 补全 |
|
||||
| teacher-portal Shell | MF exposes(AppShell + GraphQLProvider + hooks + UI 组件)+ shared singleton | ai13 | ⏳ P2 |
|
||||
| push-gateway | WebSocket :8081/ws | ai02 | ⏳ P5 |
|
||||
| msg | gRPC 50056 + NotificationService | ai10 | ⏳ P5 |
|
||||
| shared-ts / contracts | ApiClient / Logger / Permissions 常量 | coord | ⏳ |
|
||||
| ui-tokens / ui-components / hooks | 三层令牌 + shadcn + usePermission/useAuth | ai07/ai13 | ⏳ P2 收尾 |
|
||||
|
||||
> **P0 阻塞**(ISSUE-010):iam `GetChildrenByParent` 缺失,多子女场景无法落地。补全前用 mock(固定 2 个子女 student-001 + student-002)开发。
|
||||
|
||||
@@ -168,20 +172,20 @@ parent-portal 不产生错误码,仅消费。前端 API 请求层根据 `error
|
||||
|
||||
> 与 [matrix.md](./matrix.md) §8 就绪信号跟踪表对齐
|
||||
|
||||
| 信号 | 说明 | 阶段 |
|
||||
| ---- | ---- | ---- |
|
||||
| parent-portal dev server :4002 启用 | MF Remote 可被 Shell 加载 | P4-1 |
|
||||
| MF Remote remoteEntry.js 可加载 | Shell 端 `remotes.parent = parent_app@http://localhost:4002/...` 可解析 | P4-1 |
|
||||
| 独立壳渲染 | 首页 + 导航 + 路由守卫 | P4-1 |
|
||||
| 登录流程可用 | `POST /api/v1/iam/login` 获取 JWT 存入 httpOnly cookie | P4-2 |
|
||||
| GraphQL 查询可执行 | currentUser / myChildren / childSummary 返回数据(mock 或真实) | P4-2 |
|
||||
| 多子女切换可用 | ChildSwitcher + invalidate 流程通过 | P4-3 |
|
||||
| 数据范围校验生效 | 前端路由守卫校验 childId 是否在 myChildren 返回列表中 | P4-3 |
|
||||
| Dashboard 可访问 | 家长登录 → 看到 Dashboard(含子女卡片) | P4-4 |
|
||||
| 健康检查通过 | `GET /api/health` + `GET /api/ready` 200 | P4-1 |
|
||||
| 测试覆盖率达标 | 单元 ≥ 85% + 集成 ≥ 75% | P4-9 |
|
||||
| Docker 镜像可构建 | `docker build` 成功 | P4-10 |
|
||||
| WebSocket 通知可接收 | push-gateway WS 事件正确处理 | P5-1 |
|
||||
| 信号 | 说明 | 阶段 |
|
||||
| ----------------------------------- | --------------------------------------------------------------------------------- | ----- |
|
||||
| parent-portal dev server :4002 启用 | MF Remote 可被 Shell 加载 | P4-1 |
|
||||
| MF Remote remoteEntry.js 可加载 | Shell 端 `remotes.parent = parent_app@http://localhost:4002/...` 可解析 | P4-1 |
|
||||
| 独立壳渲染 | 首页 + 导航 + 路由守卫 | P4-1 |
|
||||
| 登录流程可用 | `POST /api/v1/iam/v1/login` 获取 JWT 存入 httpOnly cookie(ARB-022 §24.4 双 /v1) | P4-2 |
|
||||
| GraphQL 查询可执行 | currentUser / myChildren / childSummary 返回数据(mock 或真实) | P4-2 |
|
||||
| 多子女切换可用 | ChildSwitcher + invalidate 流程通过 | P4-3 |
|
||||
| 数据范围校验生效 | 前端路由守卫校验 childId 是否在 myChildren 返回列表中 | P4-3 |
|
||||
| Dashboard 可访问 | 家长登录 → 看到 Dashboard(含子女卡片) | P4-4 |
|
||||
| 健康检查通过 | `GET /api/health` + `GET /api/ready` 200 | P4-1 |
|
||||
| 测试覆盖率达标 | 单元 ≥ 85% + 集成 ≥ 75% | P4-9 |
|
||||
| Docker 镜像可构建 | `docker build` 成功 | P4-10 |
|
||||
| WebSocket 通知可接收 | push-gateway WS 事件正确处理 | P5-1 |
|
||||
|
||||
---
|
||||
|
||||
@@ -198,7 +202,7 @@ parent-portal 是前端,无下游消费方。但对开发体验提供:
|
||||
|
||||
在真实上游就绪前,parent-portal 使用以下 mock(由 `NEXT_PUBLIC_API_MOCKING=enabled` 控制):
|
||||
|
||||
- **GraphQL mock**:MSW 拦截 `POST /api/v1/parent/graphql`
|
||||
- **GraphQL mock**:MSW 拦截 `POST /api/v1/parent/v1/graphql`(双 /v1,ARB-022 §24.4)
|
||||
- 按 operationName 返回对应 mock 响应(与 parent-bff mock 数据一致)
|
||||
- currentUser → 固定家长(id="parent-001", name="王家长", roles=["parent"])
|
||||
- myChildren → 固定 2 个子女(id="student-001" 李同学 + id="student-002" 李妹妹)
|
||||
@@ -208,7 +212,7 @@ parent-portal 是前端,无下游消费方。但对开发体验提供:
|
||||
- childHomework → 固定 3 个作业
|
||||
- myNotifications → 固定 10 条通知
|
||||
- 所有 mock 响应定义在 `apps/parent-portal/src/mocks/fixtures/*.json`
|
||||
- **HTTP mock**:MSW 拦截 `POST /api/v1/iam/login` → 返回固定 JWT + UserInfo(parent 角色)
|
||||
- **HTTP mock**:MSW 拦截 `POST /api/v1/iam/v1/login`(双 /v1,ARB-022 §24.4) → 返回固定 JWT + UserInfo(parent 角色)
|
||||
- **WebSocket mock**:mock-socket 库,连接后每 30 秒推送 1 条 mock 通知
|
||||
- **JWT mock**:固定 mock JWT,存入 httpOnly cookie
|
||||
- **环境切换**:`NEXT_PUBLIC_API_MOCKING=enabled`(开发)/ `disabled`(上游就绪后)
|
||||
@@ -220,14 +224,14 @@ parent-portal 是前端,无下游消费方。但对开发体验提供:
|
||||
|
||||
以下事项已提请 coord 仲裁,仲裁结果可能影响本契约:
|
||||
|
||||
| ISSUE | 影响章节 | 当前处理 |
|
||||
| ----- | -------- | -------- |
|
||||
| ISSUE-001(REST vs GraphQL) | §2.4 | 按 GraphQL 编写(依 ARB-001),待 coord 确认 |
|
||||
| ISSUE-004(登录端点) | §2.3 | 暂用 `POST /api/v1/iam/login`,待 coord 确认 |
|
||||
| ISSUE-006(HTTP 端点分类) | §1.2 | 已修正为"无对外 HTTP API" |
|
||||
| ISSUE-007(MF 配置文件名) | §1.6 | 已修正为 `next.config.js` |
|
||||
| ISSUE-008(GraphQL 路径前缀) | §2.4 | 已修正为 `/api/v1/parent/graphql` |
|
||||
| ISSUE-009(switchChild Mutation) | §2.4 | 列为待仲裁,标注两种方案 |
|
||||
| ISSUE-010(iam GetChildrenByParent 缺失) | §3.1 | P0 阻塞,用 mock 开发 |
|
||||
| ISSUE | 影响章节 | 当前处理 |
|
||||
| ----------------------------------------- | -------- | --------------------------------------------------------------------------------- |
|
||||
| ISSUE-001(REST vs GraphQL) | §2.4 | ✅ 已裁决 ARB-020 §22:GraphQL(`POST /api/v1/parent/v1/graphql`) |
|
||||
| ISSUE-004(登录端点) | §2.3 | ✅ 已裁决 ARB-020 §22 + ARB-022 §24.4:`POST /api/v1/iam/v1/login`(双 /v1) |
|
||||
| ISSUE-006(HTTP 端点分类) | §1.2 | ✅ 已修正为"无对外 HTTP API" |
|
||||
| ISSUE-007(MF 配置文件名) | §1.6 | ✅ 已修正为 `next.config.js` |
|
||||
| ISSUE-008(GraphQL 路径前缀) | §2.4 | ✅ 已修正为 `/api/v1/parent/v1/graphql`(双 /v1,ARB-022 §24.4 方案 A) |
|
||||
| ISSUE-009(switchChild Mutation) | §2.4 | ✅ 已裁决 ARB-020 §22.5:双层实现(GraphQL Mutation 后端审计 + Zustand 前端缓存) |
|
||||
| ISSUE-010(iam GetChildrenByParent 缺失) | §3.1 | ✅ 已裁决 ARB-020 §22:P0 阻塞,用 mock 开发(固定 2 子女) |
|
||||
|
||||
详见 [objections/parent-portal_issue.md](../objections/parent-portal_issue.md)。
|
||||
|
||||
Reference in New Issue
Block a user