- 学生域 32 页全量迁移(含作答/自动保存/提交/诊断) - 补齐 4 个 MSW mock 缺口,修 diagnostic case 名 - 修 4 处 Tailwind 任意值;新增共享组件与路由
51 KiB
管理域(Admin)待完成功能分析
参考项目:
e:\desktop\CICD\src\app\(dashboard)\admin\(41 个 page.tsx) 当前项目:e:\Desktop\Edu\apps\portal-shell\src\app\shell\admin\(49 个 page.tsx) 规划依据:apps\portal-shell\ARCHITECTURE.md§9.4(管理域 24 页顶层入口,B5 批次) 核查日期:2026-08-04 核查方式:逐个读取 49 个 page.tsx + 44 个 features/admin/*-client.tsx + lib/api/admin.ts(973 行) + lib/api/admin-p5.ts(3371 行) + mocks/graphql-data.ts(9867 行),结合 ARCH §9.4 契约判断实现完整性
〇、方法论与对比基线
- CICD 单体(Next.js App Router + Server Actions + Drizzle)作为功能基线,反映"老版单体已实现"的管理员功能完整态。
- portal-shell 作为目标态,遵循 ARCH §9.4 的契约与批次规划(B5,24 页顶层入口)。
- CICD admin/layout.tsx 仅为
<>{children}</>passthrough,无独立侧边栏/权限逻辑(权限由各 page.tsx 调requirePermission完成)。 - ARCH §9.4 规划 24 页顶层入口 = 1 仪表盘 + 23 管理子页;portal-shell 在此基础上补充了详情/编辑/创建子页与 redirect 入口,实际落地 49 个 page.tsx。
- 判断口径(任务约束):
- ✅ 完整实现:page.tsx 引入
@/features/admin/*-client.tsx并渲染(client 组件承担业务逻辑,调用 lib/api hooks,处理三态);或 page.tsx 为有意的redirect()入口跳转。 - 🟡 占位空态:page.tsx 仅用 ListPageShell/FormPageShell/DetailPageShell 直接渲染空态,无 children 业务内容。
- ❌ 缺失:page.tsx 文件不存在。
- ✅ 完整实现:page.tsx 引入
- 核查覆盖维度:page.tsx 入口 + features/admin/*-client.tsx 业务组件 + lib/api hooks + mocks/graphql-data.ts 兜底数据,四层齐全方视为完整实现。
一、页面完成度总览
| 状态 | 数量 | 说明 |
|---|---|---|
| ✅ 完整实现(业务页) | 46 | page.tsx 引入对应 features/admin/*-client.tsx 并在 <Suspense> 中渲染;client 组件调用 lib/api hooks,处理 loading/error/empty 三态 |
| ✅ 完整实现(重定向) | 3 | page.tsx 为有意的 redirect() 入口跳转(classes / scheduling / school 三个模块根路径) |
| 🟡 占位空态 | 0 | 无 |
| ❌ 缺失 | 0 | 无 |
| 合计 | 49 | 管理员域 49/49 page.tsx 全部落地 |
✅ 完整实现(46 业务页 + 3 重定向页 = 49 页)
所有 49 个 page.tsx 均已存在且非占位。46 个业务页统一采用 Server Component 入口 + Suspense 边界 + Client Component 业务的架构;3 个重定向页为有意的入口跳转,避免空白入口。
业务页架构样例(以 /shell/admin/ai-settings/page.tsx 为例):
import { Suspense } from "react";
import { AiSettingsClient } from "@/features/admin/ai-settings/ai-settings-client";
import { ListPageSkeleton } from "@/shared/components/page-templates";
export default function AiSettingsPage(): React.ReactElement {
return (
<Suspense fallback={<ListPageSkeleton rows={5} />}>
<AiSettingsClient />
</Suspense>
);
}
重定向页架构样例(以 /shell/admin/school/page.tsx 为例):
import { redirect } from "next/navigation";
export default function SchoolAdminIndexPage(): never {
redirect("/shell/admin/school/schools");
}
二、已实现页面清单(按模块分组,49 页)
状态标识:✅ 完整业务实现 / ↪️ 重定向入口 / 🟡 占位 / ❌ 缺失 三态规范:所有 ✅ 业务页的 client 组件均处理 loading(Skeleton)/ error(局部降级)/ empty(EmptyState)三态(ARCH §11.3 DoD)
2.1 dashboard 模块(1 页)
| 页面路径 | 状态 | 实现要点 |
|---|---|---|
/shell/admin |
✅ | "use client" + useAdminDashboard() hook 接 data-ana adminDashboard 真实契约;4 StatCard(教师/学生/班级/全校平均分)+ 近期预警 + AI 用量;含 loading/error 兜底;引用 ARCH §7.1 / §10 P1-2 |
2.2 ai-settings 模块(1 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/ai-settings | ✅ | ai-settings-client.tsx | 522 | useAiProviders / useCreateAiProvider / useUpdateAiProvider / useDeleteAiProvider / useTestAiProvider / useAiUsageDashboard | ❌ schema 未就绪 → MSW 兜底 |
2.3 announcements 模块(3 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/announcements | ✅ | announcements-list-client.tsx | 469 | useAdminAnnouncements / useDeleteAnnouncement / useArchiveAnnouncement / usePinAnnouncement / usePublishAnnouncement | ❌ → MSW 兜底 |
| /shell/admin/announcements/[id] | ✅ | announcement-detail-client.tsx | 289 | useAdminAnnouncement | ❌ → MSW 兜底 |
| /shell/admin/announcements/[id]/edit | ✅ | announcement-edit-client.tsx | 266 | useAdminAnnouncement / useUpdateAnnouncement | ❌ → MSW 兜底 |
2.4 attendance 模块(1 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/attendance | ✅ | admin-attendance-client.tsx | 340 | useAdminAttendanceStats / useAdminAttendanceRecords / useAttendanceGradeCorrelation | ❌ → MSW 兜底 |
2.5 audit-logs 模块(4 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/audit-logs | ✅ | audit-logs-list-client.tsx | 461 | useAuditLogs / useAuditModuleOptions / useExportAuditLogs | ❌ → MSW 兜底 |
| /shell/admin/audit-logs/data-changes | ✅ | data-changes-client.tsx | 472 | useDataChangeLogs / useDataChangeTableOptions / useDataChangeStats / useExportDataChanges | ❌ → MSW 兜底 |
| /shell/admin/audit-logs/login-logs | ✅ | login-logs-client.tsx | 325 | useLoginLogs / useExportLoginLogs | ❌ → MSW 兜底 |
| /shell/admin/audit-logs/overview | ✅ | audit-overview-client.tsx | 386 | useAuditOverviewStats / useAuditTrend / useDataChangeActionStats | ❌ → MSW 兜底 |
2.6 classes 模块(1 页,重定向)
| 页面路径 | 状态 | 实现要点 |
|---|---|---|
| /shell/admin/classes | ↪️ | redirect("/shell/admin/school/classes"):班级管理归属于 school 限界上下文,避免空白入口重复实现 |
2.7 course-plans 模块(4 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/course-plans | ✅ | course-plans-list-client.tsx | 339 | useAdminCoursePlans | ❌ → MSW 兜底 |
| /shell/admin/course-plans/create | ✅ | course-plan-create-client.tsx | 415 | useAdminClasses / useCreateCoursePlanItem 系列 | ❌ → MSW 兜底 |
| /shell/admin/course-plans/[id] | ✅ | course-plan-detail-client.tsx | 644 | useAdminCoursePlan / useUpdateCoursePlanItem / useReorderCoursePlanItems / useBulkToggleCoursePlanItems | ❌ → MSW 兜底 |
| /shell/admin/course-plans/[id]/edit | ✅ | course-plan-edit-client.tsx | 562 | useAdminCoursePlan / useUpdateCoursePlanItem 系列 | ❌ → MSW 兜底 |
2.8 curriculum-map 模块(1 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/curriculum-map | ✅ | curriculum-map-client.tsx | 256 | useStandardsCoverageHeatmap / useGlobalLessonPlanStats | ❌ → MSW 兜底 |
2.9 elective 模块(4 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/elective | ✅ | elective-list-client.tsx | 545 | useAdminElectives / useGetElectiveOverviewStats / useDeleteElective | ❌ → MSW 兜底 |
| /shell/admin/elective/create | ✅ | elective-create-client.tsx | 381 | useAdminCreateElective | ❌ → MSW 兜底 |
| /shell/admin/elective/[id] | ✅ | elective-detail-client.tsx | 385 | useAdminElective | ❌ → MSW 兜底 |
| /shell/admin/elective/[id]/edit | ✅ | elective-edit-client.tsx | 464 | useAdminUpdateElective / useOpenElectiveSelection / useCloseElectiveSelection / useRunElectiveLottery | ❌ → MSW 兜底 |
2.10 error-book 模块(1 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/error-book | ✅ | error-book-client.tsx | 738 | useAdminErrorBookStats / useExportErrorBookCsv | ❌ → MSW 兜底 |
2.11 files 模块(1 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/files | ✅ | files-list-client.tsx | 377 | useFileAttachments / useFileStats / useUploadFile / useBatchDeleteFiles | ❌ → MSW 兜底 |
2.12 invitation-codes 模块(1 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/invitation-codes | ✅ | invitation-codes-list-client.tsx | 542 | useInvitationCodes / useCreateInvitationCode / useRevokeInvitationCode / useGenerateInvitationCodes / useDeleteInvitationCodes | ❌ → MSW 兜底 |
2.13 lesson-plans 模块(2 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/lesson-plans | ✅ | lesson-plans-list-client.tsx | 489 | useAdminLessonPlans | ❌ → MSW 兜底 |
| /shell/admin/lesson-plans/[planId]/view | ✅ | lesson-plan-view-client.tsx | 205 | useAdminLessonPlan / useSoftDeleteLessonPlan | ❌ → MSW 兜底 |
2.14 organization 模块(1 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/organization | ✅ | organization-tree-client.tsx | 245 | useOrganizationTree | ❌ → MSW 兜底 |
2.15 permissions 模块(1 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/permissions | ✅ | permissions-list-client.tsx | 216 | usePermissions / usePermissionRoleCounts | ❌ → MSW 兜底 |
2.16 plugins 模块(1 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/plugins | ✅ | plugins-client.tsx | 402 | usePluginRegistry / useUpdatePluginRegistry | ✅ schema 已就绪(config-service) |
2.17 questions 模块(1 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/questions | ✅ | questions-list-client.tsx | 537 | useAdminQuestions / useAdminQuestion | ❌ → MSW 兜底 |
2.18 roles 模块(2 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/roles | ✅ | roles-list-client.tsx | 411 | useRoles / useCreateRole / useDeleteRole / useToggleRoleEnabled | ❌ → MSW 兜底 |
| /shell/admin/roles/[id] | ✅ | role-detail-client.tsx | 165 | useRole / useUpdateRole / useDeleteRole / useRolePermissions / useUpdateRolePermissionActions | ❌ → MSW 兜底 |
2.19 scheduling 模块(4 页,含 1 重定向)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/scheduling | ↪️ | redirect("/shell/admin/scheduling/changes"):避免空白入口,默认进入变更审批页 | — | — | — |
| /shell/admin/scheduling/auto | ✅ | auto-schedule-client.tsx | 270 | useAutoSchedule | ❌ → MSW 兜底 |
| /shell/admin/scheduling/changes | ✅ | schedule-changes-client.tsx | 471 | useAdminScheduleChanges / useAdminScheduleEntries / useApproveScheduleChange / useRejectScheduleChange | ❌ → MSW 兜底 |
| /shell/admin/scheduling/rules | ✅ | scheduling-rules-client.tsx | 401 | useAdminSchedulingRules / useUpdateSchedulingRules | ❌ → MSW 兜底 |
2.20 school 模块(7 页,含 1 重定向)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/school | ↪️ | redirect("/shell/admin/school/schools"):避免空白入口,默认进入学校列表页 | — | — | — |
| /shell/admin/school/academic-year | ✅ | academic-year-client.tsx | 601 | useAcademicYears / useCreateAcademicYear / useUpdateAcademicYear / useDeleteAcademicYear | ❌ → MSW 兜底 |
| /shell/admin/school/classes | ✅ | admin-classes-client.tsx | 598 | useAdminClasses / useTeacherOptions / useStaffOptions / useCreateAdminClass / useUpdateAdminClass / useDeleteAdminClass | ❌ → MSW 兜底 |
| /shell/admin/school/departments | ✅ | departments-client.tsx | 444 | useDepartments / useCreateDepartment / useUpdateDepartment / useDeleteDepartment | ❌ → MSW 兜底 |
| /shell/admin/school/grades | ✅ | grades-client.tsx | 688 | useGrades / useGradeOverviewStats / useAdminCreateGrade / useUpdateGrade / useDeleteGrade | ❌ → MSW 兜底 |
| /shell/admin/school/grades/insights | ✅ | grade-insights-client.tsx | 495 | useGradeOverviewStats 系列 | ❌ → MSW 兜底 |
| /shell/admin/school/schools | ✅ | schools-client.tsx | 509 | useSchools / useCreateSchool / useAdminUpdateSchool / useDeleteSchool | ❌ → MSW 兜底 |
2.21 students 模块(1 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/students | ✅ | students-list-client.tsx | 387 | useAdminStudents | ❌ → MSW 兜底 |
2.22 system 模块(1 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/system | ✅ | system-settings-client.tsx | 566 | useSystemSettings / useUpdateSystemSettings | ❌ → MSW 兜底 |
2.23 teachers 模块(1 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/teachers | ✅ | teachers-list-client.tsx | 269 | useAdminTeachers | ❌ → MSW 兜底 |
2.24 users 模块(3 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/users | ✅ | users-list-client.tsx | 538 | useUsers / useUpdateUserStatus / useUpdateUserRole / useDeleteUser / useAssignUserRoles / useUpdateUser | ❌ → MSW 兜底 |
| /shell/admin/users/import | ✅ | users-import-client.tsx | 414 | useImportUsers | ❌ → MSW 兜底 |
| /shell/admin/users/[id] | ✅ | user-detail-client.tsx | 404 | useUser / useUpdateUser / useAssignUserRoles | ❌ → MSW 兜底 |
2.25 viewports 模块(1 页)
| 页面路径 | 状态 | client 组件 | 行数 | lib/api hooks | 契约状态 |
|---|---|---|---|---|---|
| /shell/admin/viewports | ✅ | viewports-client.tsx | 383 | useViewports / useUpdateViewport | ❌ → MSW 兜底 |
三、按 ARCH §9.4 模块汇总
| 模块 | ARCH §9.4 规划页数 | portal-shell 已实现 | 缺失 | 契约状态 |
|---|---|---|---|---|
| dashboard | 1 | 1 | 0 | ✅ adminDashboard |
| users | 1(+1 import +1 详情) | 3 | 0 | ❌ → MSW 兜底 |
| roles | 1(+1 详情) | 2 | 0 | ❌ → MSW 兜底 |
| permissions | 1 | 1 | 0 | ❌ → MSW 兜底 |
| audit-logs | 4 | 4 | 0 | ❌ → MSW 兜底 |
| invitation-codes | 1 | 1 | 0 | ❌ → MSW 兜底 |
| school | 6(+redirect) | 7(+grades/insights) | 0 | ❌ → MSW 兜底 |
| classes | 1(与 school/classes 同源) | 1(redirect) | 0 | — |
| students | 1 | 1 | 0 | ❌ → MSW 兜底 |
| teachers | 1 | 1 | 0 | ❌ → MSW 兜底 |
| organization | 1 | 1 | 0 | ❌ → MSW 兜底 |
| announcements | 1(+2 子页) | 3 | 0 | ❌ → MSW 兜底 |
| files | 1 | 1 | 0 | ❌ → MSW 兜底 |
| ai-settings | 1 | 1 | 0 | ❌ → MSW 兜底 |
| system | 1 | 1 | 0 | ❌ → MSW 兜底 |
| viewports | 1 | 1 | 0 | ❌ → MSW 兜底 |
| plugins | 1 | 1 | 0 | ✅ config-service |
| course-plans | §四补充(4 页) | 4 | 0 | ❌ → MSW 兜底 |
| curriculum-map | §四补充(1 页) | 1 | 0 | ❌ → MSW 兜底 |
| elective | §四补充(4 页) | 4 | 0 | ❌ → MSW 兜底 |
| questions | §四补充(1 页) | 1 | 0 | ❌ → MSW 兜底 |
| lesson-plans | §四补充(2 页) | 2 | 0 | ❌ → MSW 兜底 |
| error-book | §四补充(1 页) | 1 | 0 | ❌ → MSW 兜底 |
| scheduling | §四补充(3+redirect) | 4 | 0 | ❌ → MSW 兜底 |
| attendance | §四补充(1 页) | 1 | 0 | ❌ → MSW 兜底 |
| 合计 | ~24(顶层)+ ~25(子页/补充) | 49 | 0 | 2 ✅ / 47 ❌(MSW 兜底) |
批次:全部 B5(含 §四补充批次,已全部落地);契约就绪:plugins ✅ + dashboard ✅;其余 47 页 schema 未就绪,前端用 MSW 兜底先行(@contract-pending 标注)。
四、CICD 中存在但 ARCH §9.4 未规划的管理员页面(已全部实现)
这些页面在 CICD 中属于"管理员视角的跨班聚合/全局只读"功能,是教师域功能在管理员层级的复用。ARCH §9.4 未将其纳入 24 页顶层规划,但 portal-shell 已全部实现(含详情/编辑/创建子页),共 25 页。
4.1 course-plans 模块(4 页,已实现)
| portal-shell 路径 | 状态 | client 组件 | 行数 |
|---|---|---|---|
| /shell/admin/course-plans | ✅ | course-plans-list-client.tsx | 339 |
| /shell/admin/course-plans/create | ✅ | course-plan-create-client.tsx | 415 |
| /shell/admin/course-plans/[id] | ✅ | course-plan-detail-client.tsx | 644 |
| /shell/admin/course-plans/[id]/edit | ✅ | course-plan-edit-client.tsx | 562 |
4.2 curriculum-map 模块(1 页,已实现)
| portal-shell 路径 | 状态 | client 组件 | 行数 |
|---|---|---|---|
| /shell/admin/curriculum-map | ✅ | curriculum-map-client.tsx | 256 |
4.3 elective 模块(4 页,已实现)
| portal-shell 路径 | 状态 | client 组件 | 行数 |
|---|---|---|---|
| /shell/admin/elective | ✅ | elective-list-client.tsx | 545 |
| /shell/admin/elective/create | ✅ | elective-create-client.tsx | 381 |
| /shell/admin/elective/[id] | ✅ | elective-detail-client.tsx | 385 |
| /shell/admin/elective/[id]/edit | ✅ | elective-edit-client.tsx | 464 |
4.4 questions 模块(1 页,已实现)
| portal-shell 路径 | 状态 | client 组件 | 行数 |
|---|---|---|---|
| /shell/admin/questions | ✅ | questions-list-client.tsx | 537 |
4.5 lesson-plans 模块(2 页,已实现)
| portal-shell 路径 | 状态 | client 组件 | 行数 |
|---|---|---|---|
| /shell/admin/lesson-plans | ✅ | lesson-plans-list-client.tsx | 489 |
| /shell/admin/lesson-plans/[planId]/view | ✅ | lesson-plan-view-client.tsx | 205 |
4.6 error-book 模块(1 页,已实现)
| portal-shell 路径 | 状态 | client 组件 | 行数 |
|---|---|---|---|
| /shell/admin/error-book | ✅ | error-book-client.tsx | 738 |
4.7 scheduling 模块(3 页 + redirect,已实现)
| portal-shell 路径 | 状态 | client 组件 | 行数 |
|---|---|---|---|
| /shell/admin/scheduling | ↪️ | redirect → /scheduling/changes | — |
| /shell/admin/scheduling/auto | ✅ | auto-schedule-client.tsx | 270 |
| /shell/admin/scheduling/changes | ✅ | schedule-changes-client.tsx | 471 |
| /shell/admin/scheduling/rules | ✅ | scheduling-rules-client.tsx | 401 |
4.8 attendance 模块(1 页,已实现)
| portal-shell 路径 | 状态 | client 组件 | 行数 |
|---|---|---|---|
| /shell/admin/attendance | ✅ | admin-attendance-client.tsx | 340 |
4.9 announcements 详情/编辑(2 页,已实现)
| portal-shell 路径 | 状态 | client 组件 | 行数 |
|---|---|---|---|
| /shell/admin/announcements/[id] | ✅ | announcement-detail-client.tsx | 289 |
| /shell/admin/announcements/[id]/edit | ✅ | announcement-edit-client.tsx | 266 |
4.10 users/import + users/[id] 子页(2 页,已实现)
| portal-shell 路径 | 状态 | client 组件 | 行数 |
|---|---|---|---|
| /shell/admin/users/import | ✅ | users-import-client.tsx | 414 |
| /shell/admin/users/[id] | ✅ | user-detail-client.tsx | 404 |
4.11 roles/[id] 详情(1 页,已实现)
| portal-shell 路径 | 状态 | client 组件 | 行数 |
|---|---|---|---|
| /shell/admin/roles/[id] | ✅ | role-detail-client.tsx | 165 |
4.12 school/grades/insights(1 页,已实现)
| portal-shell 路径 | 状态 | client 组件 | 行数 |
|---|---|---|---|
| /shell/admin/school/grades/insights | ✅ | grade-insights-client.tsx | 495 |
五、迁移注意事项
5.1 架构迁移要点(已完成)
- 管理员权限校验:portal-shell 采用 Client Component + BFF 模式,权限校验由 route-permissions.ts 在路由层 EXACT/PREFIX 表登记(如 /shell/admin/* → ["admin"]),与 CICD 的 Server Component + requirePermission 模式不同但等价。
- DataScope 上下文:portal-shell 在 BFF 层注入数据范围上下文,client 组件通过 lib/api hooks 消费,无需 page.tsx 显式传递。
- Server Action + router.refresh 模式:portal-shell 改用 Apollo Client mutation + useQuery refetch / notify 通知,等价于 CICD 的 Server Action + router.refresh()。
- 导出功能:audit-logs 三页 + error-book 的 CSV 导出,已通过 useExportAuditLogs / useExportLoginLogs / useExportDataChanges / useExportErrorBookCsv hooks 封装,等待后端契约就绪后接真实端点。
- 服务注入:audit-logs/overview 在 portal-shell 中改为 client 组件直接调用 useAuditOverviewStats / useAuditTrend / useDataChangeActionStats 三个 hook 并行查询,等价于 CICD 的 AuditServiceProvider + adminAuditService 模式。
5.2 模块复杂度与契约风险
| 模块 | 风险点 | 当前缓解 | 待办 |
|---|---|---|---|
| audit-logs(4 页) | 审计核心,多维筛选 + 导出 + 概览统计 + 数据变更统计 | 前端 4 页 UI 已完成(共 1644 行 client 代码),MSW 兜底 | 后端契约工单:auditLogs / loginLogs / dataChangeLogs / auditOverviewStats / 导出端点 |
| school(7 页) | 体系复杂,6 业务子页 + 1 redirect,跨表关联 | 前端 7 页 UI 已完成(共 3335 行 client 代码),MSW 兜底 | 后端契约工单:schools / departments / academicYears / grades / adminClasses / gradeOverviewStats |
| scheduling(4 页) | 自动排课算法 + 冲突检测 + 审批流 | 前端 4 页 UI 已完成(共 1142 行 client 代码),MSW 兜底 | 后端契约工单:autoSchedule / scheduleChanges / scheduleEntries / schedulingRules + 排课算法服务 |
| error-book(1 页) | 5 统计卡 + 4 图表 + Top 50 学生 + Top 10 错题 | 前端 1 页 UI 已完成(738 行 client 代码,最复杂单页),MSW 兜底 | 后端契约工单:adminErrorBookStats + CSV 导出端点 |
| attendance(1 页) | 7 统计 + 班级对比 + 考勤-成绩关联分析 | 前端 1 页 UI 已完成(340 行 client 代码),MSW 兜底 | 后端契约工单:adminAttendanceStats / adminAttendanceRecords / attendanceGradeCorrelation |
| curriculum-map(1 页) | 标准覆盖热图 + 5 张统计卡 | 前端 1 页 UI 已完成(256 行 client 代码),MSW 兜底 | 后端契约工单:standardsCoverageHeatmap / globalLessonPlanStats |
| ai-settings(1 页) | 双权限 + Provider 配置 + Usage 仪表盘 | 前端 1 页 UI 已完成(522 行 client 代码),MSW 兜底 | 后端契约工单:aiProviders / aiUsageDashboard + Provider CRUD 端点 |
| users(3 页) | 用户列表 + 批量导入 + 详情,关联角色分配 | 前端 3 页 UI 已完成(共 1356 行 client 代码),MSW 兜底 | 后端契约工单:users 列表 + importUsers mutation |
| course-plans(4 页) | 课程计划 CRUD + 子项 reorder + 批量切换 | 前端 4 页 UI 已完成(共 1960 行 client 代码),MSW 兜底 | 后端契约工单:adminCoursePlans / adminCoursePlan + 子项 CRUD mutations |
| elective(4 页) | 选修课 CRUD + 抽签 + 选课开关 | 前端 4 页 UI 已完成(共 1775 行 client 代码),MSW 兜底 | 后端契约工单:adminElectives / adminElective + 抽签 mutation |
5.3 契约就绪优先级(用于后端工单排期)
前端 49 页已全部落地,瓶颈在后端 GraphQL schema 就绪。按业务价值与依赖关系排期:
- 优先级 1(契约 ✅,已完成真实查询):/shell/admin(adminDashboard ✅)+ /shell/admin/plugins(config-service ✅)
- 优先级 2(高价值 RBAC 核心,需后端契约工单):users(3 页)+ roles(2 页)+ permissions(1 页)+ invitation-codes(1 页)= 7 页;后端契约:users / roles / permissions / permissionRoleCounts / invitationCodes + 相关 mutations
- 优先级 3(高频运营功能,需后端契约工单):announcements(3 页)+ files(1 页)+ ai-settings(1 页)+ system(1 页)= 6 页;后端契约:adminAnnouncements / fileAttachments / aiProviders / aiUsageDashboard / systemSettings
- 优先级 4(审计与组织管理,高复杂度):audit-logs(4 页)+ school(7 页)+ organization(1 页)+ students(1 页)+ teachers(1 页)+ viewports(1 页)= 15 页;后端契约:审计 4 类查询 + 导出端点;school 6 类实体 CRUD;organizationTree / adminStudents / adminTeachers / viewports
- 优先级 5(§四补充批次,教师域聚合视图):course-plans(4 页)+ curriculum-map(1 页)+ elective(4 页)+ questions(1 页)+ lesson-plans(2 页)+ error-book(1 页)+ scheduling(4 页)+ attendance(1 页)= 18 页;后端契约:均为教师域聚合查询在 admin scope 下的复用
5.4 CICD admin/layout.tsx 迁移说明
CICD admin/layout.tsx 仅 return <>{children}</>,无独立侧边栏/权限逻辑(侧边栏由 (dashboard)/layout.tsx 统一处理,权限由各 page 调 requirePermission)。
portal-shell 同样无需在 shell/admin/layout.tsx 实现额外逻辑,保持 passthrough 即可;侧边栏与权限校验由 shell/layout.tsx 与 route-permissions.ts 分担。
5.5 三层支撑完整度核查
| 支撑层 | 文件 | 行数 | 覆盖情况 |
|---|---|---|---|
| page.tsx 入口 | src/app/shell/admin/**/page.tsx | 49 文件 | 49/49 全部存在,46 业务页 + 3 redirect 页 |
| client 业务组件 | src/features/admin/**/*-client.tsx | 44 文件 | 44/44 全部实现,165-738 行/文件,均调用 lib/api hooks,处理三态 |
| lib/api hooks | src/lib/api/admin.ts + admin-p5.ts | 973 + 3371 = 4344 行 | 全覆盖:users/roles/permissions/audit-logs/invitation-codes/school/announcements/files/ai-settings/system/viewports/students/teachers/organization/course-plans/curriculum-map/elective/questions/lesson-plans/error-book/scheduling/attendance/plugins |
| mocks 兜底数据 | src/mocks/graphql-data.ts | 9867 行 | 全覆盖:mockAdminDashboard / mockUsers / mockAdminPermissions / mockSchools / mockDepartments / mockAcademicYears / mockAdminGrades / mockAdminClasses / mockAdminAnnouncements / mockInvitationCodes / mockFileAttachments / mockAiProviders / mockSystemSettings / mockViewports / mockAdminStudents / mockAdminTeachers / mockOrganizationTree / mockAdminCoursePlans / mockAdminLessonPlans / mockAdminElectives / mockAdminQuestions / mockAdminScheduleChanges / mockSchedulingRules / mockAdminAttendanceRecords / mockLoginLogs / mockDataChangeLogs 等 |
六、附录:CICD admin/page.tsx 完整清单(41 个)+ ARCH 新建(5 个)= 46 项对照
| # | CICD 路径 | ARCH §9.4 归属 | portal-shell 状态(2026-08-04) |
|---|---|---|---|
| 1 | admin/dashboard/page.tsx | §9.4 第 1 行 ✅ | ✅ /shell/admin/page.tsx(真实契约 adminDashboard) |
| 2 | admin/users/page.tsx | §9.4 第 2 行 ❌ | ✅ /shell/admin/users/page.tsx(MSW 兜底) |
| 3 | admin/users/import/page.tsx | §9.4 第 2 行 ❌(合并) | ✅ /shell/admin/users/import/page.tsx(MSW 兜底) |
| 4 | admin/roles/page.tsx | §9.4 第 3 行 ❌ | ✅ /shell/admin/roles/page.tsx(MSW 兜底) |
| 5 | admin/roles/[id]/page.tsx | §四补充批次 | ✅ /shell/admin/roles/[id]/page.tsx(MSW 兜底) |
| 6 | admin/permissions/page.tsx | §9.4 第 3 行 ❌ | ✅ /shell/admin/permissions/page.tsx(MSW 兜底) |
| 7 | admin/audit-logs/page.tsx | §9.4 第 4 行 ❌ | ✅ /shell/admin/audit-logs/page.tsx(MSW 兜底) |
| 8 | admin/audit-logs/overview/page.tsx | §9.4 第 4 行 ❌ | ✅ /shell/admin/audit-logs/overview/page.tsx(MSW 兜底) |
| 9 | admin/audit-logs/login-logs/page.tsx | §9.4 第 4 行 ❌ | ✅ /shell/admin/audit-logs/login-logs/page.tsx(MSW 兜底) |
| 10 | admin/audit-logs/data-changes/page.tsx | §9.4 第 4 行 ❌ | ✅ /shell/admin/audit-logs/data-changes/page.tsx(MSW 兜底) |
| 11 | admin/invitation-codes/page.tsx | §9.4 第 5 行 ❌ | ✅ /shell/admin/invitation-codes/page.tsx(MSW 兜底) |
| 12 | admin/school/page.tsx(redirect) | §9.4 第 6 行 ❌ | ↪️ /shell/admin/school/page.tsx → /school/schools |
| 13 | admin/school/schools/page.tsx | §9.4 第 6 行 ❌ | ✅ /shell/admin/school/schools/page.tsx(MSW 兜底) |
| 14 | admin/school/classes/page.tsx | §9.4 第 6/7 行 ❌ | ✅ /shell/admin/school/classes/page.tsx(MSW 兜底) |
| 15 | admin/school/departments/page.tsx | §9.4 第 6 行 ❌ | ✅ /shell/admin/school/departments/page.tsx(MSW 兜底) |
| 16 | admin/school/academic-year/page.tsx | §9.4 第 6 行 ❌ | ✅ /shell/admin/school/academic-year/page.tsx(MSW 兜底) |
| 17 | admin/school/grades/page.tsx | §9.4 第 6 行 ❌ | ✅ /shell/admin/school/grades/page.tsx(MSW 兜底) |
| 18 | admin/school/grades/insights/page.tsx | §四补充批次 | ✅ /shell/admin/school/grades/insights/page.tsx(MSW 兜底) |
| 19 | admin/announcements/page.tsx | §9.4 第 10 行 ❌ | ✅ /shell/admin/announcements/page.tsx(MSW 兜底) |
| 20 | admin/announcements/[id]/page.tsx | §四补充批次 | ✅ /shell/admin/announcements/[id]/page.tsx(MSW 兜底) |
| 21 | admin/announcements/[id]/edit/page.tsx | §四补充批次 | ✅ /shell/admin/announcements/[id]/edit/page.tsx(MSW 兜底) |
| 22 | admin/files/page.tsx | §9.4 第 11 行 ❌ | ✅ /shell/admin/files/page.tsx(MSW 兜底) |
| 23 | admin/ai-settings/page.tsx | §9.4 第 12 行 ❌ | ✅ /shell/admin/ai-settings/page.tsx(MSW 兜底) |
| 24 | admin/settings/page.tsx | §9.4 第 13 行 ❌(→ /system) | ✅ /shell/admin/system/page.tsx(MSW 兜底) |
| 25 | admin/course-plans/page.tsx | §四补充批次 | ✅ /shell/admin/course-plans/page.tsx(MSW 兜底) |
| 26 | admin/course-plans/create/page.tsx | §四补充批次 | ✅ /shell/admin/course-plans/create/page.tsx(MSW 兜底) |
| 27 | admin/course-plans/[id]/page.tsx | §四补充批次 | ✅ /shell/admin/course-plans/[id]/page.tsx(MSW 兜底) |
| 28 | admin/course-plans/[id]/edit/page.tsx | §四补充批次 | ✅ /shell/admin/course-plans/[id]/edit/page.tsx(MSW 兜底) |
| 29 | admin/curriculum-map/page.tsx | §四补充批次 | ✅ /shell/admin/curriculum-map/page.tsx(MSW 兜底) |
| 30 | admin/elective/page.tsx | §四补充批次 | ✅ /shell/admin/elective/page.tsx(MSW 兜底) |
| 31 | admin/elective/create/page.tsx | §四补充批次 | ✅ /shell/admin/elective/create/page.tsx(MSW 兜底) |
| 32 | admin/elective/[id]/page.tsx | §四补充批次 | ✅ /shell/admin/elective/[id]/page.tsx(MSW 兜底) |
| 33 | admin/elective/[id]/edit/page.tsx | §四补充批次 | ✅ /shell/admin/elective/[id]/edit/page.tsx(MSW 兜底) |
| 34 | admin/questions/page.tsx | §四补充批次 | ✅ /shell/admin/questions/page.tsx(MSW 兜底) |
| 35 | admin/lesson-plans/page.tsx | §四补充批次 | ✅ /shell/admin/lesson-plans/page.tsx(MSW 兜底) |
| 36 | admin/lesson-plans/[planId]/view/page.tsx | §四补充批次 | ✅ /shell/admin/lesson-plans/[planId]/view/page.tsx(MSW 兜底) |
| 37 | admin/error-book/page.tsx | §四补充批次 | ✅ /shell/admin/error-book/page.tsx(MSW 兜底) |
| 38 | admin/scheduling/auto/page.tsx | §四补充批次 | ✅ /shell/admin/scheduling/auto/page.tsx(MSW 兜底) |
| 39 | admin/scheduling/changes/page.tsx | §四补充批次 | ✅ /shell/admin/scheduling/changes/page.tsx(MSW 兜底) |
| 40 | admin/scheduling/rules/page.tsx | §四补充批次 | ✅ /shell/admin/scheduling/rules/page.tsx(MSW 兜底) |
| 41 | admin/attendance/page.tsx | §四补充批次 | ✅ /shell/admin/attendance/page.tsx(MSW 兜底) |
ARCH §9.4 规划但 CICD 无源(5 项,已全部新建):
| # | ARCH 目标路由 | 说明 | 契约 | portal-shell 状态(2026-08-04) |
|---|---|---|---|---|
| A | /shell/admin/students | ARCH 新建,CICD 无 | ❌ → MSW 兜底 | ✅ /shell/admin/students/page.tsx |
| B | /shell/admin/teachers | ARCH 新建,CICD 无 | ❌ → MSW 兜底 | ✅ /shell/admin/teachers/page.tsx |
| C | /shell/admin/organization | ARCH 新建,CICD 无 | ❌ → MSW 兜底 | ✅ /shell/admin/organization/page.tsx |
| D | /shell/admin/viewports | ARCH 新建,对齐 004 §5.4 | ❌ → MSW 兜底 | ✅ /shell/admin/viewports/page.tsx |
| E | /shell/admin/plugins | ARCH 新建(plugin-manager 升级) | ✅ config-service | ✅ /shell/admin/plugins/page.tsx(真实契约) |
portal-shell 额外新增(3 项 redirect 入口):
| # | portal-shell 路由 | 说明 |
|---|---|---|
| α | /shell/admin/classes | redirect → /shell/admin/school/classes |
| β | /shell/admin/scheduling | redirect → /shell/admin/scheduling/changes |
| γ | /shell/admin/school | redirect → /shell/admin/school/schools |