# 架构影响地图(微服务版)
> 版本:2.0
> 日期:2026-07-14
> 状态:实施状态同步(基于代码现状校准)
> 适用范围:Edu 微服务架构(DDD + EDA + CQRS)
> 关联文档:
>
> - [理想蓝图](./0010_architecture.md)
> - [项目规则](../../.trae/rules/project_rules.md)
> - [路线图](./roadmap/README.md)
> - [端口分配唯一源](../../infra/port-allocation.md)
> - [P6 附录](./004-p6-addendum.md)
> **v2.0 变更摘要**:基于代码现状(截至 2026-07-14)全面校准服务清单、模块边界、依赖关系、Kafka topic、可观测性栈、BFF 实现细节;新增 §15 实施状态索引。
---
## 目录
1. [项目概述](#1-项目概述)
2. [技术栈](#2-技术栈)
3. [分层架构](#3-分层架构)
4. [服务依赖图](#4-服务依赖图)
5. [认证与权限](#5-认证与权限)
6. [数据访问与缓存](#6-数据访问与缓存)
7. [事件驱动架构](#7-事件驱动架构)
8. [跨服务协作](#8-跨服务协作)
9. [核心业务流程](#9-核心业务流程)
10. [可观测性](#10-可观测性)
11. [契约与 API 架构](#11-契约与-api-架构)
12. [架构约束](#12-架构约束)
13. [ADR 记录](#13-adr-记录)
14. [附录:6 阶段路线图](#14-附录6-阶段路线图)
15. [实施状态索引(v2.0 新增)](#15-实施状态索引v20-新增)
---
## 1. 项目概述
### 1.1a 技术分层视角(系统边界)
> 本图展示**部署分层结构**(自上而下:用户 → 微前端 → 网关 → BFF → 业务服务 → 总线 → 数据)。
> 用户层按"使用场景域"标注,BFF 层按场景域分(不是按角色分)。业务领域视角见 [1.1b](#11b-业务领域视角)。
> 端口标注见 [infra/port-allocation.md](../../infra/port-allocation.md)(唯一源)。
```mermaid
graph TB
subgraph Users["用户层(场景域用户)"]
Teacher["教学场景域用户
(教师 / 教导主任 / 教研组长 共用)"]
Student["学习场景域用户
(学生)"]
Parent["家长场景域用户
(家长)"]
Admin["管理场景域用户
(系统管理员 / 校管理员)"]
end
subgraph MFE["微前端层(Module Federation)
Next.js 15 + standalone"]
TeacherPortal["teacher-portal :4000
Shell 宿主 + 教学场景域"]
StudentPortal["student-portal :4001
Remote"]
ParentPortal["parent-portal :4002
Remote(被 teacher-portal 加载)"]
AdminPortal["admin-portal :4003
Remote"]
end
subgraph PortalShell["Portal Shell 层(规划中)
详见 [0020 Portal Shell 架构](./0020_portal_shell_architecture.md)"]
PortalShellApp["portal-shell :4010
Modular Monolith + Micro-kernel
取代 MF 微前端,单服务部署"]
end
subgraph Gateway["网关层(Go 1.25 / Gin)"]
APIGateway["api-gateway :8080
JWT RS256 + JWKS + 限流 + 熔断"]
PushGateway["push-gateway :8081
WebSocket + Redis Pub/Sub
(gRPC 豁免,HTTP /internal/*)"]
end
subgraph BFF["BFF 聚合层(NestJS / GraphQL Yoga)
按使用场景域分 BFF"]
TeacherBFF["teacher-bff :3003
Teacher + Admin Resolvers
6 下游 gRPC 客户端"]
StudentBFF["student-bff :3009
Cache + CircuitBreaker + Event"]
ParentBFF["parent-bff :3010
Aggregation + Kafka 订阅"]
end
subgraph Services["业务微服务(NestJS + FastAPI)"]
IAM["iam :3002 / gRPC :50052
5 Controller + Outbox"]
CoreEdu["core-edu :3004 / gRPC :50053
10 模块(含合并的 classes)"]
Content["content :3005 / gRPC :50054
7 模块 + Neo4j + ES sync"]
DataAna["data-ana :3006 / gRPC :50055
FastAPI + CDC consumer"]
Msg["msg :3007 / gRPC :50056
4 模块 + 4 渠道 + Kafka 16 事件"]
AI["ai :3008 / gRPC :50058
FastAPI + LLM Failover + Workflow"]
end
subgraph Bus["事件总线"]
Kafka[("Kafka
双 listener 29092/9092")]
Debezium["Debezium Connect 2.7
CDC MySQL → Kafka"]
end
subgraph Data["数据层"]
MySQL[("MySQL 8.0
每服务独占 schema")]
Redis[("Redis 7
缓存/会话/Pub/Sub")]
ClickHouse[("ClickHouse 24.3
读模型宽表")]
Neo4j[("Neo4j 5.20
知识图谱")]
ES[("Elasticsearch 8.13
题库检索")]
end
Teacher --> TeacherPortal
Student --> StudentPortal
Parent --> ParentPortal
Admin --> AdminPortal
TeacherPortal --> APIGateway
StudentPortal --> APIGateway
ParentPortal --> APIGateway
AdminPortal --> APIGateway
TeacherPortal -.MF Remote 加载.-> ParentPortal
TeacherPortal -.WS 推送.-> PushGateway
StudentPortal -.WS 推送.-> PushGateway
ParentPortal -.WS 推送.-> PushGateway
APIGateway --> TeacherBFF
APIGateway --> StudentBFF
APIGateway --> ParentBFF
APIGateway -.admin graphql 透传.-> TeacherBFF
PushGateway -.HTTP /internal/push.-> Msg
TeacherBFF --> IAM
TeacherBFF --> CoreEdu
TeacherBFF --> Content
TeacherBFF --> DataAna
TeacherBFF --> AI
TeacherBFF --> Msg
StudentBFF --> IAM
StudentBFF --> CoreEdu
StudentBFF --> DataAna
ParentBFF --> IAM
ParentBFF --> CoreEdu
ParentBFF --> DataAna
ParentBFF --> Msg
ParentBFF -.HTTP.-> PushGateway
CoreEdu <--> Kafka
Content <--> Kafka
DataAna <--> Kafka
Msg <--> Kafka
IAM <--> Kafka
AI <--> Kafka
MySQL --> Debezium
Debezium --> Kafka
IAM --> MySQL
CoreEdu --> MySQL
Content --> MySQL
Msg --> MySQL
Content --> Neo4j
Content --> ES
DataAna --> ClickHouse
AI --> ES
IAM --> Redis
CoreEdu --> Redis
TeacherBFF --> Redis
StudentBFF --> Redis
ParentBFF --> Redis
DataAna --> Redis
AI --> Redis
PushGateway --> Redis
```
### 1.1b 业务领域视角
> 本图按 **DDD 限界上下文**展示 6 个业务领域及其依赖关系。同一服务可横跨多个领域(如 core-edu 同时承载"教学组织"与"教学核心")。
> 技术分层视角见 [1.1a](#11a-技术分层视角系统边界)。
```mermaid
graph TB
subgraph D1["D1 身份认证领域(iam 服务)"]
IAM[iam 服务]
IAM_M["5 Controller: Iam / Rbac / Audit / Jwks / IamGrpc
users / roles / permissions / refresh_tokens / sessions
totp / audit_logs / navigation_config / route_permission"]
end
subgraph D2["D2 教学组织领域(core-edu 服务)"]
ORG["core-edu 服务
classes + scheduling + leave-requests"]
ORG_M["classes / teacher-associations / subjects
schedule / leave-requests"]
end
subgraph D3["D3 教学核心领域(core-edu 服务)"]
TEACH["core-edu 服务
exams + homework + grades + attendance"]
TEACH_M["exams / exam-extensions / homework / grades
attendance / dashboard / admin / iam-consumer
(含 state machine + datascope-injector)"]
end
subgraph D4["D4 内容资源领域(content 服务)"]
CONTENT["content 服务"]
CONTENT_M["7 模块: textbooks / chapters / knowledge-points
questions / electives / lesson-plans / course-plans
Neo4j 知识图谱 + ES 题库检索 + sync worker"]
end
subgraph D5["D5 沟通通知领域(msg 服务)"]
MSG["msg 服务"]
MSG_M["4 模块: notifications / preferences / templates / announcements
4 渠道: email / sms / push / in-app
Kafka 消费 16 类事件 + Idempotency Guard"]
end
subgraph D6["D6 智能洞察领域(data-ana + ai 服务)"]
DATA["data-ana 服务"]
AI["ai 服务"]
DATA_M["FastAPI HTTP /analytics + gRPC 50055
CDC consumer + ClickHouse 宽表
analytics / dashboard / diagnostic / warnings / mastery"]
AI_M["FastAPI HTTP /v1/ai + gRPC 50058
LLM FailoverChain + Prompt Service + Quality Gate
chat / question / expression / lesson-plan / report"]
end
IAM --> ORG
IAM --> TEACH
IAM --> CONTENT
IAM --> MSG
ORG --> TEACH
TEACH --> CONTENT
TEACH --> MSG
CONTENT --> DATA
TEACH --> DATA
AI -.gRPC.-> CONTENT
AI -.gRPC.-> DATA
AI -.gRPC.-> IAM
```
**双图并存说明**:
- **1.1a 技术分层**:描述部署、流量路径、网络边界,关注"如何部署与调用"
- **1.1b 业务领域**:描述 DDD 限界上下文、聚合根、领域依赖,关注"业务边界与归属"
- 两图互补,分别服务于运维/SRE 与产品/架构视角
### 1.2 服务清单
> 端口、阶段、实施状态基于代码现状(2026-07-14)。✅ = 已落地,🚧 = 部分落地,⏳ = 规划中。
| 类别 | 服务名 | 语言/框架 | HTTP 端口 | gRPC 端口 | 限界上下文 | 业务领域 | 阶段 | 状态 |
| -------- | -------------- | -------------------------- | --------- | --------- | -------------------------------------------------------------------------- | ----------------------------- | ---- | ---- |
| 基础设施 | api-gateway | Go 1.25 (Gin) | 8080 | — | 网关(路由+鉴权+限流+熔断+CORS) | — | P1 | ✅ |
| 基础设施 | push-gateway | Go 1.25 (Gin) | 8081 | — | 推送(WS + Redis Pub/Sub + Kafka 消费) | — | P5 | ✅ |
| BFF | teacher-bff | TS (NestJS + GraphQL Yoga) | 3003 | — | 教师聚合 + Admin 命名空间聚合 | 教学场景域 | P2 | ✅ |
| BFF | student-bff | TS (NestJS + GraphQL Yoga) | 3009 | — | 学生聚合 | 学习场景域 | P3 | ✅ |
| BFF | parent-bff | TS (NestJS + GraphQL Yoga) | 3010 | — | 家长聚合 | 家长场景域 | P4 | ✅ |
| 业务 | iam | TS (NestJS) | 3002 | 50052 | 身份认证 | **D1 身份认证** | P2 | ✅ |
| 业务 | core-edu | TS (NestJS) | 3004 | 50053 | 教学核心(含原 classes) | **D2 教学组织 + D3 教学核心** | P3 | ✅ |
| 业务 | content | TS (NestJS) | 3005 | 50054 | 内容资源 | **D4 内容资源** | P4 | ✅ |
| 业务 | data-ana | Python (FastAPI) | 3006 | 50055 | 数据分析 | **D6 智能洞察** | P4 | ✅ |
| 业务 | msg | TS (NestJS) | 3007 | 50056 | 消息通知 | **D5 沟通通知** | P5 | ✅ |
| 业务 | ai | Python (FastAPI) | 3008 | 50058 | AI 网关 | **D6 智能洞察** | P5 | ✅ |
| 微前端 | teacher-portal | TS (Next.js 15) | 4000 | — | 教师端(MF Shell) | 教学场景域 | P2 | ✅ |
| 微前端 | student-portal | TS (Next.js 15) | 4001 | — | 学生端(MF Remote) | 学习场景域 | P3 | ✅ |
| 微前端 | parent-portal | TS (Next.js 15) | 4002 | — | 家长端(MF Remote,被 teacher-portal 加载) | 家长场景域 | P4 | ✅ |
| 微前端 | admin-portal | TS (Next.js 15) | 4003 | — | 管理端(MF Remote) | 管理场景域 | P6 | ✅ |
| 共享包 | shared-proto | protobuf + buf v2 | — | — | 跨语言契约(8 proto 文件) | — | P1 | ✅ |
| 共享包 | shared-ts | TS | — | — | TS 共享(bff / outbox) | — | P1 | ✅ |
| 共享包 | shared-go | Go | — | — | Go 共享(env / jwks / logger / tracer) | — | P1 | ✅ |
| 共享包 | shared-py | Python | — | — | Python 共享 | — | P4 | 🚧 |
| 共享包 | contracts | TS | — | — | 跨端权限点常量 | — | P3 | 🚧 |
| 共享包 | hooks | TS (React) | — | — | React Hooks(auth / permission / viewports / graphql / trace / a11y) | — | P2 | ✅ |
| 共享包 | ui-components | TS (shadcn 风格) | — | — | UI 组件库(data-table / form / modal / chart / filter-bar / status-badge) | — | P2 | ✅ |
| 共享包 | ui-tokens | TS + CSS | — | — | 设计令牌(primitive / semantic-light/dark / tailwind-theme) | — | P2 | ✅ |
> **历史服务**:classes(端口 3001)已合并入 core-edu(C1 裁决),目录保留作历史参考,不再构建部署。
### 1.3 CICD → Edu 模块映射
| CICD 模块(旧) | Edu 服务(新) | 迁移阶段 |
| ----------------------------------------- | -------------- | -------- |
| auth + users + rbac | iam | P2 |
| classes + subjects + enrollment | core-edu | P3 |
| courses + lessons + schedule + attendance | core-edu | P3 |
| assignments + grades + exams | core-edu | P3 |
| textbooks + knowledge-points | content | P4 |
| questions + grading | content | P4 |
| messaging + notifications | msg | P5 |
| analytics + dashboard + diagnostic | data-ana | P4 |
| ai + lesson-preparation | ai | P5 |
| search | content (ES) | P4 |
---
## 2. 技术栈
### 2.1 多语言技术栈矩阵
| 层级 | 语言 | 框架/版本 | 用途 |
| -------- | --------------- | ------------------------------------------------------- | -------------------------------------- |
| 网关层 | Go 1.25 | Gin + otelgin + prometheus | api-gateway、push-gateway |
| 业务服务 | TypeScript 5.6+ | NestJS 10 + Drizzle ORM | iam、core-edu、content、msg |
| 分析/AI | Python 3.12 | FastAPI + structlog + prometheus-client | data-ana、ai |
| BFF | TypeScript 5.6+ | NestJS 10 + GraphQL Yoga + DataLoader + opossum(熔断) | teacher-bff / student-bff / parent-bff |
| 微前端 | TypeScript 5.6+ | Next.js 15 + Module Federation + Tailwind + shadcn 风格 | 4 端门户 |
| 契约 | protobuf | buf v2(FILE 级 breaking) | 跨语言契约定义与生成 |
| 包管理 | — | pnpm 11 / go.work / uv workspace | 多语言 monorepo |
### 2.2 多存储矩阵
| 存储 | 版本 | 用途 | 使用服务 |
| ------------- | -------- | --------------------------------------- | ------------------------------------------------------------------------------- |
| MySQL | 8.0 | 写模型主库(每服务独占 schema) | iam、core-edu、content、msg |
| Redis | 7-alpine | 缓存、会话、限流计数、分布式锁、Pub/Sub | iam、core-edu、teacher-bff、student-bff、parent-bff、data-ana、ai、push-gateway |
| ClickHouse | 24.3 | 读模型宽表、分析聚合 | data-ana |
| Neo4j | 5.20 | 知识图谱、前置依赖 | content |
| Elasticsearch | 8.13 | 题库全文检索、消息全文检索 | content、msg |
### 2.3 基础设施矩阵
| 组件 | 版本 | 用途 |
| ---------------- | ---------------- | -------------------------------------------- |
| Kafka | cp-kafka 7.6 | 事件总线,领域事件异步通信(双 listener) |
| Zookeeper | cp-zookeeper 7.6 | Kafka 协调 |
| Debezium Connect | 2.7 | CDC,MySQL Binlog → Kafka 实时同步 |
| OpenTelemetry | SDK + OTLP | 分布式追踪(HTTP / gRPC 自动埋点) |
| Jaeger | all-in-one 1.57 | 分布式 Trace 存储 + UI(OTLP 4317/4318) |
| Loki | 3.2.1 | 日志聚合 |
| Promtail | 3.2.1 | 日志采集 |
| Prometheus | v2.51.0 | 指标采集(--web.enable-lifecycle,15d 保留) |
| Alertmanager | v0.27.0 | 告警路由与抑制 |
| Grafana | 10.4.0 | 可观测性可视化 |
| node-exporter | v1.8.2 | 主机指标 |
| mysqld-exporter | v0.15.1 | MySQL 指标(命令行参数模式) |
| redis-exporter | v1.67.0 | Redis 指标 |
| Temporal | ⏳ 规划中 | 工作流编排(考试生命周期、AI 编排) |
| Vault | ⏳ P6 | 密钥管理 |
> **v2.0 修正**:Trace 存储实际使用 **Jaeger all-in-one**(OTLP 接收),原 v1.0 文档误写为 Tempo。当前未引入 Temporal,长流程编排暂由 ai 服务内 WorkflowStateStore(Redis)实现备课工作流。
---
## 3. 分层架构
### 3.1 六层架构
```mermaid
graph TB
subgraph L1["L1 客户端层"]
Browser[浏览器]
Mobile[移动端]
end
subgraph L2["L2 微前端层"]
MFE[Module Federation
4 端门户 Next.js 15]
end
subgraph L3["L3 网关层(Go 1.25 / Gin)"]
GW[API Gateway :8080
HTTP 反向代理 + JWT RS256 + 限流 + 熔断]
Push[Push Gateway :8081
WebSocket + Redis Pub/Sub + Kafka 消费]
end
subgraph L4["L4 BFF 聚合层(NestJS + GraphQL Yoga)"]
BFF[3 个 BFF
聚合 + DataLoader + 熔断(opossum)]
end
subgraph L5["L5 业务微服务层"]
SVC[6 业务服务
NestJS + FastAPI
DDD + CQRS + Outbox]
end
subgraph L6["L6 数据与总线层"]
DB[(MySQL / ClickHouse / Neo4j / ES)]
REDIS[(Redis 7)]
KAFKA[(Kafka + Debezium CDC)]
TEMPORAL["Temporal
⏳ 规划中"]
end
Browser --> MFE
Mobile --> MFE
MFE --> GW
MFE -.WS 推送.-> Push
GW -- HTTP 代理 --> BFF
GW -- HTTP 代理 --> SVC
BFF -- gRPC --> SVC
SVC --> DB
SVC --> REDIS
BFF --> REDIS
SVC <--> KAFKA
SVC -.规划中.-> TEMPORAL
Push --> REDIS
Push -.Kafka 消费.-> KAFKA
```
### 3.2 依赖方向
```
L1 客户端 → L2 微前端 → L3 网关 → L4 BFF → L5 业务服务 → L6 数据/总线
```
**严格规则**:
1. L3 网关层只做路由、鉴权、限流、熔断,**不写业务逻辑**;只做 HTTP 反向代理,不做协议转换
2. L4 BFF 层只做聚合、裁剪、协议转换(GraphQL → gRPC),**不持有业务状态**
3. L5 业务服务之间通过 gRPC(同步)或 Kafka 事件(异步)通信,**不直接访问对方数据库**
4. L6 数据层每个微服务独占自身数据库,**禁止跨库联表**
---
## 4. 服务依赖图
```mermaid
graph TB
subgraph Gateway["网关层"]
APIGW[api-gateway :8080]
PushGW[push-gateway :8081]
end
subgraph BFF["BFF 层"]
TBFF[teacher-bff :3003]
SBFF[student-bff :3009]
PBFF[parent-bff :3010]
end
subgraph Services["业务服务"]
IAM[iam :3002]
CoreEdu[core-edu :3004]
Content[content :3005]
DataAna[data-ana :3006]
Msg[msg :3007]
AI[ai :3008]
end
subgraph Shared["共享包"]
Proto[shared-proto
8 proto]
SharedTS[shared-ts
bff/outbox]
SharedGo[shared-go
env/jwks/logger/tracer]
SharedPy[shared-py]
Contracts[contracts
权限点]
Hooks[hooks
React Hooks]
UIComps[ui-components]
UITokens[ui-tokens]
end
%% Gateway → BFF(HTTP 反向代理 + 路径重写)
APIGW -- HTTP 代理 --> TBFF
APIGW -- HTTP 代理 --> SBFF
APIGW -- HTTP 代理 --> PBFF
APIGW -. /api/admin/graphql 透传 .-> TBFF
APIGW -- HTTP 代理 --> IAM
APIGW -- HTTP 代理 --> CoreEdu
APIGW -- HTTP 代理 --> Content
APIGW -- HTTP 代理 --> Msg
APIGW -- HTTP 代理 --> AI
APIGW -- HTTP 代理 --> DataAna
PushGW -. HTTP /internal/push .-> Msg
PushGW -. Kafka edu.notify.notification.sent .-> Msg
%% BFF → 业务服务(gRPC)
TBFF -- gRPC --> IAM
TBFF -- gRPC --> CoreEdu
TBFF -- gRPC --> Content
TBFF -- gRPC --> DataAna
TBFF -- gRPC --> AI
TBFF -- gRPC --> Msg
SBFF -- gRPC --> IAM
SBFF -- gRPC --> CoreEdu
SBFF -- gRPC --> DataAna
SBFF -. Kafka 事件 .-> PushGW
PBFF -- gRPC --> IAM
PBFF -- gRPC --> CoreEdu
PBFF -- gRPC --> DataAna
PBFF -- gRPC --> Msg
PBFF -. HTTP .-> PushGW
PBFF -. Kafka 订阅 .-> CoreEdu
PBFF -. Kafka 订阅 .-> IAM
%% 业务服务间事件
CoreEdu -. Kafka 事件 .-> Content
CoreEdu -. Kafka 事件 .-> DataAna
CoreEdu -. Kafka 事件 .-> Msg
Content -. Kafka 事件 .-> DataAna
IAM -. Kafka 事件 .-> CoreEdu
IAM -. Kafka 事件 .-> Msg
AI -. gRPC .-> Content
AI -. gRPC .-> DataAna
AI -. gRPC .-> IAM
DataAna -. Kafka 事件 .-> CoreEdu
DataAna -. Kafka 事件 .-> Msg
%% 共享包依赖
IAM --> Proto
CoreEdu --> Proto
Content --> Proto
DataAna --> Proto
Msg --> Proto
AI --> Proto
APIGW --> SharedGo
PushGW --> SharedGo
IAM --> SharedTS
CoreEdu --> SharedTS
Content --> SharedTS
Msg --> SharedTS
TBFF --> SharedTS
SBFF --> SharedTS
PBFF --> SharedTS
```
### 4.1 服务间通信矩阵
| 调用方 → 被调用方 | 协议 | 场景 |
| ------------------------- | ---------------- | ------------------------------------------ |
| api-gateway → BFF | HTTP 反向代理 | 路由分发 + 剥离 `/api/v1/{bff}` 前缀 |
| api-gateway → 业务服务 | HTTP 反向代理 | 剥离 `/api` 前缀,保留 `/v1/{domain}/*` |
| api-gateway → teacher-bff | HTTP 透传 | `/api/admin/graphql` → `/graphql`(admin) |
| BFF → 业务服务 | gRPC | 同步查询聚合 + DataLoader 批量去重 |
| push-gateway → msg | HTTP /internal/* | msg 主动推送(X-Internal-Key 鉴权) |
| push-gateway → msg | Kafka 消费 | 消费 `edu.notify.notification.sent` |
| parent-bff → push-gateway | HTTP | 触发家长端推送 |
| CoreEdu → Content | Kafka 事件 | 教学内容变更通知 |
| CoreEdu → DataAna | Kafka 事件 | 学情数据投递(9 类事件) |
| CoreEdu → Msg | Kafka 事件 | 通知触发(考试/作业/成绩/考勤) |
| IAM → CoreEdu | Kafka 事件 | 用户变更同步(6 类事件) |
| IAM → Msg | Kafka 事件 | 用户/角色变更通知(6 类事件) |
| Content → DataAna | Kafka 事件 | 内容发布同步 |
| DataAna → CoreEdu | Kafka 事件 | 掌握度更新 → 推荐练习 |
| DataAna → Msg | Kafka 事件 | 掌握度预警触发 |
| AI → Content | gRPC | 题库查询 / 知识点查询 |
| AI → DataAna | gRPC | 学情数据查询 |
| AI → IAM | gRPC | 用户信息查询 |
| AI → Kafka | Kafka 生产 | AI 用量事件发布(`edu.ai.usage.*`) |
### 4.2 BFF 下游客户端矩阵
> 所有 BFF 下游客户端统一抽象(B8 裁决):每个客户端有 `gRPC` + `mock` 两个实现,未配置 gRPC target 时自动降级为 mock。
| BFF | 下游客户端(gRPC :port) |
| ----------- | ---------------------------------------------------------------------------------------------------- |
| teacher-bff | iam (:50052) / core-edu (:50053) / content (:50054) / data-ana (:50055) / msg (:50056) / ai (:50058) |
| student-bff | iam / core-edu / data-ana |
| parent-bff | iam / core-edu / data-ana / msg / push-gateway (HTTP) |
---
## 5. 认证与权限
### 5.1 JWT RS256 认证流程
> 实施细节:api-gateway 通过 JWKS Fetcher(shared-go/jwks)缓存 RS256 公钥校验 JWT;
> 校验通过后注入 `x-user-id` / `x-user-roles` / `x-user-data-scope` / `x-request-id` 头部,HTTP 反向代理到下游服务;
> 下游服务(NestJS)通过 `AuthMiddleware` 解析头部、`PermissionGuard`(APP_GUARD)做权限校验。
> DEV_MODE=true 时跳过 JWT 校验,接受 `dev-token`。
```mermaid
sequenceDiagram
participant U as 用户
participant GW as API Gateway (Go)
participant IAM as iam 服务
participant SVC as 下游服务 (NestJS / FastAPI)
rect rgb(240, 248, 255)
Note over U,IAM: 阶段 1: 登录签发
U->>GW: POST /api/v1/iam/login {username, password}
GW->>IAM: HTTP 反向代理(无鉴权路由)
IAM->>IAM: bcrypt 校验 + 查询权限 (PermissionCacheService)
IAM->>IAM: 生成 JWT(RS256 私钥签发)+ refresh_token
IAM->>IAM: 写 iam_outbox(USER_EVENTS)
IAM-->>GW: {accessToken, refreshToken, userInfo}
GW-->>U: 200 Set-Cookie httpOnly + ActionState 信封
end
rect rgb(240, 255, 240)
Note over U,SVC: 阶段 2: 请求鉴权
U->>GW: GET /api/v1/classes + Authorization: Bearer
GW->>GW: JWKS Fetcher 取 RS256 公钥
GW->>GW: 校验签名 + exp/iss/aud
GW->>GW: 提取 userId/roles/dataScope
GW->>SVC: HTTP 代理 + 注入 x-user-* 头部
SVC->>SVC: AuthMiddleware 解析头部
SVC->>SVC: PermissionGuard (APP_GUARD) 校验权限
SVC->>SVC: DataScopeInjector 注入 WHERE 条件
SVC-->>GW: ActionState 响应
GW-->>U: 200 响应
end
```
### 5.2 三层角色模型
| 层级 | 来源 | 示例 | 优先级 |
| -------- | ------------- | ------------------------------- | ------ |
| 系统角色 | 系统预设 | admin、teacher、student、parent | 最高 |
| 组织角色 | 学校/班级分配 | 年级组长、班主任、学科组长 | 中 |
| 临时角色 | 临时授权 | 代课教师、临时代理 | 最低 |
**规则**:权限取三层角色权限的并集,拒绝权限取交集(任一层拒绝则拒绝)。
### 5.3 DataScope 6 级数据范围
| 级别 | 名称 | 数据范围 | 典型角色 |
| ---- | -------- | ---------- | ------------ |
| L0 | SELF | 仅本人数据 | 学生、家长 |
| L1 | CLASS | 本班数据 | 班主任、学生 |
| L2 | GRADE | 本年级数据 | 年级组长 |
| L3 | SCHOOL | 本校数据 | 校管理员 |
| L4 | DISTRICT | 本区数据 | 区教研员 |
| L5 | ALL | 全部数据 | 系统管理员 |
**实现**:业务服务在 Repository 层根据 dataScope 级别动态注入 WHERE 条件。
### 5.4 视口四层模型
视口(Viewport)是用户在特定场景域下的可见范围。视口既可独立配置(RoleViewport 表),
也可由权限推导(permission → viewport 默认映射)。新角色只需配置权限集,视口自动推导;
需要差异化时再显式配置视口。
| 层级 | 含义 | 配置载体 | 示例 |
| ------- | ---------------- | ---------------------------------- | -------------------------------------------- |
| L1 导航 | 侧边栏菜单项 | navigation_config 表 | 教导主任看到"全校成绩分析"菜单 |
| L2 路由 | 可访问路由 | route_permission 表 + Gateway 校验 | 教导主任可访问 /admin/grade-analysis |
| L3 组件 | 页面内组件可见性 | usePermission().hasPermission() | 教导主任看到"导出全校报表"按钮 |
| L4 数据 | 数据行级过滤 | DataScope 枚举 | 教导主任 DataScope=grade_managed(管辖年级) |
**场景域 BFF 复用策略**:
按"使用场景域"分 BFF,而非按角色分。新角色复用现有 BFF,通过视口差异化。
| BFF | 场景域 | 复用角色 |
| ----------- | -------- | ------------------------ |
| Teacher BFF | 教学场景 | 教师、教导主任、教研组长 |
| Student BFF | 学习场景 | 学生 |
| Parent BFF | 家长场景 | 家长 |
| Admin BFF | 管理场景 | 系统管理员、校管理员 |
**实现**:教导主任归入 Teacher BFF + 额外管理视口(L1 导航增加管理菜单项,L4 数据范围扩大到年级)。
**iam 服务职责**:
- 认证:登录/登出/JWT/2FA
- RBAC:角色/权限/角色-权限映射 CRUD
- 视口配置:导航/路由/组件级视口配置 CRUD
- DataScope:数据范围解析(all/grade_managed/class_taught/children/owned + 自定义)
- 权限解析 API:getEffectivePermissions(userId) → {permissions, viewports, dataScope}
---
## 6. 数据访问与缓存
### 6.1 CQRS 读写分离
```mermaid
graph LR
subgraph Write["写路径"]
Cmd[Command 命令] --> App[Application Service]
App --> Domain[Domain 领域模型]
Domain --> Repo[Repository 写模型]
Repo --> mysql_w[(MySQL 主库)]
App --> Outbox[(Outbox 表
同事务)]
end
subgraph Sync["同步链路"]
Outbox --> Relay[Relay Worker]
Relay --> kafka_sync[(Kafka)]
kafka_sync --> Proj[Projection]
Proj --> ch_sync[(ClickHouse 宽表)]
Proj --> redis_sync[(Redis 缓存)]
Proj --> es_sync[(ES 索引)]
end
subgraph Read["读路径"]
Query[Query 查询] --> ReadModel[Read Model]
ReadModel --> ch_read[(ClickHouse 宽表)]
ReadModel --> redis_read[(Redis 缓存)]
ReadModel --> es_read[(ES 索引)]
end
```
### 6.2 BFF 混合读策略
```mermaid
flowchart TD
Q[BFF 收到查询请求] --> C1{Redis 命中?}
C1 -- 是 --> R1[返回缓存]
C1 -- 否 --> C2{需要聚合多服务?}
C2 -- 否 --> C3[直接 gRPC 调用单一服务]
C3 --> C4[写入 Redis]
C4 --> R2[返回]
C2 -- 是 --> C5[并行 gRPC 调用多服务]
C5 --> C6[内存聚合裁剪]
C6 --> C7[写入 Redis 5-30s 短缓存]
C7 --> R3[返回聚合结果]
```
### 6.3 缓存策略矩阵
| 数据类型 | 存储 | TTL | 失效策略 |
| ------------- | ---------- | ------- | ------------ |
| 用户会话 | Redis | 30 分钟 | 滑动过期 |
| 权限列表 | Redis | 5 分钟 | 事件驱动失效 |
| 班级/年级列表 | Redis | 5 分钟 | 事件驱动失效 |
| 教学资源详情 | Redis | 30 秒 | 短 TTL |
| BFF 聚合结果 | Redis | 5-30 秒 | 短 TTL |
| 学情宽表 | ClickHouse | 实时 | CDC 同步 |
| 题库检索 | ES | 实时 | CDC 同步 |
---
## 7. 事件驱动架构
### 7.1 Outbox + Kafka + CDC 全链路
```mermaid
graph LR
subgraph Service["业务服务"]
Cmd[Command 处理]
Domain[Domain 聚合]
Repo[Repository]
Outbox[(Outbox 表)]
end
subgraph MySQL["MySQL 主库"]
BizTable[(业务表)]
OutboxTable[(outbox 表)]
end
subgraph Relay["Relay Worker"]
Poll[轮询 outbox
每 100ms]
Publish[发布到 Kafka]
Mark[标记 processed]
end
subgraph Bus["事件总线"]
kafka_bus[(Kafka topic)]
end
subgraph Consumers["消费者"]
Proj[Projection
更新读模型]
OtherSvc[其他服务
业务订阅]
end
Cmd --> Domain
Domain --> Repo
Repo --> BizTable
Repo --> OutboxTable
OutboxTable --> Poll
Poll --> Publish
Publish --> kafka_bus
kafka_bus --> Proj
kafka_bus --> OtherSvc
Proj --> read_stores[(ClickHouse / Redis / ES)]
```
### 7.2 事件 Topic 分类
> 实际命名(基于 `services/*/src/shared/kafka/topic-map.ts` 与 `services/iam/src/config/kafka.ts`):
> 模式 `edu...`。msg 服务统一使用 `edu.notify.notification.*` 发布(ARB-013)。
| Topic | 生产者 | 消费者 | 说明 |
| -------------------------------------- | -------- | ---------------------------- | -------------------- |
| `edu.identity.user.created` | iam | core-edu (iam-consumer)、msg | 用户创建 |
| `edu.identity.user.updated` | iam | core-edu、msg | 用户更新 |
| `edu.identity.user.deleted` | iam | msg | 用户删除 |
| `edu.identity.user.role_changed` | iam | core-edu、msg | 用户角色变更 |
| `edu.identity.role.created` | iam | msg | 角色创建 |
| `edu.identity.role.updated` | iam | msg | 角色更新 |
| `edu.teaching.exam.published` | core-edu | msg | 考试发布 |
| `edu.teaching.exam.extended` | core-edu | msg | 考试延时(实时) |
| `edu.teaching.exam.force_submitted` | core-edu | msg | 考试强制交卷(实时) |
| `edu.teaching.exam.question_reordered` | core-edu | msg | 题序打乱(实时) |
| `edu.teaching.homework.assigned` | core-edu | msg | 作业布置 |
| `edu.teaching.assignment.submitted` | core-edu | data-ana、msg | 作业提交 |
| `edu.teaching.assignment.graded` | core-edu | msg | 作业批改完成 |
| `edu.teaching.grade.recorded` | core-edu | data-ana、msg | 成绩录入 |
| `edu.teaching.attendance.recorded` | core-edu | msg | 考勤记录 |
| `edu.content.question.published` | content | ai、ES sync worker | 题目发布 |
| `edu.content.textbook.updated` | content | data-ana | 教材更新 |
| `edu.insight.mastery.updated` | data-ana | core-edu、msg | 掌握度更新 |
| `edu.notify.notification.sent` | msg | push-gateway | 通知投递(驱动推送) |
| `edu.notify.notification.read` | msg | — | 通知已读 |
| `edu.notify.notification.recalled` | msg | — | 通知撤回 |
| `edu.notify.notification.failed` | msg | — | 通知投递失败 |
| `edu.notify.notification.events` | msg | — | 兜底 topic |
| `edu.ai.usage.*` | ai | (data-ana 规划中) | AI 用量事件 |
> **Outbox 表命名**:每服务独立 outbox 表(iam_outbox / core_edu_outbox / content_outbox / msg_outbox),由 shared-ts/outbox 模块统一管理。
> **必需依赖软失败标注**(ARB-015 §17.6,ISSUE-058 覆盖 ISSUE-055):
>
> - push-gateway → Redis:**软失败**(Redis 故障仅告警 + `degraded: true` + /readyz 返 200,不返 503、不触发 Pod 重启)
> - 理由:Redis 故障时单实例仍能服务本地连接(仅跨实例广播失效);重启会丢失本地连接表,加剧雪崩风险
> - ISSUE-055 必需依赖列表应排除 push-gateway → Redis
### 7.3 核心领域事件
| 事件 | 触发场景 | 消费者动作 |
| --------------------- | -------------- | ------------------------------------------------ |
| UserRegistered | 新用户注册 | CoreEdu 初始化默认班级关联;Msg 发送欢迎通知 |
| ExamPublished | 考试发布 | Msg 推送考试通知给学生;DataAna 创建考试分析骨架 |
| HomeworkSubmitted | 学生提交作业 | DataAna 记录提交行为;Msg 通知教师 |
| HomeworkGraded | 教师批改完成 | DataAna 更新掌握度;Msg 通知学生 |
| MasteryUpdated | 掌握度计算完成 | CoreEdu 推荐个性化练习;Msg 触发预警 |
| NotificationRequested | 通知请求 | Msg 投递通知到 4 渠道(email/sms/push/in-app) |
| NotificationSent | 通知投递完成 | push-gateway 通过 Kafka 消费触发 WebSocket 推送 |
---
## 8. 跨服务协作
### 8.1 同步 vs 异步决策
```mermaid
flowchart TD
Req[跨服务协作需求] --> C1{需要强一致性?}
C1 -- 是 --> C2{调用方需要立即结果?}
C2 -- 是 --> Sync[同步 gRPC 调用]
C2 -- 否 --> Saga[Saga 编排
Temporal]
C1 -- 否 --> C3{需要事件最终一致?}
C3 -- 是 --> Async[异步 Kafka 事件]
C3 -- 否 --> C4{仅查询读取?}
C4 -- 是 --> Read[读模型冗余]
C4 -- 否 --> Sync
```
### 8.2 BFF 同步聚合
```mermaid
sequenceDiagram
participant U as 教师端
participant BFF as teacher-bff
participant IAM as iam
participant CoreEdu as core-edu
participant DataAna as data-ana
U->>BFF: 查询班级仪表盘
BFF->>BFF: 解析 token 获取 userId
par 并行查询
BFF->>IAM: gRPC GetUser(userId)
IAM-->>BFF: 用户信息
and
BFF->>CoreEdu: gRPC GetClassesByTeacher(userId)
CoreEdu-->>BFF: 班级列表
and
BFF->>DataAna: gRPC GetTeacherDashboardStats(userId)
DataAna-->>BFF: 统计数据
end
BFF->>BFF: 内存聚合裁剪
BFF-->>U: 仪表盘聚合数据
```
### 8.3 异步事件闭环
```mermaid
flowchart LR
A[教师录入成绩] --> B[CoreEdu 写入 MySQL + Outbox]
B --> C[Outbox Relay 发布事件]
C --> D[teaching.grade.recorded]
D --> E[DataAna 消费更新掌握度]
D --> F[Msg 消费通知学生]
E --> G[insight.mastery.updated]
G --> H[CoreEdu 消费推荐练习]
G --> I[Msg 消费掌握度预警]
```
### 8.4 Temporal 工作流编排
```mermaid
flowchart TD
Start[考试发布] --> A1[Activity: 创建考试实例]
A1 --> A2[Activity: 通知学生]
A2 --> A3[Activity: 等待作答窗口]
A3 --> A4[Activity: 收集提交]
A4 --> C1{是否全部提交?}
C1 -- 否 --> A5[Activity: 自动提交未答]
C1 -- 是 --> A6[Activity: 批改]
A5 --> A6
A6 --> A7[Activity: 发布成绩]
A7 --> A8[Activity: 生成分析]
A8 --> End[工作流完成]
```
---
## 9. 核心业务流程
### 9.1 考试生命周期
```mermaid
sequenceDiagram
participant T as 教师
participant BFF as teacher-bff
participant Core as core-edu
participant Msg as msg
participant DA as data-ana
participant S as 学生
rect rgb(240, 248, 255)
Note over T,Core: 阶段 1: 创建发布
T->>BFF: 创建考试
BFF->>Core: gRPC CreateExam
Core->>Core: 写入 MySQL + Outbox
Core-->>BFF: examId
BFF-->>T: 创建成功
Core->>Msg: ExamPublished 事件
Msg->>S: 推送考试通知
end
rect rgb(240, 255, 240)
Note over S,Core: 阶段 2: 作答提交
S->>BFF: 提交答卷
BFF->>Core: gRPC SubmitExam
Core->>Core: 写入答卷 + Outbox
Core-->>BFF: 提交成功
Core->>DA: ExamSubmitted 事件
DA->>DA: 记录提交行为
end
rect rgb(255, 240, 245)
Note over T,DA: 阶段 3: 批改出分
T->>BFF: 批改答卷
BFF->>Core: gRPC GradeExam
Core->>Core: 写入成绩 + Outbox
Core-->>BFF: 批改完成
Core->>DA: GradeRecorded 事件
DA->>DA: 更新掌握度
Core->>Msg: GradeRecorded 事件
Msg->>S: 推送成绩通知
end
```
### 9.2 高并发提交
```mermaid
flowchart TD
S[学生提交] --> GW[API Gateway]
GW --> GW1{限流检查}
GW1 -- 通过 --> BFF[BFF]
GW1 -- 拒绝 --> R1[429 限流响应]
BFF --> Core[CoreEdu]
Core --> C1{Redis 分布式锁}
C1 -- 获取锁 --> C2[写入答卷]
C2 --> C3[Outbox 事件]
C3 --> C4[释放锁]
C4 --> R2[成功]
C1 -- 锁竞争 --> C5[排队等待 500ms]
C5 --> C1
C5 --> C6{超时?}
C6 -- 是 --> R3[排队中,请稍后]
```
### 9.3 AI 辅助出题
```mermaid
sequenceDiagram
participant T as 教师
participant BFF as teacher-bff
participant AI as ai 网关
participant Content as content
participant DA as data-ana
T->>BFF: 请求 AI 出题
BFF->>AI: gRPC GenerateQuestions
AI->>Content: gRPC 查询知识点
Content-->>AI: 知识点列表
AI->>DA: gRPC 查询班级学情
DA-->>AI: 学情数据
AI->>AI: LLM 调用生成题目
AI-->>BFF: 生成的题目列表
BFF-->>T: 返回题目供教师审核
T->>BFF: 确认入库
BFF->>Content: gRPC CreateQuestions
Content-->>BFF: 入库成功
```
---
## 10. 可观测性
### 10.1 三支柱可观测性
> 实际落地:Jaeger all-in-one 接收 OTLP(HTTP 4318 / gRPC 4317),Loki + Promtail 采集容器日志,Prometheus 抓取 `/metrics` 端点。
> 所有 NestJS 服务通过 `shared/observability/{logger,metrics,tracer}.ts` 注册;Go 网关通过 `shared-go/{logger,tracer}` + `otelgin`;Python 服务通过 `structlog` + `opentelemetry-instrumentation-fastapi` + `prometheus-client`。
```mermaid
graph TB
subgraph App["应用层"]
NESTJS[NestJS 服务
pino + prom-client + OTLP]
GO[Go 网关
slog + prometheus + otelgin]
PY[Python 服务
structlog + prometheus-client + OTLP]
PORTAL[Next.js portal
OTel Web + Sentry]
end
subgraph Collect["采集层"]
OTEL[OpenTelemetry SDK
OTLP exporter]
PROM[Prometheus 抓取
/metrics]
PROMTAIL[Promtail
容器日志]
end
subgraph Storage["存储层"]
LOKI[(Loki 3.2.1
日志)]
JAEGER[(Jaeger 1.57
Trace,OTLP 4317/4318)]
PROMDB[(Prometheus v2.51
指标 15d 保留)]
end
subgraph Exporters["Exporters"]
NODE[node-exporter :9100
host.docker.internal]
MYSQL[mysqld-exporter :9104]
REDIS[redis-exporter :9121]
end
subgraph Vis["可视化层"]
GRAFANA[Grafana 10.4
统一面板 :3030]
ALERT[Alertmanager v0.27
告警路由]
end
NESTJS --> OTEL
GO --> OTEL
PY --> OTEL
PORTAL -.OTLP HTTP.-> OTEL
OTEL --> JAEGER
NESTJS --> PROM
GO --> PROM
PY --> PROM
PROM --> PROMDB
PROMTAIL --> LOKI
NODE --> PROM
MYSQL --> PROM
REDIS --> PROM
LOKI --> GRAFANA
JAEGER --> GRAFANA
PROMDB --> GRAFANA
PROMDB --> ALERT
```
### 10.2 Trace 上下文传播
```mermaid
flowchart LR
A[客户端请求] --> B[API Gateway
otelgin 生成 traceId]
B --> C[BFF
继承 W3C traceparent]
C --> D[业务服务 gRPC
继承 metadata]
D --> E[Kafka 事件
traceId 写入 header]
E --> F[消费者服务
继承 traceId]
F --> G[下游存储
span 记录]
G --> H[Jaeger UI
查询链路]
```
**规则**:
- 所有跨服务调用必须透传 W3C Trace Context(HTTP `traceparent` 头 / gRPC metadata)
- Kafka 事件必须将 traceId 写入消息 header
- 日志必须包含 traceId / requestId 用于关联查询
- 关键业务操作必须创建 span(创建考试、提交作业、批改、AI 生成、通知投递等)
- 每服务暴露 `/metrics`(Prometheus 抓取)+ `/healthz`(liveness)+ `/readyz`(readiness)
### 10.3 健康检查与降级
| 服务类型 | /healthz 行为 | /readyz 行为 |
| ------------ | ------------- | ------------------------------------------------- |
| 网关层 | 进程存活即 ok | 检查下游可达性(soft-failure) |
| BFF | 进程存活即 ok | 检查 Redis + 下游 gRPC probe(6 个 probe) |
| 业务服务 | 进程存活即 ok | 检查 DB + Redis + Kafka + gRPC server |
| push-gateway | 进程存活即 ok | Redis 软失败(不返 503)+ Kafka consumer 状态 |
| data-ana | 进程存活即 ok | ClickHouse 1s 超时 + CDC lag < 1000 + Redis + iam |
---
## 11. 契约与 API 架构
### 11.1 Protobuf 契约体系
> 实际 proto 文件位于 `packages/shared-proto/proto/`,共 8 个:`ai.proto` / `analytics.proto` / `classes.proto` / `content.proto` / `core_edu.proto` / `events.proto` / `iam.proto` / `msg.proto`。
> arch.db 统计(2026-07-14):8 proto 文件 / 23 service / 305 message / 139 RPC。
> buf v2 配置:`lint STANDARD`(含 5 项 except 豁免)+ `breaking FILE` 级别。
> `buf.gen.yaml` 生成 6 套代码:protocolbuffers {go/js/python} + grpc {go/node/python},输出到 `shared-{go,ts,py}/gen/proto/`。
```mermaid
graph TB
subgraph Proto["shared-proto/proto/ (8 文件)"]
IamProto[iam.proto
IamService]
CoreEduProto[core_edu.proto
9 Service: Exam/Homework/Grade/
Attendance/Class/Schedule/
LeaveRequest/Dashboard/Admin]
ClassesProto[classes.proto
ClassService(历史保留)]
ContentProto[content.proto
Textbook/Chapter/
KnowledgeGraph/Question/
Elective/LessonPlan/CoursePlan]
MsgProto[msg.proto
Notification/Preference/
Template Service]
DataAnaProto[analytics.proto
AnalyticsService]
AiProto[ai.proto
AiService]
EventsProto[events.proto
领域事件 schema]
end
subgraph Gen["buf generate (buf v2)"]
BufGen[buf generate]
TSGen[shared-ts/gen/proto
@bufbuild/protobuf + grpc-node]
GoGen[shared-go/gen/proto
protobuf-go + grpc-go]
PyGen[shared-py/gen/proto
protobuf + grpc-python]
end
subgraph Services["消费服务"]
SvcTS[NestJS 服务
iam/core-edu/content/msg
teacher-bff/student-bff/parent-bff]
SvcGo[Go 网关
api-gateway/push-gateway]
SvcPy[Python 服务
data-ana/ai]
end
IamProto --> BufGen
CoreEduProto --> BufGen
ClassesProto --> BufGen
ContentProto --> BufGen
MsgProto --> BufGen
DataAnaProto --> BufGen
AiProto --> BufGen
EventsProto --> BufGen
BufGen --> TSGen
BufGen --> GoGen
BufGen --> PyGen
TSGen --> SvcTS
GoGen --> SvcGo
PyGen --> SvcPy
```
### 11.2 契约规则
| 规则 | 说明 |
| ---------- | ------------------------------------------------------------------------------------------------------------ |
| 包命名 | proto 包名采用 `next_edu_cloud..v1` 格式(如 `next_edu_cloud.iam.v1`、`next_edu_cloud.core_edu.v1`) |
| Topic 命名 | Kafka topic 采用 `edu...` 格式(如 `edu.identity.user.created`) |
| 版本化 | 破坏性变更必须升版本(v1 → v2),buf breaking FILE 级别 CI 强制 |
| 字段编号 | 禁止复用已删除字段编号,使用 reserved |
| 消息命名 | PascalCase |
| 字段命名 | snake_case |
| 注释 | 每个 message 和字段必须注释 |
| CI 强制 | buf lint + buf breaking 必须通过 |
| 代码生成 | `buf generate` 生成 6 套代码(go/js/python × protobuf/grpc) |
### 11.3 BFF 聚合模式
```mermaid
graph LR
subgraph Client["客户端"]
Q[GraphQL 查询]
end
subgraph BFF["BFF 层"]
Resolver[GraphQL Resolver]
DataLoader[DataLoader 批量去重]
Cache[Redis 短缓存]
end
subgraph Services["业务服务"]
S1[服务 A]
S2[服务 B]
S3[服务 C]
end
Q --> Resolver
Resolver --> Cache
Cache --> DataLoader
DataLoader --> S1
DataLoader --> S2
DataLoader --> S3
```
### 11.4 错误码前缀矩阵
> 来源:coord 仲裁 ARB-017 §19.6 / ARB-014 / ARB-015 / ARB-018 / G14 / F4
> 规则:服务名大写 + 下划线分隔,禁止子前缀(如 EXAMS_/HOMEWORK_/GRADES_ 已移除)
| 层级 | 服务 | 前缀 | 示例 | 仲裁依据 |
| ---- | ------------ | -------------- | ------------------------------------------------------------- | -------- |
| 网关 | api-gateway | `GW_` | GW_UNAUTHORIZED / GW_RATE_LIMITED | ARB-014 |
| 网关 | push-gateway | `PUSH_` | PUSH_DEVICE_NOT_FOUND / PUSH_CHANNEL_FAILED | ARB-015 |
| BFF | teacher-bff | `BFF_TEACHER_` | BFF_TEACHER_UNAUTHORIZED / BFF_TEACHER_BAD_GATEWAY | ARB-016 |
| BFF | student-bff | `BFF_STUDENT_` | BFF_STUDENT_UNAUTHORIZED / BFF_STUDENT_VALIDATION_ERROR | ARB-017 |
| BFF | parent-bff | `BFF_PARENT_` | BFF_PARENT_CHILD_NOT_BOUND / BFF_PARENT_BAD_GATEWAY | ARB-018 |
| 业务 | iam | `IAM_` | IAM_USER_NOT_FOUND / IAM_INVALID_CREDENTIALS | ARB-003 |
| 业务 | core-edu | `CORE_EDU_` | CORE_EDU_EXAM_NOT_FOUND / CORE_EDU_GRADE_NOT_FOUND | ARB-004 |
| 业务 | content | `CONTENT_` | CONTENT_QUESTION_NOT_FOUND / CONTENT_TEXTBOOK_NOT_FOUND | ARB-005 |
| 业务 | msg | `MSG_` | MSG_NOTIFICATION_NOT_FOUND / MSG_TEMPLATE_NOT_FOUND | ARB-008 |
| 业务 | data-ana | `DATA_ANA_` | DATA_ANA_DASHBOARD_UNAVAILABLE / DATA_ANA_ANALYTICS_NOT_READY | ARB-009 |
| 业务 | ai | `AI_` | AI_GENERATION_FAILED / AI_QUOTA_EXCEEDED | ARB-010 |
**前端 i18n key 映射规则**(F4 裁决):
| 服务 | i18n key 模式 | 示例 |
| ------------ | ------------------------------- | -------------------------------------- |
| api-gateway | `error.gateway.` | `error.gateway.unauthorized` |
| push-gateway | `error.push.` | `error.push.device_not_found` |
| teacher-bff | `error.bffTeacher.` | `error.bffTeacher.unauthorized` |
| student-bff | `error.bffStudent.` | `error.bffStudent.validation_error` |
| parent-bff | `error.bffParent.` | `error.bffParent.child_not_bound` |
| iam | `error.iam.` | `error.iam.user_not_found` |
| core-edu | `error.core_edu.` | `error.core_edu.exam_not_found` |
| content | `error.content.` | `error.content.question_not_found` |
| msg | `error.msg.` | `error.msg.notification_not_found` |
| data-ana | `error.data_ana.` | `error.data_ana.dashboard_unavailable` |
| ai | `error.ai.` | `error.ai.generation_failed` |
### 11.5 ActionState 信封规范
> 来源:coord 仲裁 ARB-017 §19.6
> 适用范围:所有 BFF / Gateway HTTP 响应、GraphQL response 的 errors 扩展字段
> 设计原则:统一错误信封 + 降级模式方案 B(degraded 放 error.details 子字段)
**信封结构**:
```typescript
interface ActionState {
success: boolean; // 整体成功/失败
data: T | null; // 成功时返回数据,失败时为 null
error: {
code: string; // 错误码(见 §11.4 前缀矩阵)
message: string; // 人类可读错误消息(i18n key 解析后)
details?: Record; // 附加详情(含 degraded 字段)
traceId: string; // 链路追踪 ID(X-Request-Id)
} | null; // 成功时为 null
}
```
**降级模式(方案 B)**:
- `success = true`(整体成功)
- `data` 内含 `extensions.degraded: true` 子字段
- `error` 仍为 null(非错误)
- 用于部分聚合失败场景(如 teacher-bff 聚合 iam 成功但 core-edu 失败)
**示例 1:完全成功**
```json
{
"success": true,
"data": { "userId": "u001", "name": "张老师" },
"error": null
}
```
**示例 2:完全失败**
```json
{
"success": false,
"data": null,
"error": {
"code": "BFF_TEACHER_BAD_GATEWAY",
"message": "下游服务不可用",
"details": { "downstream": "core-edu", "reason": "timeout" },
"traceId": "req-abc123"
}
}
```
**示例 3:降级模式(部分聚合成功)**
```json
{
"success": true,
"data": {
"user": { "userId": "u001", "name": "张老师" },
"classes": null,
"extensions": { "degraded": true, "failedServices": ["core-edu"] }
},
"error": null
}
```
**GraphQL errors 数组扩展**:
GraphQL 响应中,错误通过 `errors[].extensions` 携带 ActionState 字段:
```json
{
"errors": [
{
"message": "下游服务不可用",
"extensions": {
"code": "BFF_TEACHER_BAD_GATEWAY",
"details": { "downstream": "core-edu" },
"traceId": "req-abc123"
}
}
]
}
```
---
## 12. 架构约束
### 12.1 服务独立性约束
| 约束 | 说明 |
| ----------- | -------------------------------------- |
| 数据库独占 | 每个微服务独占自身数据库,禁止跨库联表 |
| 契约先行 | 所有跨服务通信必须先定义 protobuf 契约 |
| Outbox 强制 | 所有领域事件必须通过 Outbox 模式发布 |
| 幂等消费 | 所有事件消费者必须实现幂等性 |
| 单一职责 | 每个服务只负责一个限界上下文 |
| 无状态服务 | 业务服务不持有会话状态(Redis 承载) |
### 12.2 通信约束
| 场景 | 允许 | 禁止 |
| -------------------- | --------------------------------- | ------------------------ |
| 客户端 → Gateway | REST + WebSocket | 直连业务服务 |
| Gateway → BFF | HTTP 反向代理(路径重写剥离前缀) | gRPC 转换、REST 业务逻辑 |
| Gateway → 业务服务 | HTTP 反向代理(剥离 `/api` 前缀) | gRPC 转换 |
| BFF → 业务服务 | gRPC + DataLoader 批量去重 | 直接访问 DB |
| push-gateway → msg | HTTP /internal/* + Kafka 消费 | gRPC(豁免,ARB-015) |
| 业务服务之间(同步) | gRPC | REST、直接 DB |
| 业务服务之间(异步) | Kafka 事件(Outbox 模式) | 直接 producer 调用 |
| 事件发布 | Outbox 模式 | 直接 Kafka producer |
### 12.3 数据一致性约束
| 场景 | 一致性级别 | 实现 |
| ------ | ---------- | --------------------- |
| 聚合内 | 强一致 | 单事务 |
| 聚合间 | 最终一致 | Kafka 事件 |
| 服务间 | 最终一致 | Kafka 事件 / Saga |
| 读模型 | 最终一致 | Projection 异步更新 |
| 缓存 | 最终一致 | 事件驱动失效 + 短 TTL |
---
## 13. ADR 记录
| 编号 | 决策 | 原因 | 状态 |
| ------- | --------------------------------------------------- | -------------------------------------------------------------------------- | ----------------------------------------------------- |
| ADR-001 | 采用 DDD 限界上下文划分服务 | 业务边界清晰,独立演进 | 已采纳 |
| ADR-002 | 采用 NestJS 作为业务服务框架 | TS 生态成熟,装饰器 + DI 适合 DDD | 已采纳 |
| ADR-003 | 采用 Go 作为网关语言 | 高并发、低内存、适合网关场景 | 已采纳 |
| ADR-004 | 采用 Python 作为分析/AI 语言 | 数据科学/AI 生态丰富 | 已采纳 |
| ADR-005 | 采用 CQRS 读写分离 | 读多写少,读模型可独立优化 | 已采纳 |
| ADR-006 | 采用 Outbox 模式发布事件 | 保证事务与事件最终一致 | 已采纳 |
| ADR-007 | 采用 Kafka 作为事件总线 | 高吞吐、持久化、成熟生态 | 已采纳 |
| ADR-008 | 采用 Debezium CDC | 解耦 Outbox Relay,减少业务侵入 | 已采纳 |
| ADR-009 | 采用 protobuf + buf 契约先行 | 多语言契约统一、版本化、CI 强制 | 已采纳 |
| ADR-010 | 采用 JWT RS256 非对称签名 | 网关公钥校验无需共享私钥 | 已采纳 |
| ADR-011 | 采用 DataScope 6 级数据范围 | 满足 K12 多层级数据隔离 | 已采纳 |
| ADR-012 | 采用 Module Federation 微前端 | 独立部署、技术栈无关、渐进迁移 | 已采纳 |
| ADR-013 | 采用 Temporal 工作流编排 | 长流程编排、可观测、可回滚 | ⏳ 规划中(当前由 ai 内 WorkflowStateStore 临时实现) |
| ADR-014 | 采用 ClickHouse 读模型宽表 | 分析查询亚秒级响应 | 已采纳 |
| ADR-015 | api-gateway 采用 HTTP 反向代理(非 gRPC 转换) | Go 网关只做 HTTP,简化部署;下游 HTTP/gRPC 双协议 | 已采纳 |
| ADR-016 | push-gateway 豁免 gRPC | 基础设施层无流式推送场景;msg/student-bff/parent-bff 改用 HTTP /internal/* | 已采纳 |
| ADR-017 | classes 服务合并入 core-edu | 教学组织与教学核心共享聚合根边界 | 已采纳 |
| ADR-018 | BFF 统一 GraphQL Yoga + DataLoader + opossum 熔断 | 协议统一、批量去重、降级模式 B(degraded 子字段) | 已采纳 |
| ADR-019 | admin-portal GraphQL 经 teacher-bff 命名空间 | 复用 teacher-bff resolver,admin role 中间件强制隔离 | 已采纳 |
| ADR-020 | parent-portal 作为 MF Remote 被 teacher-portal 加载 | 家长入口可由教师端嵌入,统一 Shell 宿主 | 已采纳 |
| ADR-021 | Trace 存储 Jaeger 替代 Tempo | all-in-one 镜像部署简单,OTLP 原生支持 | 已采纳 |
| ADR-022 | 共享包 ui-tokens 替代原 shared-tokens 命名 | 三层令牌(primitive/semantic/tailwind-theme)实际落地 | 已采纳 |
---
## 14. 附录:6 阶段路线图
### 14.1 阶段总览
```mermaid
graph LR
P1[P1 地基
M1-M3] --> P2[P2 身份
M4-M6]
P2 --> P3[P3 核心教学
M7-M10]
P3 --> P4[P4 内容分析
M11-M13]
P4 --> P5[P5 沟通AI
M14-M16]
P5 --> P6[P6 硬化
M17-M18]
```
### 14.2 服务与阶段映射
> 状态基于代码现状(2026-07-14)。✅ 已落地 / 🚧 部分落地 / ⏳ 规划中。
| 阶段 | 周期 | 交付服务 | 退出标准 | 实际状态 |
| ----------- | ------- | ----------------------------------------------------- | ------------------------------ | -------------------------------------------------------------------------------- |
| P1 地基 | M1-M3 | api-gateway、classes(黄金模板)、shared-proto | classes 域 CRUD 端到端跑通 | ✅ 完成(classes 已合并入 core-edu) |
| P2 身份 | M4-M6 | iam、teacher-bff、teacher-portal 骨架 | 教师可登录并看到空白 Dashboard | ✅ 完成 |
| P3 核心教学 | M7-M10 | core-edu(合并 classes)、student-bff、student-portal | 考试→作答→批改→成绩全链路 | ✅ 完成(含 LeaveRequests/Dashboard/Admin/IamConsumer 扩展) |
| P4 内容分析 | M11-M13 | content、data-ana、parent-bff、parent-portal | 知识图谱查询 + 学情宽表 5s | ✅ 完成(含 7 模块 + Neo4j + ES sync + CDC consumer + 11 analytics 端点) |
| P5 沟通AI | M14-M16 | msg、push-gateway、ai | 全校广播 + AI 辅助出题 | ✅ 完成(msg 4 模块 4 渠道 + push-gateway WS + Kafka + ai 11 端点 + 备课工作流) |
| P6 硬化 | M17-M18 | admin-portal、Service Mesh | 99.9% 可用性 + 独立扩缩容 | 🚧 admin-portal 已落地;Service Mesh / Vault / 99.9% SLO 待硬化 |
> 详细规划见 [路线图目录](./roadmap/README.md)、[tech-debt](./roadmap/tech-debt.md)、[pending-features](./roadmap/pending-features.md)
---
## 15. 实施状态索引(v2.0 新增)
> 本节按服务/包罗列实际落地的模块、Controller、关键组件,作为代码现状的快速索引。
> 详细模块设计见各服务 `README.md` 与 `docs/01-understanding.md`。
### 15.1 api-gateway(Go :8080)
- **中间件链**:Recovery → otelgin → RequestID → CORS → SecurityHeaders → RequestBodyLimit(10MB) → RateLimit(100rps+20burst) → CircuitBreaker → AuthMiddleware(JWKS RS256) → Metrics
- **路由组**:
- `/healthz`、`/readyz`、`/metrics`(公开)
- `/api/v1/{classes,iam,exams,homework,grades,textbooks,chapters,knowledge-points,questions,notifications,messages,announcements,ai,analytics,dashboard}/*` → HTTP 反向代理
- `/api/v1/{teacher,student,parent}/*` → BFF 反向代理(剥离 `/api/v1/{bff}` 前缀)
- `/api/admin/graphql` → teacher-bff `/graphql`(AdminRoleMiddleware 强制)
- **关键依赖**:`shared-go/jwks`(公钥缓存)、`shared-go/env`、`shared-go/logger`、`shared-go/tracer`
### 15.2 push-gateway(Go :8081)
- **WebSocket 端点**:`/ws`(JWT RS256 via query `?token=` 或 Authorization 头)
- **内部 HTTP API**:`/internal/push`、`/internal/broadcast`、`/internal/online/:userID`(X-Internal-Key 鉴权)
- **跨实例广播**:Redis Pub/Sub(SubscribeAll + RebuildPresenceOnStartup)
- **Kafka 消费**:`edu.notify.notification.sent`(ARB-013)
- **健康检查**:`/healthz`(liveness)、`/readyz`(Redis 软失败 + Kafka consumer 状态)
- **依赖**:`hub`(in-memory connection registry)、`redisclient`、`kafkaconsumer`、`ws`、`observability`
### 15.3 iam(NestJS :3002 / gRPC :50052)
- **Controllers**:IamController、RbacController、AuditController、JwksController、IamGrpcController
- **Services**:IamService、JwksService、PermissionCacheService(Redis)、TokenBlacklistService
- **Outbox**:`iam_outbox` 表,发布到 `edu.identity.user.*` topic
- **APP_GUARD**:PermissionGuard(DB 驱动 + Redis 缓存,I3 裁决)
- **AuthMiddleware** 应用范围:`v1/iam/me`、`logout`、`change-password`、`viewports`、`permissions/effective`、`children`、`roles`、`permissions`、`users`、`audit`、`totp`
### 15.4 core-edu(NestJS :3004 / gRPC :50053)
- **业务模块(10)**:
- exams(含 exam-extensions、exam-state-machine)
- homework(含 homework-state-machine)
- grades(含 grade-calculator)
- attendance
- classes(含 teacher-associations,C1 合并自原 classes 服务)
- scheduling(含 schedule-conflict 检测)
- leave-requests(P3.13)
- dashboard
- admin
- iam-consumer(消费 IAM 6 类事件)
- **共享组件**:datascope-injector(Repository 层 WHERE 注入)、outbox(core_edu_outbox)、global-error.filter
- **gRPC 服务(9,43 RPC)**:ExamService / HomeworkService / GradeService / AttendanceService / ClassService / ScheduleService / LeaveRequestService / DashboardService / AdminService
### 15.5 content(NestJS :3005 / gRPC :50054)
- **业务模块(7)**:textbooks、chapters、knowledge-points、questions、electives、lesson-plans、course-plans
- **gRPC controllers(7)**:Textbook / Chapter / KnowledgeGraph / Question / Elective / LessonPlan / CoursePlan
- **同步 worker**:es-sync.worker(题库 ES 索引)、neo4j-sync.worker(知识图谱节点)
- **Outbox**:content_outbox,发布 `edu.content.*` 事件
- **存储**:MySQL(业务表)+ Neo4j(知识图谱)+ Elasticsearch(题库检索)
### 15.6 msg(NestJS :3007 / gRPC :50056)
- **业务模块(4)**:notifications、preferences、templates、announcements
- **gRPC controllers(3,17 RPC)**:NotificationService(9 RPC)/ NotificationPreferenceService(2 RPC)/ NotificationTemplateService(6 RPC,ARB-008 裁剪)
- **渠道(4)**:email、sms、push、in-app(channel-dispatcher 路由)
- **Kafka 消费**:16 类事件(iam 6 + core-edu 9 + data-ana 1),见 `shared/kafka/topic-map.ts`
- **Kafka 生产**:4 类 `edu.notify.notification.*` 事件 + 1 兜底 topic
- **辅助组件**:push-gateway.client(HTTP 调用 /internal/push)、idempotency.guard(Redis SETNX 去重)、Outbox(msg_outbox)
- **存储**:MySQL + Elasticsearch(消息全文检索)+ Redis(幂等性)
### 15.7 data-ana(FastAPI :3006 / gRPC :50055)
- **HTTP 端点(3 基础 + 11 业务 = 14)**:
- 基础:`/`、`/healthz`、`/readyz`
- 业务(全部 ActionState 信封):
- `/analytics/class/{class_id}/performance`
- `/analytics/student/{student_id}/{weakness,trend,errorbook,mastery}`
- `/analytics/{teacher,student,parent,admin}/dashboard`
- `/analytics/warnings` + `/analytics/warnings/trigger`
- `/analytics/class/{class_id}/mastery-distribution`
- **gRPC 服务**:AnalyticsService(18 RPC)
- **CDC 消费者**:手动 commit,lag 阈值 1000(超过 readyz 返 503)
- **/readyz 4 依赖**:ClickHouse(1s)+ CDC consumer(lag<1000)+ Redis(200ms)+ iam gRPC(2s)
- **存储**:ClickHouse(宽表)+ Redis(缓存)+ iam gRPC(用户信息)
### 15.8 ai(FastAPI :3008 / gRPC :50058)
- **HTTP 端点(11)**:
- `/healthz`、`/readyz`
- `/v1/ai/chat`(非流式)+ `/v1/ai/chat/stream`(SSE)
- `/v1/ai/generate/question` + `/v1/ai/generate/question/stream`(SSE)
- `/v1/ai/optimize/expression`
- `/v1/ai/lesson-plan/generate` + `/v1/ai/lesson-plan/status/{workflow_id}` + `/v1/ai/lesson-plan/confirm/{workflow_id}`
- `/v1/ai/generate/report`(class_summary / student_detail / exam_analysis)
- **gRPC 服务**:AiService(9 RPC)
- **核心组件**:LLM FailoverChain(4 适配器 + 熔断 + 故障切换)、PromptTemplateService(Jinja2 + YAML)、QualityGate(RuleValidator + LLMJudge)
- **用量与配额**:UsageRecorder(Redis)+ QuotaEnforcer + KafkaProducer(`edu.ai.usage.*`)
- **限流**:RateLimiter(Redis 三维度令牌桶:user/ip/school)
- **安全**:PII redactor + 输入清洗 + 输出审核
- **备课工作流**:4 步编排 + WorkflowStateStore(Redis TTL)
- **下游 gRPC 客户端**:ContentClientGrpc / DataAnaClientGrpc / IamClientGrpc(连接失败降级,不阻断启动)
### 15.9 teacher-bff(NestJS :3003 / GraphQL Yoga)
- **模块**:GraphQLModule(Teacher + Admin Resolvers,ARB-001 扁平合并)+ HealthModule + MiddlewareModule
- **下游客户端(6)**:iam / core-edu / content / data-ana / msg / ai(B8 裁决统一抽象,gRPC + mock 双实现)
- **GraphQL 端点**:`/graphql`(同时承载 teacher 与 admin 命名空间)
- **SSE 控制器**:`ai-chat-sse.controller.ts`(透传 ai 服务流式响应)
- **Health probes(6)**:iam-grpc / core-edu-grpc / content-grpc / data-ana-grpc / ai-grpc / msg-grpc + redis probe
### 15.10 student-bff(NestJS :3009 / GraphQL Yoga)
- **模块(8)**:CacheModule(Global Redis)+ DownstreamModule(Global gRPC)+ CircuitBreakerModule(Global opossum)+ HealthModule + DataLoaderModule + StudentModule(GraphQL Yoga + Resolver)+ PushGatewayModule(HTTP /internal/push)+ EventModule(Kafka 事件订阅 + push-gateway 推送)
- **下游客户端**:iam / core-edu / data-ana
### 15.11 parent-bff(NestJS :3010 / GraphQL Yoga)
- **模块**:HealthModule + GraphqlModule(Yoga /v1/graphql)+ ClientsModule(iam + core-edu + data-ana + msg + push-http)+ KafkaModule(cache-invalidation + notification-push handler)
- **聚合组件**:AggregationModule(orchestrator + fallback-strategy + child-guard + response-mapper)
- **DataLoader**:dataloader.factory + loaders(批量去重)
- **缓存**:Redis + LRU cache + cache-key.builder
### 15.12 teacher-portal(Next.js 15 :4000,MF Shell)
- **路由组**(25+ 业务页面):dashboard、classes、schedule、exams、homework、grades、attendance、analytics、knowledge-graph、lesson-plans、course-plans、textbooks、questions、notifications、students、ai-assist、ai-lesson-plan、ai-report、diagnostic、error-book、practice、leave、elective、schedule-changes、settings
- **MF Remote 加载**:ParentPortalRemote(在 teacher-portal 内嵌入家长端视图)
- **GraphQL 客户端文件**:graphql.ts(base)+ graphql-p4.ts / p5.ts / p7-admin.ts / p7-advanced.ts / p7-exams.ts / p7-grades.ts / p7-insights.ts(按阶段渐进扩展)
- **可观测性**:observability-provider(OTel Web + Sentry + web-vitals + performance-dashboard)
- **国际化**:messages/{en,zh-CN}.json
- **认证**:lib/auth.ts(cookie 迁移 + token 刷新 + cross-tab sync)
### 15.13 student-portal / parent-portal / admin-portal(Next.js 15 :4001/:4002/:4003,MF Remote)
- **student-portal**:路由组 leave + 主页;exam-types 类型;mocks/handlers + server
- **parent-portal**:login + 主页 + providers;child-store(Zustand);middleware.ts;PWA(manifest + sw.js)
- **admin-portal**:login + admin layout;hooks(use-classes/files/roles/school/students/teachers/users/graphql);lib/{auth,i18n,permissions,web-vitals}
### 15.14 共享包实施状态
| 包 | 关键导出 | 状态 |
| ------------- | --------------------------------------------------------------------------------------------------------------------------------- | ---- |
| shared-proto | 8 proto 文件 + buf.yaml + buf.gen.yaml(生成 6 套代码) | ✅ |
| shared-ts | `bff/`(logger)、`outbox/`(OutboxModule + publisher + schema + types,被 iam/core-edu/content/msg/BFF 共享) | ✅ |
| shared-go | `env/`(config.Load)、`jwks/`(Fetcher,RS256 公钥缓存)、`logger/`(slog JSON)、`tracer/`(OTLP init) | ✅ |
| shared-py | pyproject.toml(uv workspace member) | 🚧 |
| contracts | `STUDENT_PERMISSIONS` 常量(12 权限点) | 🚧 |
| hooks | use-auth / use-permission / use-viewports / use-graphql-client / use-trace-id / use-a11y-id / use-aria-live / use-api / use-toast | ✅ |
| ui-components | data-table / filter-bar / form / modal / chart / calendar / status-badge / empty / loading + utils/cn | ✅ |
| ui-tokens | primitive.css / semantic-light.css / semantic-dark.css / tailwind-theme.css / all.css + colors/shadows/spacing/typography (.ts) | ✅ |
### 15.15 部署与运维实施状态
- **本地开发**:`infra/docker-compose.yml`(基础设施)+ pnpm dev / go run / uv run
- **最小化部署**:`infra/docker-compose.minimal.yml`
- **生产部署**:`infra/docker-compose.deploy.yml`(build: 替代 image:)
- **测试部署**:`infra/docker-compose.test.yml`
- **监控栈**:`infra/docker-compose.monitoring.yml`(observability profile)
- **K8s Helm chart**:`infra/k8s/helm/`(edu-platform umbrella + 各子 chart)
- **CI/CD**:`.github/workflows/ci.yml`(quality-ts / quality-go / quality-proto / deploy,no-push 本地构建模式)
- **备份**:`infra/backup/backup-mysql.sh`(每服务独立,保留 7 天)
- **混沌工程**:`infra/chaos/experiments.yaml`
- **WAF**:`infra/security/waf-rules.conf`
- **端口分配**:`infra/port-allocation.md`(唯一源)
### 15.16 文档体系实施状态
| 路径 | 用途 |
| -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `docs/architecture/004_architecture_impact_map.md` | 本文件(架构影响地图,设计意图唯一源) |
| `docs/architecture/0010_architecture.md` | 理想蓝图(目标态) |
| `docs/architecture/004-p6-addendum.md` | P6 硬化附录 |
| `docs/architecture/roadmap/` | tech-debt / pending-features / integration-test-phase |
| `docs/architecture/runbooks/` | p6-hardening / post-p6-followup / incident-response |
| `docs/architecture/issues/` | 协调记录(coord / matrix / workline)+ contracts/ + objections/ + worklines/ |
| `docs/architecture/ai-allocation.md` | AI 模块分配 |
| `docs/architecture/ai-work-orchestration.md` | AI 工作编排 |
| `docs/architecture/coord-cross-review.md` | coord 交叉审查 |
| `docs/architecture/coord-final-decisions.md` | coord 最终裁决(ARB-001~022+) |
| `docs/architecture/president-final-rulings.md` | president 最终裁决(batch 0.9+) |
| `docs/modules//README.md` | 各服务模块文档(iam/core-edu/content/msg/data-ana/ai/api-gateway/push-gateway/classes) |
| `docs/standards/` | coding-standards / cicd-runbook / full-stack-runbook / git-workflow / local-dev-runbook / multi-ai-collaboration / ui-design-system |
| `docs/troubleshooting/known-issues.md` | 已知问题速查(索引式场景→技术映射) |
---
> **本文件 v2.0 已基于代码现状(2026-07-14)全面校准。后续代码变更须按 [项目规则 §1](../../.trae/rules/project_rules.md) 同步更新本文件 + 运行 `pnpm run arch:scan`。**