Files
Edu/apps/admin-portal/docs/01-understanding.md
SpecialX b3511910d1 feat(admin-portal): 完整实现 admin-portal 管理端微前端
包含 src 全部实现、Dockerfile、配置文件等
2026-07-10 19:09:12 +08:00

21 KiB
Raw Blame History

模块理解确认书 — admin-portal

AIai16TS/React · 管理场景域前端 remote 阶段:阶段 1 交付物(仲裁后修订版 v2 日期2026-07-10 关联:


0. 仲裁结果摘要ARB-001~006

编号 议题 裁决
ARB-001 BFF 归属ISSUE-044 复用 teacher-bff GraphQL endpoint不新建 admin-bffai03 预留 admin.* 命名空间
ARB-002 错误码前缀ISSUE-045 ADMIN_ 前缀(合并 SCHOOL_/ORG_ADMIN_i18n key error.admin.*
ARB-003 权限点命名ISSUE-046 admin 自身资源用 ADMIN_*;跨服务资源保留原前缀(IAM_USER_READ 等)
ARB-004 GraphQL 客户端ISSUE-047 MF 模式复用 Shell 暴露的 GraphQL client 单例standalone 模式自建 urql client
ARB-005 审计日志归属ISSUE-048 审计事件归 iam 发布到 edu.iam.audit.createdteacher-bff 消费聚合admin-portal 经 GraphQL auditLogs Query 消费
ARB-006 WebSocket 实时通知 接入 push-gateway GET /ws(审计告警/异常登录/系统异常),不再用轮询
端口分配 admin-portal dev server 4003(非旧文档的 3003

1. 我在架构中的位置

  • 层级L2 微前端层004 §3.1 六层架构中的前端层)
  • MF 角色Remote 子应用,挂载到 teacher-portal Shell主应用端口 4000
  • 上游(谁调用我):浏览器(系统管理员 / 校管理员)
  • 下游(同步)api-gatewayGraphQL POST /api/admin/graphql + REST /api/auth/login
  • 下游(推送)push-gateway GET /wsWebSocket 实时通知ARB-006
  • BFF 对接:复用 teacher-bff GraphQL admin 命名空间ARB-001不新建 admin-bff
  • 通信方式GraphQL业务数据+ HTTP登录+ WebSocket实时通知
  • 不直连:前端不直连任何业务服务或 BFF 后端实例,全部经 api-gateway 代理

说明

  • admin-portal 作为 Remote 子应用,挂载到 teacher-portal Shell
  • Shell 暴露 GraphQLProvider / useGraphQLClient / AppShell / useAuth / usePermissionadmin-portal MF 模式复用standalone 模式自建
  • 路由前缀 /admin/* 由 teacher-portal Shell 动态加载 admin-portal Remote 模块(暴露 ./AdminApp
  • 场景域 BFF 复用策略004 §5.4 + ARB-001复用 teacher-bff GraphQL endpointadmin 命名空间(admin.* Query/Mutation

2. 我的限界上下文

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

  • 用户、角色、权限、视口(管理场景域前端视图,调 iam 经 GraphQL
  • 组织(学校/年级/班级层级)
  • 学校设置system 路由)
  • 班级/教师/学生全局管理admin 视角,只读 + 状态管理)
  • 审计日志(只读,经 teacher-bff GraphQL auditLogs Query 消费)
  • 管理仪表盘(聚合统计 + 服务健康)
  • 实时通知WebSocket 推送:审计告警/异常登录/系统异常)

2.2 业务领域

  • 管理场景域(前端场景域:管理场景域,对应后端 iam 限界上下文 + teacher-bff admin 命名空间)

2.3 不负责

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

2.4 数据范围

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

3. 我与外部的契约

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

路径 Method 下游 BFF/服务 用途
/api/admin/graphql POST teacher-bffadmin 命名空间) 全部业务 GraphQL 查询ARB-001
/api/auth/login POST api-gateway → iam 登录standalone 模式用MF 模式复用 Shell 登录)
GET /wspush-gateway WS push-gateway 实时通知(审计告警/异常登录/系统异常ARB-006

3.2 GraphQL Operationscontract §2.4

admin-portal 消费 teacher-bff admin 命名空间的 18 个 GraphQL operations

Operation 类型 用途
currentUser Query 当前管理员信息
adminUsers / adminUser(id) Query 用户列表 / 详情
createUser / updateUser / toggleUserStatus Mutation 用户 CRUD
adminRoles Query 角色列表(含权限)
createRole / updateRolePermissions Mutation 角色 CRUD + 权限矩阵
adminPermissions Query 全量权限点(按 resource
adminViewports(scope) Query 视口配置列表
updateViewport Mutation 视口配置更新
adminOrganization(parentId) Query 组织树
adminClasses Query 班级管理(全局)
adminTeachers Query 教师管理
adminStudents Query 学生管理
auditLogs(filter) Query 审计日志(聚合 iam AuditEvent
adminDashboard Query 管理员仪表盘聚合
systemSettings / updateSystemSettings Query/Mutation 学校设置

3.3 推送契约ARB-006

admin-portal 接入 push-gateway GET /ws,消费 3 类实时通知:

通知类型 severity 用途
audit_alert warning 审计告警(敏感操作触发)
abnormal_login error 异常登录(异地/异常时段)
system_error error 系统异常(服务降级/宕机)

不再用轮询:旧文档的"60s 轮询监控 + 5min 轮询统计"策略已被 ARB-006 替换为 WebSocket 实时推送。开发期用 mock-socket + 30s 定时器模拟推送。

3.4 proto 不直接消费

前端不调用 gRPCteacher-bff 把 gRPC 聚合为 GraphQL 暴露给前端。前端仅消费 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,端口 4003
数据层 urql GraphQL client standalone 自建 / MF 复用 Shell 单例ARB-004
样式 Tailwind CSS 3.4+ 配合设计令牌三层(复用 Shell
UI 组件库 shadcn/ui 风格(复用 Shell @edu/ui-components admin-portal 内部 ui.tsx 封装 PaperCard/Button/Table 等纸面组件
表单 react-hook-form + zod 用户表单/学校设置
拖拽排序 @dnd-kit/sortable 视口配置拖拽排序
图表 recharts 仪表盘趋势表(实际以纯表格为主,纸面风格)
i18n 轻量 i18nmessages 字典 + t() 函数) 命名空间 admin.*,不依赖 next-intl
Mock MSWMock Service Worker+ mock-socket 开发期拦截全部 GraphQL/HTTP + WebSocket mock
Web Vitals web-vitals v4 LCP/CLS/FCP/INP/TTFB 采集,navigator.sendBeacon 上报
A11y eslint-plugin-jsx-a11yerror 级) WCAG 2.2 AA
字体 Intersans/ Frauncesserif/ JetBrains Monomono RootLayout 加载standaloneMF 模式复用 Shell
测试 Vitest + @testing-library/react jsdom 环境,覆盖率 ≥ 80%
ESLint ESLint 9 flat config jsx-a11y + tseslint + prettier@next/eslint-plugin-next 14.x 与 ESLint 9 不兼容,已移除)

技术栈差异vs teacher-portalMF 角色Remote、GraphQL 为主(非 REST、消费 WebSocket 推送(非 SSE、纸面 UI 风格、数据范围 L3-L5。

5. 我的阶段归属

  • 阶段P6硬化阶段批次 5
  • 当前状态 已实现P2-P6 全阶段交付完成,含 11 路由 + MSW mock + A11y + Web Vitals + Dockerfile
  • 依赖上游阶段P6依赖 teacher-portal Shell 已就绪 + teacher-bff GraphQL admin 命名空间 + iam 已实现用户/角色/权限/视口 CRUD + push-gateway WebSocket

6. 路由表11 路由contract §1.2

路由 页面 权限点 数据范围
/admin/dashboard 管理员仪表盘 ADMIN_DASHBOARD_VIEW L3-L5
/admin/users 用户管理 IAM_USER_READ L3-L5
/admin/roles 角色权限管理 IAM_ROLE_READ L3-L5
/admin/permissions 权限点管理 IAM_PERMISSION_READ L5
/admin/viewports 视口配置 IAM_VIEWPORT_READ L5
/admin/organization 组织管理 ADMIN_ORG_MANAGE L3-L5
/admin/system 学校设置 ADMIN_SYSTEM_MANAGE L5
/admin/classes 班级管理(全局) ADMIN_CLASS_READ L3-L5
/admin/teachers 教师管理 ADMIN_TEACHER_READ L3-L5
/admin/students 学生管理 ADMIN_STUDENT_READ L3-L5
/admin/audit-logs 审计日志 ADMIN_AUDIT_READ L5

权限点前缀规则ARB-003admin 自身资源用 ADMIN_*;跨服务资源保留原前缀(如 IAM_USER_READ)。ADMIN_* 常量由 coord 维护于 packages/contracts/src/permissions.tsadmin-portal 引用 src/lib/permissions.ts,不硬编码。

7. 黄金模板对齐清单(前端等价)

对齐项 后端等价 admin-portal 实现 状态
权限校验 @RequirePermission(Permissions.XXX) usePermission().hasPermission("XXX") Hook + AuthGuard
错误码前缀 IAM_* / ADMIN_* CONSUMED_ERROR_PREFIXES 常量 + i18n 路由
logger pino console + 结构化(生产 → 上报)
metrics prom-client /metrics Web Vitals v4 → navigator.sendBeacon 上报
/health + /ready GET /healthz GET /readyz Next.js Route Handler /api/health + /api/ready
优雅关闭 SIGTERM handler N/ANext.js 无长连接)
测试覆盖率 ≥ 80% Vitest Vitest + @testing-library/react ⚠️
Dockerfile 多阶段构建 builder + runtime node:22-alpine 多阶段standalone 输出EXPOSE 4003
Zod 输入验证 class-validator + Zod schema react-hook-form + zod
GlobalErrorFilter NestJS 全局异常过滤器 React ErrorBoundary + Toast 错误处理
设计令牌三层 globals.cssprimitive/semantic+ tailwind-theme
A11y 工具集 eslint-plugin-jsx-a11yerror 级)+ skip-link + focus-visible
Module Federation next.config.js Remote 角色,NEXT_PUBLIC_MF_ENABLED 控制
MSW mock 18 GraphQL operation + /api/auth/login mock

admin-portal 实现清单v2仲裁后修订

文件结构

apps/admin-portal/
├─ package.json                    # 依赖urql/msw/@dnd-kit/web-vitals/eslint-plugin-jsx-a11y
├─ next.config.js                  # MF Remote 配置 + rewritesGraphQL 代理)
├─ tsconfig.json                   # extends tsconfig.base.json
├─ tailwind.config.js              # paper/ink/accent/rule 色板
├─ eslint.config.js                # ESLint 9 flat configjsx-a11y + tseslint + prettier
├─ Dockerfile                      # 多阶段构建node:22-alpinestandalone
├─ vitest.config.ts                # jsdom + coverage ≥80%
├─ .env.example                    # 环境变量模板
├─ public/mockServiceWorker.js     # MSW worker
└─ src/
   ├─ app/
   │  ├─ globals.css               # 设计令牌 + A11y 样式
   │  ├─ layout.tsx                # RootLayout字体加载
   │  ├─ page.tsx                  # 根页面redirect /admin/dashboard
   │  ├─ admin-app.tsx             # MF Remote 入口exposes ./AdminApp
   │  ├─ login/page.tsx            # 登录页standalone mock 登录)
   │  ├─ admin/
   │  │  ├─ layout.tsx             # admin 路由组 layoutProvider 链 + AuthGuard + AdminShell
   │  │  ├─ dashboard/page.tsx     # 管理仪表盘
   │  │  ├─ users/page.tsx         # 用户管理
   │  │  ├─ roles/page.tsx         # 角色权限
   │  │  ├─ permissions/page.tsx   # 权限点管理
   │  │  ├─ viewports/page.tsx     # 视口配置(@dnd-kit 拖拽)
   │  │  ├─ organization/page.tsx  # 组织管理
   │  │  ├─ system/page.tsx        # 学校设置
   │  │  ├─ classes/page.tsx       # 班级管理
   │  │  ├─ teachers/page.tsx      # 教师管理
   │  │  ├─ students/page.tsx      # 学生管理
   │  │  └─ audit-logs/page.tsx    # 审计日志CSV 导出)
   │  └─ api/
   │     ├─ health/route.ts        # Liveness 检查
   │     └─ ready/route.ts         # Readiness 检查
   ├─ components/
   │  ├─ ui.tsx                    # 通用 UIPaperCard/Button/Input/Select/Badge/Table/Pagination
   │  ├─ admin-shell.tsx           # AdminShell左栏 11 项导航 + 主内容 + 跳过链接)
   │  ├─ user-management-table.tsx # 用户管理表格
   │  ├─ user-form-modal.tsx       # 用户表单弹窗
   │  ├─ role-permission-matrix.tsx# 角色权限矩阵
   │  ├─ organization-tree.tsx     # 组织树A11y treeitem
   │  ├─ notification-panel.tsx    # 通知面板WebSocket
   │  ├─ msw-initializer.tsx       # MSW 初始化
   │  └─ web-vitals-initializer.tsx# Web Vitals 初始化
   ├─ hooks/
   │  ├─ use-graphql.ts            # useGraphQuery + useGraphMutation
   │  ├─ use-users.ts              # 用户 CRUD
   │  ├─ use-roles.ts              # 角色 CRUD
   │  ├─ use-permissions.ts        # 权限点查询
   │  ├─ use-viewports.ts          # 视口配置
   │  ├─ use-organization.ts       # 组织树
   │  ├─ use-classes.ts            # 班级
   │  ├─ use-teachers.ts           # 教师
   │  ├─ use-students.ts           # 学生
   │  ├─ use-audit-logs.ts         # 审计日志 + CSV 导出
   │  ├─ use-dashboard.ts          # 仪表盘
   │  ├─ use-system-settings.ts    # 学校设置
   │  └─ use-websocket.ts          # WebSocket 实时通知
   ├─ providers/
   │  ├─ graphql-provider.tsx      # GraphQLProviderstandalone 自建 urql client
   │  ├─ auth-provider.tsx         # AuthProvider + useAuth + usePermission
   │  └─ toast-provider.tsx        # ToastProvider + useToast
   ├─ lib/
   │  ├─ graphql-client.ts         # urql client + 18 个 GraphQL operations
   │  ├─ auth.ts                   # 认证工具
   │  ├─ permissions.ts            # 权限常量ADMIN_ + IAM_
   │  ├─ i18n.ts                   # 轻量 i18n
   │  └─ web-vitals.ts             # Web Vitals 采集
   ├─ types/
   │  └─ view-models.ts            # 视图模型类型定义
   └─ mocks/
      ├─ browser.ts                # MSW Browser Worker
      ├─ server.ts                 # MSW Node Servervitest
      ├─ fixtures.ts               # mock 数据库
      └─ handlers.ts               # MSW handlers18 GraphQL + login

质量校验

  • pnpm run typecheck 通过0 errors
  • pnpm run lint 通过0 errors

AI Agent: ai16 (admin-portal remote) Branch: admin-portal-arbitration-done-TaFkyb Coordinator: coord-ai