# parent-portal 工作排期

> 负责人：ai15
> 关联：[workline.md](../workline.md)、[coord.md](../coord.md)、[contracts/parent-portal_contract.md](../contracts/parent-portal_contract.md)
> 模式：全并行（各 AI 一口气完成 P2-P6 全部代码，开发期间用 mock，最后统一集成测试）

---

## §1 总览

parent-portal 是家长端微前端（MF Remote），挂载到 teacher-portal Shell，覆盖家长仪表盘、多子女切换、子女学情查看、通知偏好等场景。

- **MF 角色**：Remote（Shell = teacher-portal :4000）
- **端口**：4002（dev/prod 一致，[port-allocation.md](../../../../infra/port-allocation.md) §4）
- **阶段归属**：P4 启动（依赖 P4 的 parent-bff + data-ana 就绪）
- **DataScope**：CHILDREN（仅查看自己绑定子女的数据）
- **全阶段目标**：P4 MF Remote 骨架 + 核心页面 → P5 推送接入 + 通知中心 → P6 硬化（A11y/性能/安全/PWA/多语言）

> **前置阻塞**（见 [objections/parent-portal_issue.md](../objections/parent-portal_issue.md) ISSUE-010）：
>
> - iam `GetChildrenByParent` 接口缺失（P0 阻塞，ai06 补全），补全前用 mock（固定 2 个子女 student-001 + student-002）
> - ISSUE-001 待 coord 仲裁（REST vs GraphQL），仲裁前按 GraphQL 预排期，mock 用 MSW 拦截 GraphQL

---

## §2 全阶段甘特图（P4-P6）

```mermaid
gantt
    title ai15 parent-portal 全阶段排期（P4-P6）
    dateFormat YYYY-MM-DD
    axisFormat %m-%d

    section P4 骨架与核心页面（11d）
    4.1 MF Remote 骨架+next.config.js+健康检查 :crit, a15a, 2026-07-29, 2d
    4.2 GraphQL client接入+MSW mock层 :crit, a15b, after a15a, 1d
    4.3 ChildSwitcher+useChildSwitcher+Zustand slice :crit, a15c, after a15b, 2d
    4.4 Dashboard页面+ParentDashboard组件 :a15d, after a15c, 2d
    4.5 子女成绩页面+ChildGradeChart :a15e, after a15c, 1d
    4.6 子女作业页面 :a15f, after a15e, 1d
    4.7 通知偏好页面+PreferenceForm+Zod :a15g, after a15d, 1d
    4.8 跨标签同步(BroadcastChannel) :a15h, after a15c, 1d

    section P4 质量保障（并行）
    4.9 Vitest单测+MSW集成测试 :a15i, after a15g, 2d
    4.10 Dockerfile多阶段构建 :a15j, after a15a, 1d

    section P5 推送与通知中心（5d）
    5.1 WebSocket接入+事件处理 :crit, a15k, after a15i, 2d
    5.2 通知中心页面+NotificationFeed :a15l, after a15k, 2d
    5.3 推送降级(HTTP轮询) :a15m, after a15l, 1d

    section P6 硬化（8d）
    6.1 Web Vitals+OTel browser SDK :a15n, after a15m, 2d
    6.2 A11y WCAG 2.2 AA审计+修复 :a15o, after a15n, 2d
    6.3 性能优化+bundle分析 :a15p, after a15o, 1d
    6.4 多语言扩展(en-US) :a15q, after a15p, 1d
    6.5 PWA(Service Worker+manifest) :a15r, after a15q, 1d
    6.6 安全硬化(CSP+敏感数据脱敏) :a15s, after a15r, 1d
```

> **总工期**：P4 11d + P5 5d + P6 8d = 24d（约 5 周）
> **关键路径**（红色 crit）：MF 骨架 → GraphQL client → ChildSwitcher → 质量保障 → WebSocket → 通知中心

---

## §3 详细任务

### P4 阶段任务

#### P4-1：MF Remote 骨架 + next.config.js + 健康检查

- **负责人**：ai15
- **依赖**：teacher-portal Shell MF 配置就绪（ARB-002，ai13 P2 交付）；ISSUE-002 仲裁（MF shared 清单）
- **交付物**：
  - `apps/parent-portal/next.config.js`（NextFederationPlugin，Remote 角色，`name: parent_app`，`exposes: ./pages + ./ChildSwitcher`，`shared` 含 ARB-002 全部 7 项）
  - `apps/parent-portal/src/app/layout.tsx`（RootLayout，复用 Shell 暴露的字体/令牌/i18n Provider）
  - `apps/parent-portal/src/app/api/health/route.ts`（`GET /api/health` → `{ status: 'ok', ts }`）
  - `apps/parent-portal/src/app/api/ready/route.ts`（`GET /api/ready` → 检查 API_GATEWAY_URL 可达）
  - `apps/parent-portal/tsconfig.json`（继承 tsconfig.base.json，strict）
  - `apps/parent-portal/package.json`（依赖对齐 Shell：react 18.3 + next 14 + urql + @tanstack/react-query v5 + zustand + nuqs）
- **验收标准**：
  1. `pnpm --filter parent-portal dev` 启动 :4002
  2. `GET /api/health` 返回 200
  3. teacher-portal Shell 能加载 parent-portal remoteEntry.js（MF 拓扑验证）
  4. feature flag `NEXT_PUBLIC_MF_ENABLED` 可控制 MF 开关

#### P4-2：GraphQL client 接入 + MSW mock 层

- **负责人**：ai15
- **依赖**：P4-1；ISSUE-001 仲裁（确认 GraphQL）；teacher-portal Shell 暴露 GraphQLProvider（ARB-002）
- **交付物**：
  - `apps/parent-portal/src/lib/graphql-client.ts`（从 Shell 暴露的 `useGraphQLClient()` 获取 urql client 单例）
  - `apps/parent-portal/src/graphql/queries/`（currentUser / myChildren / childSummary / childGrades / childHomework / childTrend / childWeakness 查询文档）
  - `apps/parent-portal/src/graphql/mutations/`（markAsRead / updateNotificationPreferences mutation 文档）
  - `apps/parent-portal/src/mocks/handlers.ts`（MSW 拦截 `POST /api/v1/parent/graphql`，按 operationName 返回 mock）
  - `apps/parent-portal/src/mocks/fixtures/*.json`（固定 2 个子女 student-001 李同学 + student-002 李妹妹，与 parent-bff mock 一致）
  - `apps/parent-portal/src/mocks/browser.ts`（MSW worker 初始化，`NEXT_PUBLIC_API_MOCKING=enabled` 控制）
- **验收标准**：
  1. MSW enabled 时，所有 GraphQL 查询返回 mock 数据
  2. myChildren mock 返回 2 个子女，id 与 childGrades/childHomework mock 的 student_id 一致
  3. urql client 单例跨组件共享（MF shared singleton 验证）

#### P4-3：ChildSwitcher + useChildSwitcher + Zustand slice

- **负责人**：ai15
- **依赖**：P4-2；ISSUE-009 仲裁（switchChild 是 GraphQL Mutation 还是纯前端状态）
- **交付物**：
  - `apps/parent-portal/src/stores/childSwitcherSlice.ts`（Zustand slice：children / currentChildId / isLoading / error / switchChild / refreshChildren）
  - `apps/parent-portal/src/hooks/useChildSwitcher.ts`（封装 myChildren GraphQL query + 切换逻辑 + invalidate 子女维度查询）
  - `apps/parent-portal/src/components/ChildSwitcher.tsx`（variant: tab | dropdown，状态机：idle/switching/switched/error）
  - `apps/parent-portal/src/components/MultiChildTabBar.tsx`（≤3 子女用 Tab，>3 用下拉，移动端友好）
  - localStorage 持久化 `parent:currentChildId`（刷新恢复）
- **验收标准**：
  1. 切换子女后，`['parent','grades',currentChildId]` 等子女维度查询 invalidate 重拉
  2. 刷新页面后 currentChildId 从 localStorage 恢复
  3. 0 子女显示 EmptyChildState；1 子女不显示 TabBar；2-3 子女显示 Tab
  4. 切换子女竞态：快速连续切换，旧请求 abort，新数据正确显示

#### P4-4：Dashboard 页面 + ParentDashboard 组件

- **负责人**：ai15
- **依赖**：P4-3
- **交付物**：
  - `apps/parent-portal/src/app/(app)/parent/dashboard/page.tsx`
  - `apps/parent-portal/src/components/ParentDashboard.tsx`（组合 useChildren + useChildSummary，插槽：summary-cards / todo-reminders / recent-grades / attendance / custom）
  - `apps/parent-portal/src/components/ChildSummaryCard.tsx`（单子女概览：头像/姓名/年级/今日作业数/成绩趋势缩略图）
  - `apps/parent-portal/src/components/AttendanceCalendar.tsx`（出勤日历热力图）
- **验收标准**：
  1. 多子女并列卡片展示
  2. 权限校验：`PARENT_DASHBOARD_VIEW`，用 `<RequirePermission>`
  3. SSR 首屏 + CSR 交互（依 02 §14.4 渲染策略）

#### P4-5：子女成绩页面 + ChildGradeChart

- **负责人**：ai15
- **依赖**：P4-3
- **交付物**：
  - `apps/parent-portal/src/app/(app)/parent/grades/page.tsx`
  - `apps/parent-portal/src/components/ChildGradeChart.tsx`（recharts 折线 + 班级均分对比 + 多子女对比模式）
- **验收标准**：
  1. 权限校验：`GRADES_READ_CHILD`
  2. 切换子女后图表刷新
  3. 多子女对比模式可选

#### P4-6：子女作业页面

- **负责人**：ai15
- **依赖**：P4-3
- **交付物**：`apps/parent-portal/src/app/(app)/parent/homework/page.tsx`
- **验收标准**：
  1. 权限校验：`HOMEWORK_READ_CHILD`
  2. 复用 Shell 暴露的 DataTable 展示作业列表

#### P4-7：通知偏好页面 + PreferenceForm + Zod

- **负责人**：ai15
- **依赖**：P4-4
- **交付物**：
  - `apps/parent-portal/src/app/(app)/parent/preferences/page.tsx`
  - `apps/parent-portal/src/components/PreferenceForm.tsx`（矩阵式 UI：子女×事件×渠道，react-hook-form + zodResolver）
  - `apps/parent-portal/src/schemas/notificationPreferences.ts`（Zod schema，见 02 §14.4）
- **验收标准**：
  1. 权限校验：`PARENT_PREFERENCES_UPDATE`
  2. 不可用渠道 Toggle disabled + tooltip
  3. 保存成功后 invalidate `['parent','preferences']`
  4. 表单 dirty 状态追踪 + 离开页提示

#### P4-8：跨标签同步（BroadcastChannel）

- **负责人**：ai15
- **依赖**：P4-3
- **交付物**：
  - `apps/parent-portal/src/lib/crossTabSync.ts`（见 02 §16.2 完整实现）
  - 集成到 RootLayout（`useCrossTabSync()`）
- **验收标准**：
  1. Tab A 切换子女 → Tab B 同步更新
  2. LWW 冲突解决（ts 大的胜出）
  3. Safari 降级为 storage 事件

#### P4-9：Vitest 单测 + MSW 集成测试

- **负责人**：ai15
- **依赖**：P4-4 ~ P4-7
- **交付物**：
  - `apps/parent-portal/vitest.config.ts`
  - 单测：组件渲染/交互、Hook 逻辑、Zod schema 校验、纯函数 utils（覆盖率 ≥ 85%）
  - 集成测试：useChildSwitcher + Zustand slice + invalidate 流程（MSW mock，覆盖率 ≥ 75%）
- **验收标准**：
  1. `pnpm --filter parent-portal test` 全绿
  2. 覆盖率达标（单元 ≥ 85%，集成 ≥ 75%）

#### P4-10：Dockerfile 多阶段构建

- **负责人**：ai15
- **依赖**：P4-1
- **交付物**：`apps/parent-portal/Dockerfile`（builder + runtime，node:22-alpine）
- **验收标准**：
  1. `docker build` 成功
  2. HEALTHCHECK 指向 `/api/health`
  3. 镜像体积 < 300MB

### P5 阶段任务

#### P5-1：WebSocket 接入 + 事件处理

- **负责人**：ai15
- **依赖**：push-gateway :8081/ws 就绪（ai02）；parent-portal P4 完成
- **交付物**：
  - `apps/parent-portal/src/hooks/useWebSocket.ts`（连接 push-gateway ws，JWT 鉴权，自动重连）
  - 事件处理：`NotificationRequested` → toast + 未读数+1；`GradeRecorded` → toast + 成绩 invalidate；`SchoolAnnouncement` → toast + dashboard invalidate
- **验收标准**：
  1. WS 连接建立后收事件正常
  2. 断线自动重连（指数退避）

#### P5-2：通知中心页面 + NotificationFeed

- **负责人**：ai15
- **依赖**：P5-1
- **交付物**：
  - `apps/parent-portal/src/app/(app)/parent/notifications/page.tsx`
  - `apps/parent-portal/src/components/NotificationFeed.tsx`（按子女×类型×已读筛选，批量已读，跳转，置顶）
- **验收标准**：
  1. 权限校验：`NOTIFICATION_READ_OWN`
  2. WebSocket 推送 invalidate 通知列表

#### P5-3：推送降级（HTTP 轮询）

- **负责人**：ai15
- **依赖**：P5-1
- **交付物**：WS 重试 5 次失败后降级为 HTTP 轮询（60s 拉取通知列表）
- **验收标准**：降级后通知延迟 ≤ 60s，用户感知降级提示

### P6 阶段任务

#### P6-1：Web Vitals + OTel browser SDK

- **交付物**：`next/web-vitals` 上报 + OTel browser SDK（复用 Shell 暴露的 TracerProvider）
- **验收标准**：LCP/CLS/TTFB 指标上报到 Gateway

#### P6-2：A11y WCAG 2.2 AA 审计 + 修复

- **交付物**：axe-core 自动扫描 + 手动键盘导航测试，0 严重违规
- **验收标准**：所有页面 0 严重 A11y 违规

#### P6-3：性能优化 + bundle 分析

- **交付物**：bundle 分析报告 + 代码分割优化（首屏 JS ≤ 80KB gzipped）
- **验收标准**：Lighthouse 移动端 4G ≥ 90 分

#### P6-4：多语言扩展（en-US）

- **交付物**：`apps/parent-portal/src/i18n/messages/en-US/*.json`（镜像 zh-CN 结构）
- **验收标准**：en-US 完成度 100%

#### P6-5：PWA（Service Worker + manifest）

- **交付物**：`public/manifest.json` + Service Worker 缓存策略（见 02 §18.4）
- **验收标准**：可安装到主屏，离线可查看缓存的子女数据

#### P6-6：安全硬化（CSP + 敏感数据脱敏）

- **交付物**：CSP 头配置（复用 Shell）+ 截图脱敏 + 页面离开遮罩
- **验收标准**：CSP 无违规报告；敏感数据不泄漏

---

## §4 依赖与就绪信号

### 4.1 我依赖的上游就绪标志

| 上游                              | 就绪信号                                                                      | 提供方    | 状态       | 阻塞影响                      |
| --------------------------------- | ----------------------------------------------------------------------------- | --------- | ---------- | ----------------------------- |
| teacher-portal Shell              | MF exposes（AppShell + GraphQLProvider + hooks + UI 组件）+ shared singleton  | ai13      | ⏳ P2      | P4 无法启动                   |
| parent-bff GraphQL                | `POST /graphql` :3010 + currentUser/myChildren/childSummary/childGrades Query | ai05      | ⏳ P4      | 核心数据源                    |
| iam GetChildrenByParent           | gRPC 50052 + `iam_student_guardians` 表                                       | ai06      | ⏳ P3 补全 | P0 多子女阻塞（见 ISSUE-010） |
| core-edu                          | gRPC 50053 + GradeService/HomeworkService/AttendanceService                   | ai08      | ⏳ P3      | 成绩/作业数据                 |
| data-ana                          | gRPC 50055 + AnalyticsService                                                 | ai11      | ⏳ P4      | 学情分析数据                  |
| msg                               | gRPC 50056 + NotificationService                                              | ai10      | ⏳ P5      | 通知中心                      |
| push-gateway                      | :8081/ws WebSocket                                                            | ai02      | ⏳ P5      | 实时推送                      |
| shared-ts                         | ApiClient/Logger（coord 维护）                                                | coord     | ⏳         | 基础工具                      |
| contracts                         | Permissions 常量（coord 维护）                                                | coord     | ⏳         | 权限校验                      |
| ui-tokens / ui-components / hooks | 三层令牌 + shadcn + usePermission/useAuth（ai07/ai13 维护）                   | ai07/ai13 | ⏳ P2 收尾 | UI 基础                       |

### 4.2 我的就绪信号（供下游消费）

| 信号                                | 说明                                                            | 阶段       |
| ----------------------------------- | --------------------------------------------------------------- | ---------- |
| parent-portal :4002 dev server 启用 | MF Remote 可被 Shell 加载                                       | P4-1 完成  |
| MF Remote remoteEntry.js 可加载     | Shell 端 `remotes.parent` 可解析                                | P4-1 完成  |
| 核心 GraphQL 查询可执行             | currentUser / myChildren / childSummary 返回数据（mock 或真实） | P4-2 完成  |
| 多子女切换可用                      | ChildSwitcher + invalidate 流程通过                             | P4-3 完成  |
| Dashboard 可访问                    | 家长登录 → 看到 Dashboard（含子女卡片）                         | P4-4 完成  |
| 健康检查通过                        | `GET /api/health` + `GET /api/ready` 200                        | P4-1 完成  |
| 测试覆盖率达标                      | 单元 ≥ 85% + 集成 ≥ 75%                                         | P4-9 完成  |
| Docker 镜像可构建                   | `docker build` 成功                                             | P4-10 完成 |

### 4.3 全并行 Mock 策略

| 消费接口               | Mock 方式                                                                          | 切换真实时机                     |
| ---------------------- | ---------------------------------------------------------------------------------- | -------------------------------- |
| parent-bff GraphQL     | MSW 拦截 `POST /api/v1/parent/graphql`，按 operationName 返回 fixtures             | parent-bff GraphQL :3010 就绪 ✅ |
| iam login              | MSW 返回固定 JWT（parent 角色）                                                    | api-gateway + iam 就绪 ✅        |
| push-gateway WebSocket | mock-socket 模拟 WS 推送（每 30s 1 条通知）                                        | push-gateway :8081 就绪 ✅       |
| 子女数据一致性         | myChildren mock 返回 student-001 + student-002，与所有 child* 查询 student_id 一致 | iam GetChildrenByParent 就绪     |

> Mock 由 `NEXT_PUBLIC_API_MOCKING=enabled` 环境变量控制，上游就绪后设为 `disabled`。

---

## §5 风险与缓解

| 风险                                      | 影响                               | 缓解                                                     |
| ----------------------------------------- | ---------------------------------- | -------------------------------------------------------- |
| ISSUE-001/002 未仲裁（REST vs GraphQL）   | P4-2 GraphQL client 接入方向不确定 | 先按 GraphQL 预排期；仲裁若改 REST，P4-2 重写（预计 1d） |
| iam GetChildrenByParent 缺失（ISSUE-010） | 多子女场景无法落地                 | mock 固定 2 子女开发；coord 跟踪 ai06 P3 补全            |
| MF SSR 对齐复杂                           | Remote SSR 需 Shell 上下文         | 优先 CSR，仅 Dashboard 首屏 SSR；P4-1 PoC 验证           |
| parent-bff 契约未最终确认                 | GraphQL schema 可能变动            | P4 启动前与 ai05 对齐 schema；MSW mock 解耦              |
| TanStack Query 缓存膨胀                   | 多子女历史查询堆积                 | gcTime 5min + 切换子女清理非当前子女缓存                 |

---

## §6 进度跟踪（2026-07-13 更新）

> 当前分支：main（已合并 feat-review-parent-portal-docs-nRb7cN + feat/parent-portal-ai15）
> ARB-020 全部 10 项 ISSUE 已裁决（见 coord.md §22）
> ARB-020 §22.5 switchChild 双层实现已完成（useChildSwitcher + SWITCH_CHILD mutation）
> ARB-022 §24.4 双 /v1 前缀已修正（GraphQL + iam login + notifications + web-vitals 全部对齐方案 A）

### 6.1 P4 骨架与核心页面

| 任务                                              | 状态    | 说明                                                                                                               |
| ------------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------ |
| P4-1 MF Remote 骨架+next.config.js+健康检查       | ✅ 完成 | next.config.js 含 NextFederationPlugin，health/ready route 已就绪                                                  |
| P4-2 GraphQL client接入+MSW mock层                | ✅ 完成 | graphql-client.ts + operations.ts + handlers.ts + fixtures.ts 全部就绪；ARB-022 §24.4 双 /v1 端点已对齐            |
| P4-3 ChildSwitcher+useChildSwitcher+Zustand slice | ✅ 完成 | child-store.ts + useChildSwitcher.ts + ChildSwitcher.tsx + MultiChildTabBar.tsx                                    |
| P4-4 Dashboard页面+ParentDashboard组件            | ✅ 完成 | dashboard/page.tsx + ParentDashboard.tsx + ChildSummaryCard.tsx + AttendanceCalendar.tsx                           |
| P4-5 子女成绩页面+ChildGradeChart                 | ✅ 完成 | grades/page.tsx + ChildGradeChart.tsx（recharts 柱状图）                                                           |
| P4-6 子女作业页面                                 | ✅ 完成 | homework/page.tsx 含状态过滤器                                                                                     |
| P4-7 通知偏好页面+PreferenceForm+Zod              | ✅ 完成 | preferences/page.tsx + PreferenceForm.tsx + notification-preferences.ts                                            |
| P4-8 跨标签同步(BroadcastChannel)                 | ✅ 完成 | useCrossTabSync.ts + child-store.ts BroadcastChannel 集成                                                          |
| P4-9 Vitest单测+MSW集成测试                       | ✅ 完成 | 413 测试通过，覆盖率 99%+（statements 99.03% / branches 92.85% / functions 97.29% / lines 99.03%），全部 ≥85% 阈值 |
| P4-10 Dockerfile多阶段构建                        | ✅ 完成 | builder + runtime（node:20-alpine），HEALTHCHECK 指向 /api/health                                                  |

### 6.2 P5 推送与通知中心

| 任务                               | 状态    | 说明                                                                                 |
| ---------------------------------- | ------- | ------------------------------------------------------------------------------------ |
| P5-1 WebSocket接入+事件处理        | ✅ 完成 | useWebSocket.ts（指数退避重连+降级轮询）+ useRealtimeNotifications.ts（5类事件处理） |
| P5-2 通知中心页面+NotificationFeed | ✅ 完成 | notifications/page.tsx + NotificationFeed.tsx（筛选/批量已读/置顶）                  |
| P5-3 推送降级(HTTP轮询)            | ✅ 完成 | useWebSocket.ts 内实现（重试5次后降级60s轮询）                                       |

### 6.3 P6 硬化

| 任务                              | 状态    | 说明                                                                                                                                                              |
| --------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| P6-1 Web Vitals+OTel browser SDK  | ✅ 完成 | observability/env.ts + otel.ts + web-vitals.ts + WebVitalsInitializer；providers.tsx 挂载 OTel + WebVitals；optionalDependencies 含 @opentelemetry/* + web-vitals |
| P6-2 A11y WCAG 2.2 AA审计+修复    | ✅ 完成 | observability/a11y.ts 审计工具（axe-core + 对比度检查）；修复 ARIA 属性（role/aria-live/aria-label）；添加 sr-only CSS 类                                         |
| P6-3 性能优化+bundle分析          | ✅ 完成 | next.config.js 集成 @next/bundle-analyzer（ANALYZE=true 启用）；package.json 添加 analyze 脚本                                                                    |
| P6-4 多语言扩展(en-US)            | ✅ 完成 | i18n.ts 含 zh-CN + en-US 双语翻译表                                                                                                                               |
| P6-5 PWA(Service Worker+manifest) | ✅ 完成 | manifest.json + sw.js 已就绪，providers.tsx 生产环境注册                                                                                                          |
| P6-6 安全硬化(CSP+敏感数据脱敏)   | ✅ 完成 | middleware.ts CSP 已收紧（移除 unsafe-eval），安全头齐全                                                                                                          |

### 6.4 超出原 workline 的已实现内容

| 内容                                     | 说明                                                                  |
| ---------------------------------------- | --------------------------------------------------------------------- |
| 考勤页面 `/parent/attendance`            | useChildAttendance.ts + AttendanceCalendar.tsx（月度日历热力图）      |
| 学情薄弱点页面 `/parent/weakness`        | useChildWeakness.ts + weakness/page.tsx（掌握度进度条+推荐建议）      |
| 学习趋势页面 `/parent/trend`             | useChildTrend.ts + trend/page.tsx（recharts 折线图+周期选择器）       |
| 考试列表页面 `/parent/exams`             | useChildExams.ts + exams/page.tsx（按状态分组，含状态徽标）           |
| 考试结果页面 `/parent/exams/[id]/result` | useChildExamResult.ts + result/page.tsx（分数摘要+答题回顾+逐题分析） |
| 班级列表页面 `/parent/classes`           | useChildClasses.ts + classes/page.tsx（班级卡片网格）                 |
| 学习路径页面 `/parent/learning-path`     | useChildLearningPath.ts + learning-path/page.tsx（知识点进度+推荐）   |
| 设置页面 `/parent/settings`              | settings/page.tsx（家长信息只读展示）                                 |
| useNotificationPreferences.ts            | 通知偏好查询 hook                                                     |
| useRealtimeNotifications.ts              | 实时通知事件处理（5类 WebSocket 事件）                                |
| ErrorBoundary 组件                       | React 渲染异常兜底，已集成到 providers.tsx                            |
| Service Worker（PWA）                    | sw.js + manifest.json，providers.tsx 生产环境注册                     |
| middleware.ts                            | CSP 安全头 + 认证守卫                                                 |
| i18n.ts                                  | 双语翻译表（zh-CN + en-US）                                           |
| observability 模块                       | env.ts + otel.ts + web-vitals.ts + a11y.ts（可观测性 + A11y 审计）    |
| bundle-analyzer                          | next.config.js 集成 @next/bundle-analyzer（ANALYZE=true 启用）        |

### 6.5 参考项目差距分析（对照 student-portal + teacher-portal）

| 参考项目功能                     | parent-portal 状态 | 说明                                               |
| -------------------------------- | ------------------ | -------------------------------------------------- |
| 仪表盘 `/dashboard`              | ✅ 已实现          | `/parent/dashboard`                                |
| 成绩 `/my-grades`                | ✅ 已实现          | `/parent/grades`（含柱状图+明细表）                |
| 考勤 `/my-attendance`            | ✅ 已实现          | `/parent/attendance`（月度日历）                   |
| 作业 `/my-homework`              | ✅ 已实现          | `/parent/homework`（状态筛选）                     |
| 学情诊断 `/dashboard/weakness`   | ✅ 已实现          | `/parent/weakness`（掌握度+推荐）                  |
| 学习趋势 `/dashboard/trend`      | ✅ 已补齐          | `/parent/trend`（折线图+周期选择）                 |
| 考试列表 `/my-exams`             | ✅ 已补齐          | `/parent/exams`（按状态分组）                      |
| 考试结果 `/my-exams/[id]/result` | ✅ 已补齐          | `/parent/exams/[id]/result`（逐题回顾）            |
| 班级列表 `/my-classes`           | ✅ 已补齐          | `/parent/classes`                                  |
| 学习路径 `/learning-path`        | ✅ 已补齐          | `/parent/learning-path`                            |
| 通知中心 `/notifications`        | ✅ 已实现          | `/parent/notifications`（含 WebSocket 实时）       |
| 通知偏好                         | ✅ 已实现          | `/parent/preferences`（矩阵式表单+Zod）            |
| 设置 `/settings`                 | ✅ 已补齐          | `/parent/settings`（家长信息只读）                 |
| ErrorBoundary                    | ✅ 已补齐          | providers.tsx 集成                                 |
| Service Worker（PWA）            | ✅ 已补齐          | sw.js + manifest.json                              |
| OTel browser SDK                 | ✅ 已补齐          | observability/otel.ts + providers.tsx 挂载         |
| Web Vitals                       | ✅ 已补齐          | observability/web-vitals.ts + WebVitalsInitializer |
| A11y 审计工具                    | ✅ 已补齐          | observability/a11y.ts（axe-core + 对比度检查）     |
| Bundle 分析                      | ✅ 已补齐          | @next/bundle-analyzer + analyze 脚本               |
| CSP 安全头                       | ✅ 已实现          | middleware.ts（已收紧 unsafe-eval）                |
| 多语言 (en-US)                   | ✅ 已实现          | i18n.ts 双语翻译表                                 |

> **不适用功能**（学生专属，家长端不实现）：
>
> - 考试作答 `/my-exams/[id]/take`（家长不参加考试）
> - 作业提交 `/my-homework/[id]/submit`（家长不提交作业）
> - AI 辅学 `/ai-tutor`（学生专属功能）
> - 教材列表 `/textbooks`（家长端暂不需要）
> - 防作弊/多标签检测（考试作答专属）

### 6.6 剩余工作

1. ~~创建 `/parent/trend` 学习趋势页面~~ ✅
2. ~~创建 `ErrorBoundary` 组件并集成~~ ✅
3. ~~创建 Service Worker 实现 PWA 离线缓存~~ ✅
4. ~~收紧 CSP（移除 unsafe-eval）~~ ✅
5. ~~P6-1: OTel browser SDK + Web Vitals 挂载~~ ✅
6. ~~P6-2: A11y 审计工具 + ARIA 修复~~ ✅
7. ~~P6-3: Bundle 分析配置~~ ✅
8. ~~补齐考试列表/考试结果/班级/学习路径/设置页面~~ ✅
9. ~~ARB-020 §22.5 switchChild 双层实现~~ ✅
10. ~~P4-9: 测试覆盖率验证（单元 ≥ 85%，集成 ≥ 75%）~~ ✅（413 测试通过，覆盖率 99%+）
11. ~~ARB-022 §24.4 双 /v1 前缀修正（GraphQL + iam login + notifications + web-vitals）~~ ✅

> **parent-portal 全部 P4-P6 任务已完成**。无剩余工作项。

---

## §7 参考项目（CICD 单体）差距分析与实现安排

> 参考项目：`e:\Desktop\CICD\`（单体 Next_Edu 教育平台），parent 页面位于 `src/app/(dashboard)/parent/`
> 分析日期：2026-07-13
> 原则：保留当前"单子女切换"范式（已稳定 13 页），按参考项目功能点补齐缺失页面，不迁移到"多子女同屏对比"范式

### 7.1 参考项目 parent 页面全览（11 个主路由，14 个页面）

| 路由 | 分类 | 核心功能 | 当前状态 |
| ---- | ---- | -------- | -------- |
| `/parent/dashboard` | 仪表盘 | 多子女卡片网格 + AI 摘要 + 关注横幅 + 趋势图标 | ⚠️ 部分实现 |
| `/parent/attendance` | 考勤 | 聚合出勤率 + 预警横幅 + 月历导航 + a11y | ⚠️ 部分实现 |
| `/parent/children/[studentId]` | 综合详情 | 多 Tab 聚合（overview/homework/grades/exams/schedule） | ❌ 缺失（设计差异，可选） |
| `/parent/course-plans` + `[id]` | 课程 | 课程计划列表 + 详情只读 | ❌ 缺失 |
| `/parent/diagnostic` | 诊断 | 已发布诊断报告 + 掌握度摘要 | ❌ 缺失 |
| `/parent/elective` | 选修 | 选修课选课记录 | ❌ 缺失 |
| `/parent/error-book` | 错题 | 5 项统计 + Top 错题 + 薄弱知识点 | ⚠️ 部分实现（weakness 仅有知识点） |
| `/parent/grades` + `report-card` | 成绩 | 趋势 + 班级均对比 + 成长档案 + 导出 + 报告卡 | ⚠️ 部分实现 |
| `/parent/leave` | 请假 | 在线请假表单 + 历史列表 | ❌ 缺失 |
| `/parent/lesson-plans` + `[planId]/view` | 备课 | 已发布备课列表 + 只读详情 | ❌ 缺失 |
| `/parent/practice` | 练习 | 4 项统计 + 练习历史 | ❌ 缺失 |

### 7.2 实现安排（按优先级）

#### P0 高优先级（核心家长功能）

| 任务 | 路由 | 说明 |
| ---- | ---- | ---- |
| P0-1 | `/parent/leave` | 请假表单（选子女/时间/原因）+ 历史列表 |
| P0-2 | `/parent/grades/report-card` | 可打印报告卡 + 学年/学期筛选 |
| P0-3 | `/parent/children/[studentId]` | 子女详情聚合页（Tab: overview/homework/grades/exams/schedule） |

#### P1 中优先级（学情闭环）

| 任务 | 路由 | 说明 |
| ---- | ---- | ---- |
| P1-1 | `/parent/error-book` | 错题统计网格（5 项）+ Top 错题列表 |
| P1-2 | `/parent/diagnostic` | 已发布诊断报告 + 掌握度摘要 |
| P1-3 | `/parent/practice` | 练习统计（4 项）+ 历史列表 |

#### P2 低优先级（教学侧只读视图）

| 任务 | 路由 | 说明 |
| ---- | ---- | ---- |
| P2-1 | `/parent/course-plans` + `[id]` | 课程计划列表 + 详情 |
| P2-2 | `/parent/lesson-plans` + `[planId]/view` | 备课列表 + 只读详情 |
| P2-3 | `/parent/elective` | 选修课选课记录 |

#### P3 现有页面增强

| 任务 | 路由 | 增强内容 |
| ---- | ---- | -------- |
| P3-1 | `/parent/dashboard` | 多子女卡片网格 + 关注横幅 + 趋势图标 + 逾期高亮 |
| P3-2 | `/parent/attendance` | 月份导航 + 异常预警横幅 + 聚合出勤率卡 |
| P3-3 | `/parent/grades` | 班级均对比线 + 导出按钮 + 成长档案图表 |

### 7.3 实现进度

| 任务 | 状态 | 说明 |
| ---- | ---- | ---- |
| P0-1 `/parent/leave` | ✅ 完成 | LeaveRequestForm + LeaveRequestList + Zod 校验 + 历史筛选 |
| P0-2 `/parent/grades/report-card` | ✅ 完成 | ReportCardView + 学年/学期筛选 + 打印按钮 |
| P0-3 `/parent/children/[studentId]` | ✅ 完成 | ChildDetailPanel + 5 Tab(overview/homework/grades/exams/schedule) |
| P1-1 `/parent/error-book` | ✅ 完成 | ErrorBookStatsCard(5 项统计) + TopWrongQuestionList + 薄弱知识点 |
| P1-2 `/parent/diagnostic` | ✅ 完成 | MasterySummaryCard + DiagnosticReportList(仅 published) |
| P1-3 `/parent/practice` | ✅ 完成 | PracticeStatsCard(4 项统计) + PracticeSessionList(历史) |
| P2-1 `/parent/course-plans` | ✅ 完成 | CoursePlanList + CoursePlanDetail + 章节列表 |
| P2-2 `/parent/lesson-plans` | ✅ 完成 | LessonPlanList(学科筛选) + LessonPlanReadonlyView(只读) |
| P2-3 `/parent/elective` | ✅ 完成 | ElectiveSelectionList + 分类色点 + 状态徽标 |
| P3-1 dashboard 增强 | ✅ 完成 | ParentAttentionBanner + 多子女卡片网格 + 趋势图标 + 逾期高亮 |
| P3-2 attendance 增强 | ✅ 完成 | AttendanceRateCard + AttendanceWarningBanner + 月份导航 |
| P3-3 grades 增强 | ✅ 完成 | GrowthArchiveChart + ExportGradesButton + 班级均对比线 |

### 7.4 实现统计

- **新增页面**: 9 个(leave / grades/report-card / children/[studentId] / error-book / diagnostic / practice / course-plans + [id] / lesson-plans + [planId]/view / elective)
- **新增组件**: 20+ 个(LeaveRequestForm / LeaveRequestList / ReportCardView / ChildDetailPanel / ErrorBookStatsCard / TopWrongQuestionList / MasterySummaryCard / DiagnosticReportList / PracticeStatsCard / PracticeSessionList / CoursePlanList / CoursePlanDetail / LessonPlanList / LessonPlanReadonlyView / ElectiveSelectionList / ParentAttentionBanner / AttendanceWarningBanner / AttendanceRateCard / GrowthArchiveChart / ExportGradesButton)
- **新增 hooks**: 15+ 个(useChildLeaveRequests / useCreateLeaveRequest / useAcademicYears / useReportCard / useChildDetail / useChildErrorBook / useChildDiagnostic / useChildPractice / useChildCoursePlans / useChildCoursePlanDetail / useChildLessonPlans / useChildLessonPlanDetail / useChildElective / useChildGrowthArchive / useExportChildGrades)
- **新增 GraphQL operations**: 19 个(17 query + 2 mutation)
- **新增 MSW handlers**: 19 个
- **新增类型**: 20+ 个(LeaveRequest / ReportCard / ErrorBookStats / TopWrongQuestion / DiagnosticReport / PracticeStats / CoursePlan / LessonPlan / ElectiveSelection / ChildDetail / ScheduleItem 等)
- **测试总数**: 763 测试通过(从 413 增至 763,+350 测试)
- **质量校验**: typecheck 0 错误 / lint 0 错误 / test 71 文件 763 测试全部通过

### 7.5 参考项目功能覆盖完成度

| 参考项目页面 | 对应实现 | 覆盖度 |
| ---- | ---- | ---- |
| `/parent/dashboard` | `/parent/dashboard`(增强) | ✅ 100% |
| `/parent/attendance` | `/parent/attendance`(增强) | ✅ 100% |
| `/parent/children/[studentId]` | `/parent/children/[studentId]` | ✅ 100% |
| `/parent/course-plans` + `[id]` | `/parent/course-plans` + `[id]` | ✅ 100% |
| `/parent/diagnostic` | `/parent/diagnostic` | ✅ 100% |
| `/parent/elective` | `/parent/elective` | ✅ 100% |
| `/parent/error-book` | `/parent/error-book` | ✅ 100% |
| `/parent/grades` + `report-card` | `/parent/grades`(增强) + `report-card` | ✅ 100% |
| `/parent/leave` | `/parent/leave` | ✅ 100% |
| `/parent/lesson-plans` + `[planId]/view` | `/parent/lesson-plans` + `[planId]/view` | ✅ 100% |
| `/parent/practice` | `/parent/practice` | ✅ 100% |

> **参考项目所有家长端功能已全部覆盖**。保留当前"单子女切换"范式,未迁移到"多子女同屏对比"范式(仪表盘除外,已支持多子女卡片网格)。

---

## §8 质量门禁

每个任务完成前必须通过：

- `pnpm --filter parent-portal lint` 零错误
- `pnpm --filter parent-portal typecheck` 零错误
- `pnpm --filter parent-portal test` 全绿（P4-9 起强制）
- 设计令牌三层规则（无 `#hex` / 无硬编码字体 / 无任意值，ESLint 强制）
- A11y：jsx-a11y error 级零违规

> 提交前校验见 [project_rules §8](../../../../.trae/rules/project_rules.md)，commit 遵循 Conventional Commits：`feat(parent-portal): ...`
