删除合并版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
18 KiB
模块理解确认书 — admin-portal
AI:ai07(TS/React · 管理场景域前端 remote) 阶段:阶段 1 交付物 日期:2026-07-09 关联:004 架构影响地图 §1.1a/1.1b/§5.4、AI 分配方案 §5 ai07、pending-features P6、known-issues §2.12、teacher-portal 阶段1、teacher-portal 阶段2
1. 我在架构中的位置
- 层级:L2 微前端层(004 §3.1 六层架构中的前端层)
- MF 角色:Remote 子应用,挂载到 teacher-portal Shell(主应用)
- 上游(谁调用我):浏览器(系统管理员 / 校管理员)
- 下游(同步):api-gateway(REST,经 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-portal,admin-portal 仅有管理仪表盘)
2.4 数据范围
- DataScope L3-L5(校管理员 L3 学校 / 区教研员 L4 / 系统管理员 L5 全平台)
- 不出现 L1(班级)/ L2(年级)级别的教师数据视角
3. 我与外部的契约
3.1 消费的后端 API(经 api-gateway 代理)
| 路径前缀 | 下游 BFF/服务 | 关键端点 |
|---|---|---|
/api/v1/iam/*(管理用) |
iam | GET /iam/users、POST /iam/users、PUT /iam/users/:id、GET /iam/roles、GET /iam/permissions、GET /iam/viewports、PUT /iam/viewports/:id |
/api/v1/admin/* |
teacher-bff 复用 + iam 直连 | GET /admin/dashboard、GET /admin/monitoring/metrics、GET /admin/stats/users、GET /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 - 通知中心(P5):HTTP 长轮询或定时拉取
GET /api/v1/notifications(不走 push-gateway)
长期监控指标推荐用
<iframe>嵌入 Grafana 面板(PlatformMonitor 组件),不经过 BFF。
3.4 proto 不直接消费
前端不调用 gRPC,BFF 把 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-a11y(error 级) | WCAG 2.2 AA |
| 字体 | Inter(sans)/ Fraunces(serif)/ JetBrains Mono(mono) | 复用 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 + Sentry(P6) | ❌ 待建 |
| metrics | prom-client /metrics |
前端 Web Vitals → Gateway 上报 | ❌ 待建 |
| tracer | OTel SDK | 前端 OTel browser SDK(P6) | ❌ 待建 |
| /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 SDK(P6) |
| /healthz | ❌ | 待建,Next.js Route Handler |
| /readyz | ❌ | 待建,Next.js Route Handler |
| 优雅关闭 | ✅ N/A | Next.js 无长连接 |
| 测试覆盖率 | ❌ | 待建,目标 ≥ 80% |
| Dockerfile 多阶段 | ❌ | 待建,builder + runtime |
| Zod 输入验证 | ❌ | 待建,react-hook-form + zodResolver |
| GlobalErrorFilter(ErrorBoundary) | ❌ | 待建,复用 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) | 新建 |
不使用的组件:RichTextEditor(Tiptap)、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