Files
Edu/docs/architecture/issues/contracts/admin-portal_contract.md

188 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# admin-portal 对接契约
> 负责人ai16
> 关联:[matrix.md](./matrix.md)、[coord.md](./coord.md)、[ai-allocation.md §5 ai16](../../ai-allocation.md)、[iam.proto](../../../packages/shared-proto/proto/iam.proto)、[events.proto](../../../packages/shared-proto/proto/events.proto)
> 说明:本契约基于 GraphQLARB-001 admin 命名空间)+ 端口 4003 + ai16 归属,作为 01/02 文档修订基准(见 [objections/admin-portal_issue.md](../objections/admin-portal_issue.md) ISSUE-001~006
---
## §1 我提供什么(对外接口)
### 1.1 gRPC 接口
无。admin-portal 是前端微前端 Remote不提供 gRPC。
### 1.2 前端路由MF Remote 暴露给 Shell 动态加载)
> admin-portal 是前端,**不对外提供 HTTP 端点**。此处列出的是 admin-portal 在 Shell 路由树 `/admin/*` 下注册的前端页面路由,由 Shell 动态 import admin Remote 加载。
| 路由 | 页面 | 权限点 | 数据范围 |
| ------------------- | ---------------- | ---------------------- | --------------- |
| `/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` | 组织管理 | `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 |
> 权限点使用 `ADMIN_` / `IAM_` / `ORG_` 前缀ai-allocation §5admin 权限点 `ADMIN_` 前缀)。`ADMIN_*` 常量由 coord 维护于 `packages/contracts/src/permissions.ts`,前端不硬编码。
### 1.3 GraphQL schema
不适用。admin-portal **消费** teacher-bff GraphQL admin 命名空间,自身不提供 schema。
### 1.4 Kafka 事件发布
无。前端不发布 Kafka 事件。
### 1.5 错误码前缀
无(前端不定义错误码前缀,透传 BFF/网关错误码)。消费的错误码前缀见 §2.5。
### 1.6 微前端架构
| 角色 | 说明 |
| ---- | ---- |
| MF Remote | admin-portal 是微前端远程模块,挂载到 teacher-portal Shell |
| Remote 名称 | `admin_app`Shell `remotes` 中引用为 `admin: 'admin_app@http://localhost:4003/_next/static/chunks/remoteEntry.js'` |
| 暴露模块 | `./AdminApp`(管理后台应用入口,供 Shell 动态 import |
| MF 配置位置 | `apps/admin-portal/next.config.js`NextFederationPlugin对齐 ARB-002 §2.2 配置风格) |
| sharedsingleton | react / react-dom / urql / graphql / @edu/ui-tokens / @edu/ui-components / @edu/hooks / @edu/contracts |
| 复用 Shell 暴露 | `GraphQLProvider` / `AppShell` / `useAuth` / `usePermission` / `useGraphQLClient` / `ErrorBoundary` / `RequirePermission`ARB-002 §2.2 |
> admin-portal **不暴露共享组件给 Shell**(共享组件由 Shell 统一暴露,对齐 ARB-002。admin 特有组件UserManagementTable / RolePermissionMatrix / ViewportConfigEditor仅 admin-portal 内部使用。
### 1.7 i18n 命名空间
| 命名空间 | 用途 |
| -------- | ---- |
| `admin.*` | 管理端 UI 文案(导航/按钮/表单标签等) |
| `iam.error.*` | iam 服务错误码 i18n透传 |
| `bff.error.*` | teacher-bff 错误码 i18n透传 |
| `gateway.error.*` | api-gateway 错误码 i18n透传 |
| `network.error.*` | 前端网络层错误 i18n |
---
## §2 我消费什么(依赖上游)
### 2.1 gRPC 调用(同步)
无。前端不直接调 gRPC。
### 2.2 Kafka 事件订阅(异步)
无。前端不直接订阅 Kafka。审计日志经 teacher-bff 聚合后通过 GraphQL `auditLogs` Query 消费链路iam → Kafka `edu.iam.audit.created`**teacher-bff 消费** → GraphQL → admin-portal
> 注:[matrix.md §4](../matrix.md) 将 admin-portal 列为 `edu.iam.audit.created` 消费方,表述不精确,已提请 coord 修正为 teacher-bff见 [objections ISSUE-007](../objections/admin-portal_issue.md))。
### 2.3 HTTP 调用
| 被调用方 | Method.Path | 用途 | mock 策略 |
| -------- | ----------- | ---- | --------- |
| api-gateway (ai01) | POST /api/admin/graphql | 管理 GraphQL 查询(经网关代理到 teacher-bff admin 命名空间) | api-gateway/teacher-bff 就绪前使用 MSW 拦截返回 mock GraphQL 响应 |
| push-gateway (ai02) | GET /ws | WebSocket 实时通知(审计告警/异常登录/系统异常) | push-gateway 就绪前使用 mock-socket 模拟 WS 推送(**ISSUE-006 待 coord 仲裁** |
> **登录不自行实现**admin-portal 复用 Shell 统一登录入口 `/login`ARB-002 §2.3:登录页 P2 不走 MFShell 独占)。管理员登录后按 admin 角色重定向到 `/admin/dashboard`。开发期 mock 登录由 Shell 的 MSW handler 提供admin 角色 JWT + permissions=["*"])。
### 2.4 GraphQL 查询域(经 api-gateway 代理到 teacher-bff admin 命名空间)
> 依赖 teacher-bff admin 命名空间 schemaARB-001**ISSUE-005 待 ai03 补齐**)。以下为 admin-portal 消费的 Query/Mutation 清单,作为 ai03 补齐 schema 的输入。
| Query/Mutation | 类型 | 用途 | mock 策略 |
| -------------- | ---- | ---- | --------- |
| `currentUser` | Query | 当前管理员信息 | MSW 返回固定管理员admin 角色) |
| `adminUsers` | Query | 用户列表(含筛选/分页) | MSW 返回固定 50 个用户 |
| `adminUser(id)` | Query | 用户详情 | MSW 返回对应用户 |
| `createUser` / `updateUser` / `deleteUser` / `toggleUserStatus` | Mutation | 用户 CRUD | MSW 返回 CRUD success |
| `adminRoles` | Query | 角色列表(含权限) | MSW 返回固定 5 个角色 + 权限矩阵 |
| `createRole` / `updateRolePermissions` | Mutation | 角色 CRUD + 权限矩阵 | MSW 返回 success |
| `adminPermissions` | Query | 全量权限点(按 resource 分组) | MSW 返回固定权限矩阵 |
| `adminViewports(scope)` | Query | 视口配置列表 | MSW 返回固定 7 个视口 |
| `updateViewport` | Mutation | 视口配置更新 | MSW 返回 success |
| `adminOrganization(parentId)` | Query | 组织树 | MSW 返回固定 school/grade/class 树 |
| `adminClasses` | Query | 班级管理(全局) | MSW 返回固定 20 个班级 |
| `adminTeachers` | Query | 教师管理 | MSW 返回固定 50 个教师 |
| `adminStudents` | Query | 学生管理 | MSW 返回固定 1200 个学生 |
| `auditLogs(filter)` | Query | 审计日志(聚合 iam AuditEvent | MSW 返回固定 100 条审计日志 |
| `adminDashboard` | Query | 管理员仪表盘聚合 | MSW 返回固定仪表盘total_teachers=50, total_students=1200, school_avg_score=80.0 |
### 2.5 消费的错误码前缀(前端 i18n 路由)
| 前缀 | 来源服务 | i18n key 模式 |
| ---- | -------- | ------------- |
| `IAM_` | iam | `iam.error.{{code}}` |
| `BFF_TEACHER_` | teacher-bff | `bff.error.{{code}}` |
| `GW_` | api-gateway | `gateway.error.{{code}}` |
| `NETWORK_` | 前端网络层 | `network.error.{{code}}` |
---
## §3 就绪信号
### 3.1 我依赖的上游就绪标志
- [ ] api-gateway HTTP :8080 启用ai01—— 前端请求入口 + admin 角色校验
- [ ] teacher-portal Shell MF exposes/shared 就绪ai13ARB-002—— Remote 挂载前提
- [ ] teacher-bff GraphQL :3003 启用 + **admin 命名空间 schema 就绪**ai03—— **ISSUE-005 待 ai03 补齐**
- [ ] iam gRPC 50052 启用ai06—— 用户/角色/审计日志数据来源
- [ ] `edu.iam.audit.created` topic 有事件发布ai06—— 审计日志来源(经 teacher-bff 消费)
- [ ] push-gateway WebSocket :8081/ws 启用ai02—— 实时通知(**ISSUE-006 待 coord 仲裁**
- [ ] `packages/contracts` admin 权限点 `ADMIN_*` 常量就绪coord
> adminDashboard 的数据聚合由 teacher-bff 完成teacher-bff 内部聚合 iam + core-edu + data-ana。admin-portal **不直连 data-ana / core-edu gRPC**,统一经 teacher-bff GraphQL。原 contract 误列 data-ana gRPC 50055 为直接依赖,已修正。
### 3.2 我的就绪标志(供下游消费)
- [ ] admin-portal dev server :4003 启用
- [ ] MF Remote 可被 AppShell 加载(暴露 `./AdminApp` 模块)
- [ ] 独立壳渲染(首页 + 导航 + 路由守卫 + admin 角色校验)
- [ ] 登录流程可用(复用 Shell `/login`admin 角色校验后重定向 `/admin/dashboard`
- [ ] GraphQL 查询可执行currentUser / adminDashboard / auditLogs 返回数据)
- [ ] 用户/角色 CRUD 可执行createUser / updateRolePermissions
- [ ] WebSocket 通知可接收
---
## §4 Mock 策略
### 4.1 我提供的 mock
admin-portal 是前端,无下游消费方。但对开发体验提供:
- **Storybook**:各组件独立 story含权限矩阵编辑器、审计日志表格等复杂组件
- **MSW handlers**`apps/admin-portal/src/mocks/handlers.ts`,拦截所有 GraphQL/HTTP 请求
### 4.2 我消费的 mock
在真实上游就绪前admin-portal 使用以下 mock
- **HTTP/GraphQL mock**:使用 MSW 拦截所有请求
- POST /api/admin/graphql → 按 operationName 返回对应 mock 响应(与 teacher-bff admin namespace mock 数据一致)
- auditLogs mock 返回固定 100 条审计日志(含 action: create/update/delete/login/logout/permission_change
- adminDashboard mock 返回固定全校统计仪表盘
- 所有 mock 响应定义在 `apps/admin-portal/src/mocks/fixtures/*.json`
- **WebSocket mock**:使用 mock-socket 库
- 连接后每 30 秒推送 1 条 mock 系统通知(审计告警/异常登录)
- **JWT mock**:使用固定 mock JWTadmin 角色permissions=["*"]),由 Shell MSW handler 写入 httpOnly cookie复用 Shell 登录 mock
- **权限矩阵 mock**:内置固定 5 个角色 + 完整权限矩阵teacher/student/parent/admin/super_admin
- **环境切换**:通过 `NEXT_PUBLIC_API_MOCKING=enabled` 环境变量控制,上游就绪后设为 `disabled`
---
## §5 跨模块契约确认清单(需对应 AI 确认)
| 契约 | 提供方 | 当前状态 |
| ---- | ------ | -------- |
| teacher-bff admin 命名空间 schema§2.4 全部 Query/Mutation | ai03 | ⚠️ 待补齐ISSUE-005 |
| Shell 暴露 GraphQLProvider / useGraphQLClient / AppShell / useAuth / usePermission | ai13 | ⏳ P2 交付ARB-002 |
| iam 用户/角色/权限/视口 CRUD gRPC + AuditEvent Kafka | ai06 | ⏳ P2.1 |
| api-gateway /api/admin/graphql 代理路由 + admin 角色校验 | ai01 | ⏳ |
| push-gateway GET /wsadmin-portal 实时通知) | ai02 | ⚠️ 待 coord 仲裁ISSUE-006 |
| `packages/contracts` ADMIN_* 权限点常量 | coord | ⏳ |