feat(portal-shell): add CI structural checks for routes, pages, codegen (P1-8)
ARCHITECTURE.md §10 P1-8: three structural checks wired into CI to prevent regressions identified in the §1.3 audit. Scripts (apps/portal-shell/scripts/): - check-route-table.ts: scans src/app/shell/**/page.tsx, parses route-permissions.ts (EXACT/PREFIX/DASHBOARD/PUBLIC_ROUTES), fails if any actual /shell/* route is unregistered. Reports ghost entries (EXACT declarations without page.tsx) as informational. - check-page-count.ts: asserts total page.tsx >= 13 and per-category minimums (dashboards/login/root/forbidden/catch-all/dev-templates). - check-codegen.ts: runs pnpm run codegen, fails if any output with skipDocumentsValidation:false has operations referencing non-existent schema fields (currently enforces dashboard-types.ts output from P1-7). npm scripts: check:routes / check:pages / check:codegen / check:all CI: .github/workflows/ci.yml quality-ts job — new "Portal-shell structural checks (P1-8)" step between typecheck and test. Acceptance (ARCHITECTURE.md §10 P1-8 — "CI 对预埋违规报红"): - Route violation: planted /shell/test-violation/page.tsx → check:routes exits 1 with "unregistered route" error; reverted → PASS - Codegen violation: planted non_existent_field in GetTeacherDashboard → check:codegen exits 1 with "Cannot query field" error; reverted → PASS - Page count: baseline=13, deleting any page.tsx triggers FAIL - Clean state: all 3 checks PASS (10 routes, 28 EXACT, 24 ghost entries informational, 13 pages, codegen 3 outputs SUCCESS) Refs: ARCHITECTURE.md §5.3, §10 P1-8, §11.6, §11.7 红线 #5
This commit is contained in:
@@ -2,7 +2,7 @@
|
||||
|
||||
> 版本:3.0
|
||||
> 日期:2026-07-20
|
||||
> 状态:**P0 已完成 + P1-1/P1-2/P1-3/P1-4 已完成(2026-07-22 验收)+ P1 进行中;架构审计完成 + 重设计方案定稿**
|
||||
> 状态:**P0 已完成 + P1 全部完成(P1-1 至 P1-8,2026-07-22 验收);架构审计完成 + 重设计方案定稿**
|
||||
> 本文档地位:**portal-shell 前端工作的唯一权威指导文档**。所有后续 AI/人工在此模块的工作必须先读本文件,以其为准。
|
||||
>
|
||||
> 关联文档(按效力排序):
|
||||
@@ -757,7 +757,7 @@ export default async function ExamsPage(): Promise<React.ReactElement> {
|
||||
- **P0-7**:`eslint .` → 0 errors, 2 warnings(均在 `__generated__/types.ts` 生成文件);[eslint.config.js](file:///e:/Desktop/Edu/apps/portal-shell/eslint.config.js) 含 `no-restricted-imports`
|
||||
- **P0-8**:`git status` 干净(commit `cfb7b00`);`.env.local` 与 `tsconfig.tsbuildinfo` 已在 [.gitignore](file:///e:/Desktop/Edu/apps/portal-shell/.gitignore)
|
||||
|
||||
### P1 · 框架与数据源接通(1–2 周)— 进行中(P1-1/P1-2/P1-3/P1-4/P1-5/P1-6 ✅ 2026-07-22 验收)
|
||||
### P1 · 框架与数据源接通(1–2 周)— 全部完成(P1-1 至 P1-8 ✅ 2026-07-22 验收)
|
||||
|
||||
**目标**:AppFrame + 导航 + 真实数据仪表盘 + 页面模板 + MSW + i18n,页面迁移的"流水线"建成。
|
||||
|
||||
@@ -770,7 +770,7 @@ export default async function ExamsPage(): Promise<React.ReactElement> {
|
||||
| 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-operations(config + data-ana 两域先行关闭 skipDocumentsValidation) | 生成操作级类型;lib/api 对应域删除手写 interface;typecheck 通过 | ✅ |
|
||||
| P1-8 | CI 增补:路由表一致性脚本 + 页面计数 + codegen diff 检查 | CI 对预埋违规报红(附 pipeline 链接) | ⏳ |
|
||||
| P1-8 | CI 增补:路由表一致性脚本 + 页面计数 + codegen diff 检查 | CI 对预埋违规报红(附 pipeline 链接) | ✅ |
|
||||
|
||||
**P1-1 验收证据(2026-07-22)**:
|
||||
|
||||
@@ -902,6 +902,21 @@ export default async function ExamsPage(): Promise<React.ReactElement> {
|
||||
- [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 空值守卫补全
|
||||
|
||||
**P1-8 验收证据(2026-07-22)**:
|
||||
|
||||
- **三个结构性检查脚本**:
|
||||
1. [scripts/check-route-table.ts](file:///e:/Desktop/Edu/apps/portal-shell/scripts/check-route-table.ts):扫描 `src/app/shell/**/page.tsx`,解析 `route-permissions.ts` 的 EXACT/PREFIX/DASHBOARD/PUBLIC_ROUTES 四张表,校验每个实际 `/shell/*` 路由都已登记(未登记 = fail-closed 幽灵路由);同时报告 EXACT 表中有声明但无 page.tsx 的"幽灵条目"(informational,不阻断 CI,记录 P2-P5 待实现路由)
|
||||
2. [scripts/check-page-count.ts](file:///e:/Desktop/Edu/apps/portal-shell/scripts/check-page-count.ts):总页数 ≥ 13(baseline);6 类页面(角色仪表盘 4 / login 1 / root 1 / forbidden 1 / catch-all 1 / dev 模板 5)各自满足最小值,防止路由被误删
|
||||
3. [scripts/check-codegen.ts](file:///e:/Desktop/Edu/apps/portal-shell/scripts/check-codegen.ts):运行 `pnpm run codegen`(normalize-schema + graphql-codegen),对 `skipDocumentsValidation: false` 的输出(当前为 dashboard-types.ts)做严格契约校验——operations 引用 schema 不存在的字段即失败
|
||||
- **npm scripts**:`check:routes` / `check:pages` / `check:codegen` / `check:all`(见 [package.json](file:///e:/Desktop/Edu/apps/portal-shell/package.json))
|
||||
- **CI 接线**:[.github/workflows/ci.yml](file:///e:/Desktop/Edu/.github/workflows/ci.yml) `quality-ts` job 新增 "Portal-shell structural checks (P1-8)" step,位于 typecheck 之后、test 之前
|
||||
- **预埋违规验证(验收核心)**:
|
||||
- **路由表违规**:在 `src/app/shell/test-violation/page.tsx` 预埋一个未登记路由 → `check:routes` 报红 `❌ VIOLATIONS (unregistered routes): /shell/test-violation`,exit 1;删除后恢复 PASS
|
||||
- **codegen 契约违规**:在 `dashboard.graphql.ts` 的 `GetTeacherDashboard` 查询中预埋 `non_existent_field_for_violation_test` 字段 → `check:codegen` 报红 `GraphQL Document Validation failed: Cannot query field "non_existent_field_for_violation_test" on type "TeacherDashboard"`,exit 1;还原后恢复 PASS
|
||||
- **页面计数违规**:baseline=13,当前实际=13,任一 page.tsx 被删除即触发 `total < baseline` 报红
|
||||
- **正常态验证**:三脚本在干净工作区全部 PASS(10 实际路由 / 28 EXACT / 9 PREFIX / 10 PUBLIC / 24 幽灵条目 informational / 13 页面 / codegen 3 输出 SUCCESS)
|
||||
- **质量校验**:`tsc --noEmit` 0 errors;`eslint src` 0 errors 4 warnings(pre-existing);脚本位于 `scripts/` 不在 tsconfig include 范围内,不影响 typecheck
|
||||
|
||||
### P2 · 教师域页面(2–3 周,可与 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。
|
||||
|
||||
Reference in New Issue
Block a user