Files
Edu/apps/admin-portal/docs/01-understanding.md
SpecialX e691cd267d docs(teacher-portal): ai07 阶段1+2 拆分到4端portal的docs目录
删除合并版README,按portal拆分8份文档(每端01-understanding+02-architecture-design)

teacher-portal(shell/P2)+student-portal(remote/P3)+parent-portal(remote/P4)+admin-portal(remote/P6)

AI Agent: ai07 (4 portals)

Branch: docs/portals-stage1-stage2-design-ai07
2026-07-09 18:23:27 +08:00

18 KiB
Raw Blame History

模块理解确认书 — admin-portal

AIai07TS/React · 管理场景域前端 remote 阶段:阶段 1 交付物 日期2026-07-09 关联:004 架构影响地图 §1.1a/1.1b/§5.4、AI 分配方案 §5 ai07、pending-features P6known-issues §2.12teacher-portal 阶段1teacher-portal 阶段2


1. 我在架构中的位置

  • 层级L2 微前端层004 §3.1 六层架构中的前端层)
  • MF 角色Remote 子应用,挂载到 teacher-portal Shell主应用
  • 上游(谁调用我):浏览器(系统管理员 / 校管理员)
  • 下游(同步)api-gatewayREST经 teacher-portal Shell 的 Next.js rewrites 代理 /api/v1/*
  • 下游(推送):— 不消费推送,管理端用轮询)
  • BFF 对接teacher-bff 复用(/admin/* 聚合)+ iam 直连(/iam/* 用户/角色/权限/视口 CRUD
  • 通信方式HTTP/REST前端→Gateway
  • 不直连:前端不直连任何业务服务或 BFF 后端实例,全部经 api-gateway 代理

说明

  • admin-portal 作为 Remote 子应用,挂载到 teacher-portal Shell 提供的 AppShell + 共享依赖react/react-dom/@tanstack/react-query/zustand/nuqs/ui-components/ui-tokens/contracts/hooks
  • 路由前缀 /admin/* 由 teacher-portal Shell 动态加载 admin-portal Remote 模块
  • 场景域 BFF 复用策略004 §5.4):系统/校管理员复用 teacher-portal Shell + teacher-bff/admin/* 视口)+ iam 直连,不单独建 portal 后端
  • 全部业务请求经 api-gateway 代理admin-portal 本身不实现 rewrites依赖 Shell 的 rewrites

2. 我的限界上下文

2.1 我负责的聚合 / 实体(前端视图模型)

  • 用户、角色、权限、视口(管理场景域前端视图)
  • 组织(学校/年级/班级层级)
  • 平台监控(运行时指标、用户活动、错误统计)
  • 会话状态Session、视口Viewport、权限Permission与 teacher-portal 共享,引用 teacher-portal 文档)

2.2 业务领域

  • 管理场景域(前端场景域:管理场景域,对应后端 iam 限界上下文 + teacher-bff 管理视口)

2.3 不负责

  • 教学业务编排(班级/考试/作业/成绩 CRUD归 teacher-portal
  • 学生作答界面(归 student-portal
  • 家长多子女切换(归 parent-portal
  • 教师仪表盘(归 teacher-portaladmin-portal 仅有管理仪表盘)

2.4 数据范围

  • DataScope L3-L5校管理员 L3 学校 / 区教研员 L4 / 系统管理员 L5 全平台)
  • 不出现 L1班级/ L2年级级别的教师数据视角

3. 我与外部的契约

3.1 消费的后端 API经 api-gateway 代理)

路径前缀 下游 BFF/服务 关键端点
/api/v1/iam/*(管理用) iam GET /iam/usersPOST /iam/usersPUT /iam/users/:idGET /iam/rolesGET /iam/permissionsGET /iam/viewportsPUT /iam/viewports/:id
/api/v1/admin/* teacher-bff 复用 + iam 直连 GET /admin/dashboardGET /admin/monitoring/metricsGET /admin/stats/usersGET /admin/stats/active-sessions
/api/v1/notifications/* msg 通知中心P5

3.2 统一响应契约

所有后端响应遵循 ActionState 结构(迁移指南 §7.5

type ActionState<T> =
  | { success: true; data: T }
  | {
      success: false;
      error: { code: string; message: string; details?: unknown };
    };

错误码前缀按服务名大写admin-portal 涉及:IAM_BFF_TEACHER_GW_NETWORK_)。前端 API 请求层根据 error.code 前缀路由到对应的 i18n key。

3.3 推送契约

— N/A

admin-portal 不消费 WebSocket 推送或 SSE 流式响应。管理端场景对实时性要求低,采用轮询策略:

  • 平台监控页60s 轮询 GET /api/v1/admin/monitoring/metrics
  • 用户活动统计5min 轮询 GET /api/v1/admin/stats/active-sessions
  • 通知中心P5HTTP 长轮询或定时拉取 GET /api/v1/notifications(不走 push-gateway

长期监控指标推荐用 <iframe> 嵌入 Grafana 面板PlatformMonitor 组件),不经过 BFF。

3.4 proto 不直接消费

前端不调用 gRPCBFF 把 gRPC 聚合为 REST 暴露给前端。前端仅消费 packages/contracts/src/permissions.ts 中的权限点常量TS 文件,非 proto 生成)。

4. 我的技术栈

维度 选型 说明
框架 Next.js 14+App Router server components 默认client components 按需
语言 TypeScript 5.5+strict 沿用 tsconfig.base.json
微前端 Module Federation 2.0@module-federation/nextjs-mf admin-portal = Remote
样式 Tailwind CSS 3.4+ 配合设计令牌三层模型(与 teacher-portal 共享)
UI 组件库 shadcn/ui迁移指南 §7.2 复用 Shell 暴露的 packages/ui-components/
状态管理 L1 URL nuqs 可分享、可刷新状态
状态管理 L2 Server TanStack Query v5 服务端数据缓存、重试、乐观更新
状态管理 L3 Client Business Zustand slice 客户端业务状态
状态管理 L4 Global UI Zustand ui-store + ModalRoot复用 Shell 全局 UI 状态
状态管理 L5 Form react-hook-form + zodResolver 表单状态
富文本 不使用 管理端无富文本场景,不引入 Tiptap
图表 recharts 管理仪表盘、用户活动统计
i18n next-intl BFF/服务返回 i18n key + 参数,前端翻译
A11y eslint-plugin-jsx-a11yerror 级) WCAG 2.2 AA
字体 Intersans/ Frauncesserif/ JetBrains Monomono 复用 teacher-portal RootLayout 加载,不重复引入

技术栈与 teacher-portal 完全一致差异仅在MF 角色Remote 而非 Shell、不使用 Tiptap、不消费 WebSocket/SSE 推送、数据范围 L3-L5。

5. 我的阶段归属

  • 阶段P6硬化阶段
  • 当前状态 全为待建admin-portal 当前为空目录,无任何代码);📐 需设计(待全部业务服务稳定)
  • 依赖上游阶段P6依赖 teacher-portal Shell 已就绪 + iam 已实现用户/角色/权限/视口 CRUD + teacher-bff 已实现 /admin/* 复用)

6. 我需要对齐的黄金模板项(对照 classes 服务)

前端无 @RequirePermission 装饰器(后端概念),对齐项改造为前端等价物。

对齐项 classes后端黄金模板 admin-portal 前端等价 当前状态
权限校验 @RequirePermission(Permissions.XXX) usePermission().hasPermission("XXX") Hook + <RequirePermission> 组件 待建(无现有代码)
错误码前缀统一 CLASSES_*IAM_* API 请求层根据 error.code 前缀路由 i18n 待建
logger pino 前端 console + SentryP6 待建
metrics prom-client /metrics 前端 Web Vitals → Gateway 上报 待建
tracer OTel SDK 前端 OTel browser SDKP6 待建
/healthz + /readyz GET /healthz GET /readyz Next.js /api/health route + Dockerfile HEALTHCHECK 待建
优雅关闭 SIGTERM handler Next.js 无长连接,无需 N/A
测试覆盖率 ≥ 80% Vitest Vitest + @testing-library/react + Playwright E2E 待建0%
Dockerfile 多阶段构建 builder + runtime builder + runtime 待建
Zod 输入验证 class-validator + Zod schema react-hook-form + zodResolver 待建
GlobalErrorFilter NestJS 全局异常过滤器 React ErrorBoundary + API 请求层统一错误处理 待建
设计令牌三层 primitive.css / semantic-light/dark.css / tailwind-theme.css复用 待建(复用 Shell 暴露)
A11y 工具集 useA11yId / mergeA11yProps / describeInput / focus-trap复用 Shell 待建(复用 Shell 暴露)

admin-portal 现状审计(对齐黄金模板)

审计表

维度 状态 说明
权限装饰器(前端等价 usePermission 待建,复用 Shell 暴露的 usePermission Hook + <RequirePermission> 组件
错误码前缀 待建,复用 Shell 暴露的 ApiClient统一请求层
logger 待建,复用 packages/shared-ts/src/logger.ts
metrics 待建Web Vitals 上报 admin_portal_*
tracer 待建OTel browser SDKP6
/healthz 待建Next.js Route Handler
/readyz 待建Next.js Route Handler
优雅关闭 N/A Next.js 无长连接
测试覆盖率 待建,目标 ≥ 80%
Dockerfile 多阶段 待建builder + runtime
Zod 输入验证 待建react-hook-form + zodResolver
GlobalErrorFilterErrorBoundary 待建,复用 Shell 暴露的 ErrorBoundary
设计令牌三层 待建,复用 Shell 暴露的 packages/ui-tokens/
A11y 工具集 待建,复用 Shell 暴露的 packages/ui-components/
Module Federation 配置 待建next.config.js 配置 Remote 角色
5 层状态管理 待建,复用 Shell 暴露的 nuqs/TanStack Query/Zustand
共享组件库 待建,复用 Shell 暴露 + admin 特有 4 个组件
i18n 待建next-intl
API 请求层 待建,复用 Shell 暴露的 ApiClient
ESLint flat config 自定义规则 待建no-hardcoded-fonts / design-tokens 规则

现有文件清单

apps/admin-portal/        # 空目录(待建)

说明admin-portal 当前为空目录,所有维度均为 待建状态。无现有文件、无现有代码、无现有违规点。P6 阶段从零开始搭建。

L1 导航菜单(视口)

视口 key 标签i18n key 路由 权限
dashboard admin.nav.dashboard /admin/dashboard ADMIN_DASHBOARD_VIEW
users admin.nav.users /admin/users IAM_USER_READ
roles admin.nav.roles /admin/roles IAM_ROLE_READ
permissions admin.nav.permissions /admin/permissions IAM_PERMISSION_READ
viewports admin.nav.viewports /admin/viewports IAM_VIEWPORT_READ
organization admin.nav.organization /admin/organization ORG_MANAGE
monitoring admin.nav.monitoring /admin/monitoring ADMIN_MONITORING_VIEW

L2 路由表

路由 页面 权限
/admin/dashboard 管理仪表盘 ADMIN_DASHBOARD_VIEW
/admin/users 用户管理 IAM_USER_READ
/admin/users/new 新建用户 IAM_USER_CREATE
/admin/users/:id 用户编辑 IAM_USER_UPDATE
/admin/roles 角色管理 IAM_ROLE_READ
/admin/permissions 权限管理 IAM_PERMISSION_READ
/admin/viewports 视口配置 IAM_VIEWPORT_READ
/admin/organization 组织管理 ORG_MANAGE
/admin/monitoring 平台监控 ADMIN_MONITORING_VIEW

L3 组件级差异admin-portal 特有)

复用 Shell 暴露的组件AppShell、RequirePermission、ErrorBoundary、Loading、Empty、DataTable、Form、Chart、Toast、Modal、Button/Input/Select/Textarea、A11y 工具集

admin-portal 特有组件

组件 用途 来源
UserManagementTable 用户管理表格(列表/筛选/分页/批量操作) 新建
RolePermissionMatrix 角色-权限矩阵编辑器checkbox 网格) 新建
ViewportConfigEditor 视口配置编辑器(拖拽排序 + 权限绑定) 新建
PlatformMonitor 平台监控Grafana iframe embed 新建

不使用的组件RichTextEditorTiptap、ExamTaking、SSEViewer、ChildSwitcher 等(这些归 teacher-portal / student-portal / parent-portal

L4 数据层差异

维度 admin-portal teacher-portal
主要数据来源 iam 直连 + teacher-bff 复用 teacher-bff 聚合 + core-edu/content/ai
缓存策略 5min 长缓存(管理数据低频变) 5min / 30s 混合(实时性差异)
实时性要求 低(轮询 60s / 5min WebSocket 推送 + SSE 流式)
推送消费 不消费 消费 WebSocket + SSE

AI Agent: ai07 (admin-portal remote) Branch: docs/admin-portal-stage1-stage2-design-ai07 Coordinator: coord-ai