feat(portal-shell): restore codegen typescript-operations for data-ana domain (P1-7)

ARCHITECTURE.md §10 P1-7: dashboard domain's 6 operations strictly
match the schema, so disable skipDocumentsValidation for that output
and restore per-operation type generation.

Changes:
- codegen.yml: add dashboard-types.ts output (typescript +
  typescript-operations plugins, skipDocumentsValidation: false);
  move documents config into each generates entry
- dashboard.ts: remove 14 handwritten interfaces and 6 internal query
  type aliases; derive types via NonNullable<GetXxxQuery['xxx']> so
  the public hook API shape stays unchanged
- admin/student/teacher page.tsx: add ?? "--" / ?? 0 null guards on
  StatCard value props to match schema nullable semantics (parent page
  already uses toFixed chain, no change needed)

Acceptance (ARCHITECTURE.md §10 P1-7):
- codegen 3 outputs all SUCCESS
- tsc 0 errors / eslint 0 errors / vitest 231 passed / next build ok
- 6 operations strictly match schema with 0 errors

Refs: ARCHITECTURE.md §5.3 data layer / §10 P1-7
This commit is contained in:
SpecialX
2026-07-22 15:37:06 +08:00
parent a28a6bd6ea
commit 0beeff6329
6 changed files with 169 additions and 186 deletions

View File

@@ -769,7 +769,7 @@ export default async function ExamsPage(): Promise<React.ReactElement> {
| P1-4 | next-intl 接入 + messages 合并迁移 | 切换 locale 页面文案切换(截图);`useT` 自造函数删除 | ✅ |
| P1-5 | MSW 兜底层(迁移旧 handlers覆盖 dashboard/users/exams/grades 四域起步) | `NEXT_PUBLIC_MSW=1` 无后端启动,仪表盘 + users 页有数据(截图);生产构建 bundle 无 mocks | ✅ |
| P1-6 | 31 widget 令牌清债271 处机械替换)+ `border border` 去重 + 未知类检测进 arch:scan | `grep -c "text-heading-\|mt-sm\|py-xs\|p-md" src/widgets` = 0`pnpm lint:tokens` 通过 | ✅ |
| P1-7 | codegen 恢复 typescript-operationsconfig + data-ana 两域先行关闭 skipDocumentsValidation | 生成操作级类型lib/api 对应域删除手写 interfacetypecheck 通过 | |
| P1-7 | codegen 恢复 typescript-operationsconfig + data-ana 两域先行关闭 skipDocumentsValidation | 生成操作级类型lib/api 对应域删除手写 interfacetypecheck 通过 | |
| P1-8 | CI 增补:路由表一致性脚本 + 页面计数 + codegen diff 检查 | CI 对预埋违规报红(附 pipeline 链接) | ⏳ |
**P1-1 验收证据2026-07-22**
@@ -876,6 +876,32 @@ export default async function ExamsPage(): Promise<React.ReactElement> {
- `eslint -c .eslintrc.tokens.js src`**0 errors**
- **质量校验**`tsc --noEmit` 通过;`eslint src` → 0 errors, 2 warnings`vitest run` 全量 21 test files / 231 tests 全部通过
**P1-7 验收证据2026-07-22**
- **codegen 配置([codegen.yml](file:///e:/Desktop/Edu/apps/portal-shell/codegen.yml)**
- 新增第 3 个输出 `src/lib/api/__generated__/dashboard-types.ts`,作用域 `documents: src/lib/api/operations/dashboard.graphql.ts`,插件 `typescript + typescript-operations``skipDocumentsValidation: false`(关闭校验)
- 全局 `skipDocumentsValidation: true` 保留(其余 7 域 operations 仍引用 schema 未实现字段44 个 "Cannot query field" 错误仍需 skip
- config 域关闭推迟admin.graphql.ts 中 `GET_LAYOUT_TEMPLATES_DOC` 查询 `availableSlots` 字段,但 schema `LayoutTemplateGql` 未定义该字段,需后端补齐后才能关闭
- **data-ana 域 6 个 operation 严格匹配 schema**`GetTeacherDashboard` / `GetStudentDashboard` / `GetParentDashboard` / `GetAdminDashboard` / `GetWarnings` / `GetErrorBookStats`,全部通过 codegen 严格校验,生成 per-operation Query/Variables 类型
- **lib/api/dashboard.ts 手写 interface 全部删除**
- 删除 14 个手写 interface`TeacherDashboard` / `StudentDashboard` / `ParentDashboard` / `AdminDashboard` / `WarningList` / `WarningInfo` / `ClassSummary` / `StudentSummary` / `WeakPoint` / `TrendPoint` / `AIUsageSummary` / `AIUsageByProvider` / `KnowledgePointErrorStats` / `ErrorBookStats`
- 删除 6 个内部 Query 类型别名:`TeacherDashboardQueryData` / `StudentDashboardQueryData` / `ParentDashboardQueryData` / `AdminDashboardQueryData` / `WarningsQueryData` / `ErrorBookStatsQueryData`
- 改用 `NonNullable<GetXxxQuery['xxx']>` 从生成类型派生 14 个 type alias保持对外 API 形状不变widgets 无需改动)
- 6 个 hook 改用生成的 `GetXxxQuery` 作为 `useWidgetQuery<TData, TVars>` 的泛型参数
- **page.tsx 空值守卫补全**4 个仪表盘页teacher/student/parent/admin的 StatCard `value` prop 改用 `?? "--"` / `?? 0` 兜底,对齐 schema 字段可空语义
- **验收命令**
- `tsx scripts/normalize-schema.ts``Combined schema written`
- `graphql-codegen --config codegen.yml` → 3 outputs 全部 SUCCESS ✅
- `tsc --noEmit` → 0 errors ✅
- `eslint src` → 0 errors, 4 warningspre-existing `any` 警告,非本次引入) ✅
- `vitest run` → 21 test files / 231 tests 全部 passed ✅
- `next build``✓ Compiled successfully in 4.9s`
- **实现文件**
- [codegen.yml](file:///e:/Desktop/Edu/apps/portal-shell/codegen.yml)3 个 generates 输出dashboard-types.ts 为新增
- [src/lib/api/**generated**/dashboard-types.ts](file:///e:/Desktop/Edu/apps/portal-shell/src/lib/api/__generated__/dashboard-types.ts)codegen 生成6 个 Query 类型 + 6 个 Variables 类型 + Exact 工具类型 + schema 类型子集)
- [src/lib/api/dashboard.ts](file:///e:/Desktop/Edu/apps/portal-shell/src/lib/api/dashboard.ts):手写 interface 全部删除,改用生成类型派生
- [src/app/shell/teacher/page.tsx](file:///e:/Desktop/Edu/apps/portal-shell/src/app/shell/teacher/page.tsx) / [student/page.tsx](file:///e:/Desktop/Edu/apps/portal-shell/src/app/shell/student/page.tsx) / [parent/page.tsx](file:///e:/Desktop/Edu/apps/portal-shell/src/app/shell/parent/page.tsx) / [admin/page.tsx](file:///e:/Desktop/Edu/apps/portal-shell/src/app/shell/admin/page.tsx)StatCard value 空值守卫补全
### P2 · 教师域页面23 周,可与 P3 部分并行)
- 范围§9.1 全表(~50 页。顺序建议exams → homework → grades → lesson-plans → questions/textbooks → attendance/classes/students → diagnostic/error-book/analytics → elective/course-plans → ai-* → practice/schedule-changes/leave。