Files
Edu/apps/parent-portal/docs/nextstep.md
SpecialX 96a936e154 feat(parent-portal): docker 构建修复 + 禁用 mock + 记录下游待办
Dockerfile 改用 standalone 模式

next.config.js 添加 output standalone

修复 cssnano-simple 构建失败:globals.css 注释含 */ 被误解析

tailwind.config.js 覆盖 boxShadow 为 rgba 格式 + 禁用 ringWidth

组件修复:替换 / 语法为 inline style 或自定义类

otel.ts 添加 webpackIgnore 跳过 optionalDependencies 静态分析

.env.example 默认禁用 mock

新增 .dockerignore 和 docs/nextstep.md

删除 postcss.config.js

验证:Docker 镜像构建成功,容器 healthy,typecheck + lint 零错误
2026-07-13 17:21:39 +08:00

211 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# parent-portal 下游待办事项Next Steps
> 版本v1
> 日期2026-07-13
> 用途:记录 parent-portal 切换至真实 API 集成所需的下游模块工作
> 背景parent-portal 已完成 Docker Desktop 验证容器健康、25 路由生成、/login 200、/api/health 200现需下游服务就绪才能完成端到端真实 API 联调
---
## 1. 当前状态摘要
| 项目 | 状态 | 说明 |
| -------------------------- | ----------------- | ---------------------------------------------------------------------- |
| parent-portal Docker 镜像 | ✅ 已就绪 | `edu-parent-portal:test`standalone 模式25 路由 |
| parent-portal 容器健康检查 | ✅ 通过 | `/api/health` 200`/login` 200`/parent/dashboard` 307 auth redirect |
| Mock 数据 | ✅ 已禁用 | `NEXT_PUBLIC_API_MOCKING=disabled` |
| GraphQL 端点配置 | ✅ 已配置 | `NEXT_PUBLIC_GRAPHQL_ENDPOINT=/api/v1/parent/v1/graphql` |
| parent-bff 服务 | ❌ 未就绪 | 端点路径错配 + 27 query / 5 mutation 缺失 |
| api-gateway 路由 | ⚠️ 已配置但未验证 | `/api/v1/parent/*` → parent-bff:3010但 parent-bff 未运行 |
| iam GetChildrenByParent | ✅ 已就绪 | gRPC + HTTP 均已实现 |
| push-gateway /ws | ✅ 已就绪 | 完整 WebSocket 实现 |
---
## 2. P0 阻塞项parent-bff 端点路径错配
### 问题描述
前端调用 GraphQL 端点:`/api/v1/parent/v1/graphql`ARB-022 §24.4 ISSUE-003 方案 A 双 /v1 前缀)
api-gateway 代理路径转换:
- 入站:`/api/v1/parent/v1/graphql`
- 剥离 `/api` 后转发:`/v1/parent/v1/graphql` → parent-bff:3010
但 parent-bff 当前 controller 仅注册 `/graphql`,导致 `/v1/parent/v1/graphql` 在 parent-bff 找不到匹配的 handler返回 404。
### 修复位置parent-bff 模块)
| 文件 | 当前 | 应改为 |
| ----------------------------------------------------- | ----------------------------- | -------------------------------------------------------------- |
| `services/parent-bff/src/entry/graphql.controller.ts` | `@Controller("graphql")` | `@Controller("v1/parent/v1/graphql")` 或使用 `setGlobalPrefix` |
| `services/parent-bff/src/graphql/yoga.ts` | `graphqlEndpoint: "/graphql"` | `graphqlEndpoint: "/v1/parent/v1/graphql"` |
| `services/parent-bff/src/graphql/graphql.module.ts` | `forRoutes("graphql")` | `forRoutes("v1/parent/v1/graphql")` |
### 验证步骤
1. 修改后构建 parent-bff 镜像
2. 启动 parent-bff 容器,验证 `http://parent-bff:3010/v1/parent/v1/graphql` 返回 200
3. 经 api-gateway 代理访问 `http://api-gateway:8080/api/v1/parent/v1/graphql` 返回 200
---
## 3. P0 阻塞项parent-bff 缺失 pnpm-lock.yaml
### 问题描述
`services/parent-bff/Dockerfile` 第 6 行 `RUN pnpm install --frozen-lockfile` 失败,因为 `services/parent-bff/` 目录下没有 `pnpm-lock.yaml` 文件。
### 修复方案
`services/parent-bff/` 目录执行 `pnpm install` 生成 lockfile并提交到仓库。
```bash
cd services/parent-bff
pnpm install
git add pnpm-lock.yaml
git commit -m "chore(parent-bff): add pnpm-lock.yaml for Docker build"
```
---
## 4. P0 阻塞项parent-bff GraphQL Schema 严重不对齐
### 问题描述
| 类别 | 前端定义 | 后端实现 | 差距 |
| -------- | -------- | -------- | --------------------------------------------------------------- |
| Query | 32 个 | 11 个 | 21 个缺失(含 6 个命名不一致 + 15 个完全缺失 + 3 个签名不一致) |
| Mutation | 6 个 | 3 个 | 3 个缺失(含 2 个命名不一致 + 1 个完全缺失 + 1 个签名不一致) |
### 4.1 命名不一致的 Query6 个)
| 前端 operation | 后端 operation | 修复方式 |
| --------------------------- | ------------------------- | ---------------------------------------------------------------- |
| `currentUser` | `me` | 二选一统一命名(建议后端改 `me``currentUser` |
| `myChildren` | `children` | 二选一统一命名(建议后端改 `children``myChildren` |
| `myNotifications` | `notifications` | 二选一统一命名(建议后端改 `notifications``myNotifications` |
| `myNotificationPreferences` | `notificationPreferences` | 二选一统一命名 |
| `childSummary` | `child` | 字段不同,需明确语义 |
| `childAnalytics` | (前端未使用) | 后端已有但前端未对接,保留 |
### 4.2 完全缺失的 Query15 个,后端需新增)
| 前端 operation | 涉及下游服务 |
| ------------------------ | ------------ |
| `childAttendance` | core-edu |
| `childWeakness` | data-ana |
| `childTrend` | data-ana |
| `childExamResult` | core-edu |
| `childClasses` | classes |
| `childLearningPath` | data-ana |
| `childLeaveRequests` | core-edu |
| `academicYears` | core-edu |
| `childReportCard` | core-edu |
| `childErrorBookStats` | data-ana |
| `childTopWrongQuestions` | data-ana |
| `childWeakKps` | data-ana |
| `childMasterySummary` | data-ana |
| `childDiagnosticReports` | data-ana |
| `childPracticeStats` | data-ana |
| `childPracticeSessions` | data-ana |
| `childCoursePlans` | core-edu |
| `childCoursePlanDetail` | content |
| `childLessonPlans` | core-edu |
| `childLessonPlanDetail` | content |
| `childElective` | content |
| `childDetail` | data-ana |
| `childGrowthArchive` | data-ana |
### 4.3 签名不一致的 Query3 个)
| 前端 operation | 不一致点 |
| --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `childGrades` | 前端 `(childId, subject, limit)` vs 后端 `(childId, page, pageSize, subject)`;返回字段不同(前端 `examName/examDate/studentScore/classMax/classMin/gradeLevel` vs 后端 `examId/examTitle/score/rank/gradedAt` |
| `childHomework` | 前端有 `status` 过滤参数,后端无;字段差异大(前端 `subject/className/assignedDate/score/maxScore/feedback` vs 后端 `title/classId/dueDate/status` |
| `childExams` | 字段差异大(前端 `name/subject/startsAt/expiresAt/durationSeconds/questionCount/totalScore` vs 后端 `title/examDate/publishedAt` |
### 4.4 缺失的 Mutation3 个)
| 前端 operation | 涉及下游服务 |
| -------------------- | ---------------------------------------------------------- |
| `markAsRead` | parent-bff重命名 `markNotificationRead``markAsRead` |
| `markAllAsRead` | parent-bff新增 |
| `switchChild` | parent-bff重命名 `selectChild``switchChild` |
| `createLeaveRequest` | core-edu新增 |
| `exportChildGrades` | core-edu新增 |
### 4.5 签名不一致的 Mutation1 个)
| 前端 operation | 不一致点 |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------- |
| `updateNotificationPreferences` | 前端 `(parentId, preferences: JSON, defaults: JSON)` vs 后端 `(input: UpdateNotificationPreferencesInput)` |
### 修复步骤
1. **契约先行**:更新 `packages/shared-ts/contracts/graphql/parent-bff.graphql`,扩充至前端 32 query + 6 mutation
2. **resolver 实现**:在 `services/parent-bff/src/graphql/resolvers/` 新增对应 resolver
3. **下游 gRPC client**:在 `services/parent-bff/src/clients/` 新增/对接 core-edu / data-ana / content / classes 的 gRPC client
4. **测试**parent-bff 单测 + parent-portal 端到端联调
---
## 5. P1 阻塞项api-gateway 镜像构建问题
### 问题描述
`services/api-gateway/Dockerfile` 使用 `golang:1.22-alpine``alpine:3.20` 基础镜像,但本地 Docker Desktop 未拉取这两个镜像,且 daocloud 镜像源返回 401。
### 修复方案
1. 提前在服务器执行:`docker pull golang:1.22-alpine && docker pull alpine:3.20`
2. 或在 Dockerfile 中改用本地已有的镜像源
---
## 6. 已就绪的下游服务(无需等待)
| 服务 | 状态 | 验证位置 |
| ----------------------- | ----------------------- | ----------------------------------------------------------------------------------------------- |
| iam.GetChildrenByParent | ✅ gRPC + HTTP 均已实现 | `services/iam/src/iam/iam.grpc.controller.ts:116``services/iam/src/iam/iam.controller.ts:116` |
| push-gateway /ws | ✅ 完整实现 | `services/push-gateway/internal/ws/handler.go` |
---
## 7. 验证 Checklist下游就绪后执行
- [ ] parent-bff 添加 pnpm-lock.yaml
- [ ] parent-bff GraphQL 端点路径改为 `/v1/parent/v1/graphql`
- [ ] parent-bff schema 扩充至 32 query + 6 mutation
- [ ] parent-bff 所有 resolver 实现完成
- [ ] api-gateway 镜像可构建
- [ ] 在 Docker Desktop 启动完整服务栈api-gateway + parent-bff + iam + core-edu + data-ana + content + classes + push-gateway
- [ ] parent-portal 端到端联调:登录 → /parent/dashboard → 各功能页面
- [ ] 验证 WebSocket 推送:通知功能
- [ ] 验证 25 个路由全部可访问(无 500 错误)
---
## 8. 关键文件路径
| 文件 | 用途 |
| --------------------------------------------------------- | ---------------------------------------------------- |
| `apps/parent-portal/Dockerfile` | parent-portal Docker 构建已修复standalone 模式) |
| `apps/parent-portal/next.config.js` | Next.js 配置(已添加 `output: "standalone"` |
| `apps/parent-portal/src/lib/graphql-client.ts` | GraphQL 客户端配置 |
| `apps/parent-portal/src/lib/graphql/operations.ts` | 前端所有 GraphQL operations 定义 |
| `apps/parent-portal/.env.example` | 环境变量模板(`NEXT_PUBLIC_API_MOCKING=disabled` |
| `services/parent-bff/Dockerfile` | parent-bff Docker 构建(待修复:缺 pnpm-lock.yaml |
| `services/parent-bff/src/entry/graphql.controller.ts` | GraphQL 端点路径(待修复) |
| `services/parent-bff/src/graphql/yoga.ts` | GraphQL Yoga 配置(待修复) |
| `services/parent-bff/src/graphql/graphql.module.ts` | GraphQL 模块路由(待修复) |
| `services/parent-bff/src/graphql/resolvers/index.ts` | resolver 实现(待扩充) |
| `packages/shared-ts/contracts/graphql/parent-bff.graphql` | GraphQL schema 契约(待扩充) |
| `services/api-gateway/main.go:86` | parent 代理注册 |
| `services/api-gateway/Dockerfile` | api-gateway Docker 构建(待修复:基础镜像缺失) |
---
**总结**parent-portal 前端已完全就绪Docker 镜像构建成功、容器健康、25 路由可用、mock 已禁用),等待下游 parent-bff 完成端点路径修复 + schema 扩充 + resolver 实现后,即可完成端到端真实 API 联调。