feat(p1): complete P1 foundation stage
Some checks failed
CI Go / test (push) Has been cancelled
CI Proto / lint (push) Has been cancelled
CI Python / test (push) Has been cancelled
CI TypeScript / test (push) Has been cancelled

- monorepo: pnpm workspace + go.work + pyproject.toml + commitlint/husky
- infra: docker-compose (minimal + full profiles) + init-sql + prometheus
- arch-scan: multi-language scanner skeleton (TS/Go/Python/Proto)
- shared-proto: buf v2 + classes.proto (ClassService CRUD contract)
- api-gateway: Go/Gin + JWT HS256 auth + reverse proxy + request ID
- classes: NestJS golden template (error system + observability + middleware + CRUD + tests)
- teacher-portal: Next.js + paper-feel UI design system
- CI/CD: 4 workflows (go/ts/py/proto)
- docs: migration guide + project_rules + coding-standards + git-workflow + ui-design-system + 004 + 9 module READMEs + known-issues + spec/plan migration + roadmap
This commit is contained in:
SpecialX
2026-07-07 23:39:37 +08:00
commit 2ba4250165
100 changed files with 15242 additions and 0 deletions

View File

@@ -0,0 +1,174 @@
抛开历史包袱和重构成本,如果我们站在 2026 年的上帝视角为一个支撑百万级日活、多端Web、App、小程序、高并发如全校同时交卷的 K12 教育生态系统设计企业级理想架构,那么整个系统必须走向 “领域驱动设计 (DDD) + 彻底的事件驱动 (EDA) + 读写分离 (CQRS) + 异构微服务” 的云原生架构。
以下是现代企业级最优架构的设计蓝图:
一、 现代企业级架构全景图
在这种规模下Next.js 不再充当“全栈巨石”,而是退化为纯粹的展示层 (Micro-Frontends) 和 BFF (Backend for Frontend)。
code
Mermaid
graph TB
subgraph ClientLayer["1. 多端访问层 (Micro-Frontends)"]
direction LR
MFE1[Teacher Portal]
MFE2[Student Portal]
MFE3[Parent App]
MFE4[Admin Console]
end
subgraph EdgeLayer["2. 边缘与网关层 (API Gateway & BFF)"]
WAF[WAF / CDN / 防火墙]
Gateway[全局统一网关 API Gateway<br/>Kong / APISIX / 鉴权 / 限流]
BFF1[Teacher BFF<br/>GraphQL]
BFF2[Student BFF<br/>GraphQL]
BFF3[Parent BFF<br/>GraphQL]
end
subgraph ServiceLayer["3. 领域微服务层 (Domain Services)"]
IAM[IAM 服务<br/>认证授权/RBAC]
CoreEdu[核心教学服务<br/>班级/排课/试卷/作业]
Content[教研内容服务<br/>教材/知识图谱]
DataAna[学情分析服务<br/>诊断/错题/成绩]
Msg[消息调度服务<br/>通知/短信/SSE长连接]
AI[AI 调度网关<br/>大模型接入/Prompt管理]
end
subgraph EventLayer["4. 事件驱动总线 (Event Data Platform)"]
Kafka[Kafka / Pulsar 集群<br/>统一企业级事件总线]
end
subgraph DataLayer["5. 异构存储与数据层 (Polyglot Persistence)"]
MySQL[(关系型主库<br/>分布式 MySQL/TiDB)]
Redis[(缓存/分布式锁<br/>Redis Cluster)]
ClickHouse[(分析型数据仓库<br/>ClickHouse / Doris)]
Neo4j[(图数据库<br/>Neo4j / 知识图谱)]
ES[(搜索引擎<br/>Elasticsearch)]
end
ClientLayer --> WAF
WAF --> Gateway
Gateway --> BFF1 & BFF2 & BFF3
BFF1 & BFF2 & BFF3 --> ServiceLayer
%% 服务与存储的交互
CoreEdu --> MySQL
IAM --> MySQL
Content --> Neo4j
DataAna --> ClickHouse
ServiceLayer --> Redis
%% CDC 与总线
MySQL -- "CDC (Debezium)<br/>捕获变更" --> Kafka
ServiceLayer -- "发布领域事件<br/>Outbox Pattern" --> Kafka
Kafka -- "消费事件" --> ServiceLayer
Kafka -- "同步读视图" --> ClickHouse
Kafka -- "索引同步" --> ES
二、 彻底解耦的四大核心设计模式
在最优架构中,系统通过以下企业级模式解决耦合问题:
1. 读写分离 (CQRS):解决“上帝模块”与复杂聚合查询
在当前的 Next_Edu 中Dashboard仪表盘需要查询所有模块。在企业级架构中写入逻辑和查询逻辑是完全物理隔离的。
Command (写) 链路:教师批改作业,请求只打到 CoreEdu 微服务,该服务只更新 MySQL 中的作业表,并迅速返回。
Query (读) 链路:系统背后通过 CDC如 Debezium监听 MySQL 的 binlog将数据变更实时推送到 Kafka。
物化视图构建DataAna (数据分析微服务) 消费 Kafka 消息,在 ClickHouse 或 ES 中构建一个高度扁平的“宽表”(如 student_dashboard_view
收益:前端 Dashboard 请求 BFF 时BFF 只查 ClickHouse 中的那一张宽表,毫秒级返回。没有 Join没有跨服务调用系统彻底解耦。
2. 发件箱模式 (Transactional Outbox):解决跨模块数据一致性
如果模块 A 成功了,模块 B 失败了怎么办?企业级系统绝对不允许跨服务的数据库事务 (如 2PC),因为会拖垮性能。
设计教师发布考试时CoreEdu 服务在同一个本地事务中做两件事:
往 exams 表写入考试数据。
往 outbox_events 表写入一条事件:{"type": "EXAM_PUBLISHED", "data": {...}}。
流转:后台的 CDC 组件Debezium监控到 outbox_events 表有新数据,自动将其投递到 Kafka。
收益:实现了 100% 保证的不丢消息的最终一致性。业务逻辑无需关心外部模块是否存活。
3. 编排与协同 (Orchestration vs. Choreography)
企业级架构处理复杂业务流(例如:考试创建 -> 智能组卷 -> 题目查重 -> 通知分发 -> 家长推送)必须区分两种模式:
协同 (Choreography - 基于事件):适用于低耦合业务。发完作业后,发出 HomeworkCreated 事件,通知服务、积分服务各自监听,互相不知道对方存在。
编排 (Orchestration - 基于工作流):适用于强状态依赖的业务。引入工作流引擎(如 Temporal 或 Camunda。由一个中央 Coordinator 负责指挥:“先调 AI 生成题目,成功后再调试卷服务,如果失败就执行补偿逻辑回滚”。
4. 前端微前端化 (Micro-Frontends)
后端的解耦如果不配合前端的解耦,依然是一场灾难。
设计:通过 Module Federation模块联邦或 qiankun将巨大的前端应用拆解。
收益:“排课组”的前端和后端可以独立发版,“题库组”的前端和后端可以独立发版。页面的组装在运行时由宿主框架完成。
三、 基础设施与扩展性设计
统一 API 网关 (API Gateway)
所有端点不再直接暴露。网关(如 Kong 或 APISIX负责统一的 JWT 鉴权校验、黑名单拦截、全局限流(防 CC 攻击)。业务微服务默认收到请求时,用户身份已经是合法的。
长连接与推送网关独立
SSE 或 WebSocket 不再由业务容器承载。设立专门的 Push Gateway 服务(底层可基于 Go 或 Netty 编写,单节点支撑十万级连接)。业务服务只需往 Redis Pub/Sub 或 Kafka 发送消息Push Gateway 负责广播给对应连接的客户端。
异构存储 (Polyglot Persistence)
知识图谱:教材和知识点的层级不再强行用 MySQL 存储,改为 Neo4j图数据库在执行“求某知识点的前置知识树”时性能提升百倍。
错题本/诊断:这些包含海量日志和时序数据的业务,直接存入 ClickHouse列式数据库亿级数据聚合秒级返回。
题库检索:题目内容实时同步到 Elasticsearch支持分词、拼音、公式模糊全文搜索而不是 MySQL 的 FULLTEXT。
四、 对比:为什么这是“最优”?
维度 当前的单体/模块化 (Next_Edu V3) 现代企业级架构 结果差异
模块依赖 物理隔离,但代码级强引用 (import) 纯事件通信与 API 契约 任意微服务宕机/重构,完全不影响其他服务
聚合查询 并行查 5 个模块的 DB 再在内存拼装 后台预计算,直接查 ClickHouse 宽表 Dashboard 响应从 1.5s 降至 50ms
技术栈绑定 全部被绑死在 TypeScript + Next.js 异构。AI网关用Python高并发网关用Go 能够根据业务特性选择最优技术
实时推送 Next.js SSE连接数多了容易爆内存 独立的 Push Gateway + Redis PubSub 支持全校十万人同时在线答题的广播推送
容灾与扩容 只能整个应用一起扩容 核心教学扩 50 个 Pod后台审计缩至 1 个 Pod 资源利用率极高,抗高并发能力呈指数级提升
总结
企业级架构的本质是承认分布式环境下的不完美,用基础设施的复杂性来换取业务代码的简单性。
业务模块不再需要操心“谁要我的数据”、“如何拼装别人的数据”、“事务失败怎么回滚”。它们只做一件事:接收指令 -> 改变自身领域模型 -> 将改变广播给全宇宙Event Bus.
蓝图设计的合理性(几乎全对,但有几个地方需要微调)
1. 各层选型精准,但有一处“过度理想”
API Gateway + BFF + GraphQL
Gateway 做统一鉴权限流BFF 做面向前端的聚合GraphQL 允许不同端按需取数——这在多端下非常正确。
✅ 唯一需要警惕的是 GraphQL 的 N+1 和深度嵌套,必须在 BFF 层用 DataLoader 批量化解,否则可能引入严重的下游放大调用。
事件总线选 Kafka/Pulsar
对业务事件和 CDC 均用同一总线,完全可行。
✅ 建议明确划分 领域事件 topic 与 数据同步 topic两者消费模型不同业务事件可能需回溯、重试数据同步更适合顺序日志在企业级通常用不同集群或至少独立 namespace。
CQRS + CDC + ClickHouse 宽表:
这是“彻底解耦聚合查询”的王道方案。
⚠️ 但实时性要谨慎定义:从 MySQL binlog → Kafka → 消费者写入 ClickHouse一般有 1-5 秒延迟。对于需要实时成绩展示的场景,可能需要 BFF 支持“查询主库 + 降级宽表”的混合读。
⚠️ ClickHouse 宽表可能会变得非常庞大列特别多需要设计好聚合引擎表SummingMergeTree / AggregatingMergeTree和合理的分区键如按学校+日期),否则维护成本极高。
图数据库 Neo4j 用于知识图谱:
正确,前置依赖查询性能会远远优于 MySQL 递归 CTE。但也要考虑知识图谱写入频率低、读频率高Neo4j 单机足够,如果为了运维一致性,也可以用 PostgreSQL + Apache AGE 插件,但你的蓝图用 Neo4j 没问题。
Push Gateway 独立 + Redis Pub/Sub
十万级连接通过独立长连接服务处理,是正确的。
✅ 注意Redis Pub/Sub 不持久化,如果有消息可靠性要求(离线再上线收不到历史推送),需要引入一个持久化队列或消息主题,由 Push Gateway 消费后推送给在线用户,同时标记已读。
2. 四大核心模式评价
CQRS正确这是消除“上帝模块”的根本解。
Transactional Outbox + CDC
这是 唯一能保证最终一致性的分布式事务方案,比 2PC 和 Saga 都更适合高并发教育场景。
✅ 但要注意Outbox 表必须随业务服务独立部署CDC 连接器Debezium需要监控其心跳和落后量否则可能成为链路瓶颈。
Choreography vs Orchestration
你提到用 Temporal/Camunda 做编排,这非常对。
⚠️ 但要小心:“考试创建 → AI组卷 → 查重 → 通知分发”这类流程,如果使用全事件协同,会出现隐式状态机,维护复杂。用 Temporal 作为工作流引擎是明智的Temporal 本身已经内置了重试、补偿、超时,比自研编排器强得多。
微前端:
在多团队并行开发下必要,但教育产品交互一致性要求高,需要强约束的设计系统和跨应用状态共享机制(如通过 BFF 或客户端共享 token + 用户上下文)。模块联邦 + 统一 UI 库是标配。
3. 基础设施层的一个潜在疏漏
你提到了 WAF、Gateway、Kafka、异构存储但没有提到统一的配置中心与服务发现如 Consul/Nacos/K8s Service。在微服务体系下服务动态扩缩容、配置热更新如限流阈值、功能开关必须同步规划否则运维会变得困难。这一层通常与 Service MeshIstio配合可以在架构图中补上。

View File

@@ -0,0 +1,945 @@
# 架构影响地图(微服务版)
> 版本1.0
> 日期2026-07-07
> 状态:基线发布
> 适用范围Edu 微服务架构DDD + EDA + CQRS
> 关联文档:
> - [理想蓝图](./0010_architecture.md)
> - [项目规则](../../project_rules.md)
> - [路线图](./roadmap/README.md)
---
## 目录
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-阶段路线图)
---
## 1. 项目概述
### 1.1 系统边界
```mermaid
graph TB
subgraph Users["用户层"]
Teacher[教师]
Student[学生]
Parent[家长]
Admin[管理员]
end
subgraph MFE["微前端层Module Federation"]
TeacherPortal[teacher-portal]
StudentPortal[student-portal]
ParentPortal[parent-portal]
AdminPortal[admin-portal]
end
subgraph Gateway["网关层Go"]
APIGateway[api-gateway<br/>Gin + JWT + 限流]
PushGateway[push-gateway<br/>WebSocket/SSE]
end
subgraph BFF["BFF 聚合层NestJS"]
TeacherBFF[teacher-bff<br/>GraphQL]
StudentBFF[student-bff<br/>GraphQL]
ParentBFF[parent-bff<br/>GraphQL]
end
subgraph Services["业务微服务NestJS + FastAPI"]
IAM[iam<br/>身份认证]
CoreEdu[core-edu<br/>教学核心]
Content[content<br/>内容资源]
DataAna[data-ana<br/>数据分析 Python]
Msg[msg<br/>消息通知]
AI[ai<br/>AI 网关 Python]
end
subgraph Bus["事件总线"]
Kafka[(Kafka)]
Debezium[Debezium CDC]
end
subgraph Data["数据层"]
MySQL[(MySQL<br/>每服务独占)]
Redis[(Redis<br/>缓存/会话)]
ClickHouse[(ClickHouse<br/>读模型宽表)]
Neo4j[(Neo4j<br/>知识图谱)]
ES[(Elasticsearch<br/>题库检索)]
end
Teacher --> TeacherPortal
Student --> StudentPortal
Parent --> ParentPortal
Admin --> AdminPortal
TeacherPortal --> APIGateway
StudentPortal --> APIGateway
ParentPortal --> APIGateway
AdminPortal --> APIGateway
TeacherPortal -.推送.-> PushGateway
StudentPortal -.推送.-> PushGateway
APIGateway --> TeacherBFF
APIGateway --> StudentBFF
APIGateway --> ParentBFF
TeacherBFF --> IAM
TeacherBFF --> CoreEdu
TeacherBFF --> Content
TeacherBFF --> DataAna
StudentBFF --> IAM
StudentBFF --> CoreEdu
ParentBFF --> IAM
ParentBFF --> CoreEdu
CoreEdu <--> Kafka
Content <--> Kafka
DataAna <--> Kafka
Msg <--> Kafka
IAM <--> Kafka
MySQL --> Debezium
Debezium --> Kafka
IAM --> MySQL
CoreEdu --> MySQL
Content --> Neo4j
DataAna --> ClickHouse
Msg --> MySQL
AI --> ES
IAM --> Redis
CoreEdu --> Redis
```
### 1.2 服务清单
| 类别 | 服务名 | 语言/框架 | 限界上下文 | 阶段 |
|------|--------|-----------|-----------|------|
| 基础设施 | api-gateway | Go (Gin) | 网关 | P1 |
| 基础设施 | push-gateway | Go (Gin) | 推送 | P5 |
| BFF | teacher-bff | TS (NestJS) | 教师聚合 | P2 |
| BFF | student-bff | TS (NestJS) | 学生聚合 | P3 |
| BFF | parent-bff | TS (NestJS) | 家长聚合 | P4 |
| 业务 | iam | TS (NestJS) | 身份认证 | P2 |
| 业务 | core-edu | TS (NestJS) | 教学核心 | P3 |
| 业务 | content | TS (NestJS) | 内容资源 | P4 |
| 业务 | data-ana | Python (FastAPI) | 数据分析 | P4 |
| 业务 | msg | TS (NestJS) | 消息通知 | P5 |
| 业务 | ai | Python (FastAPI) | AI 网关 | P5 |
| 微前端 | teacher-portal | TS (Next.js) | 教师端 | P2 |
| 微前端 | student-portal | TS (Next.js) | 学生端 | P3 |
| 微前端 | parent-portal | TS (Next.js) | 家长端 | P4 |
| 微前端 | admin-portal | TS (Next.js) | 管理端 | P6 |
| 共享包 | shared-proto | TS | protobuf 契约 | P1 |
| 共享包 | shared-ts | TS | TS 共享工具 | P1 |
| 共享包 | shared-go | Go | Go 共享工具 | P1 |
| 共享包 | shared-py | Python | Python 共享工具 | P4 |
### 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.22+ | Gin | API Gateway、Push Gateway |
| 业务服务 | TypeScript 5.5+ | NestJS 10 | IAM、CoreEdu、Content、Msg |
| 分析/AI | Python 3.12+ | FastAPI | DataAna、AI 网关 |
| BFF | TypeScript 5.5+ | NestJS 10 + GraphQL | 教师/学生/家长聚合 |
| 微前端 | TypeScript 5.5+ | Next.js 15 + Module Federation | 4 端门户 |
| 契约 | protobuf | buf | 跨语言契约定义 |
### 2.2 多存储矩阵
| 存储 | 用途 | 使用服务 |
|------|------|----------|
| MySQL 8 | 写模型主库(每服务独占) | IAM、CoreEdu、Content、Msg |
| Redis 7 | 缓存、会话、限流计数 | 全部服务 |
| ClickHouse | 读模型宽表、分析聚合 | DataAna、CoreEdu读模型 |
| Neo4j | 知识图谱、前置依赖 | Content |
| Elasticsearch | 题库全文检索 | Content、AI |
### 2.3 基础设施矩阵
| 组件 | 用途 |
|------|------|
| Kafka | 事件总线,领域事件异步通信 |
| Debezium | CDCMySQL Binlog → Kafka 实时同步 |
| Temporal | 工作流编排考试生命周期、AI 编排) |
| OpenTelemetry | 分布式追踪 |
| Loki | 日志聚合 |
| Tempo | 分布式 Trace 存储 |
| Prometheus | 指标采集 |
| Grafana | 可观测性可视化 |
| Vault | 密钥管理P6 |
---
## 3. 分层架构
### 3.1 六层架构
```mermaid
graph TB
subgraph L1["L1 客户端层"]
Browser[浏览器]
Mobile[移动端]
end
subgraph L2["L2 微前端层"]
MFE[Module Federation<br/>4 端门户]
end
subgraph L3["L3 网关层"]
GW[API Gateway Go<br/>路由+鉴权+限流+熔断]
Push[Push Gateway Go<br/>WebSocket/SSE]
end
subgraph L4["L4 BFF 聚合层"]
BFF[BFF NestJS<br/>聚合+裁剪+协议转换]
end
subgraph L5["L5 业务微服务层"]
SVC[6 业务服务<br/>DDD+CQRS]
end
subgraph L6["L6 数据与总线层"]
DB[(MySQL/CH/Neo4j/ES)]
KAFKA[(Kafka)]
TEMPORAL[Temporal]
end
Browser --> MFE
Mobile --> MFE
MFE --> GW
MFE -.推送.-> Push
GW --> BFF
BFF --> SVC
SVC --> DB
SVC <--> KAFKA
SVC --> TEMPORAL
```
### 3.2 依赖方向
```
L1 客户端 → L2 微前端 → L3 网关 → L4 BFF → L5 业务服务 → L6 数据/总线
```
**严格规则**
1. L3 网关层只做路由、鉴权、限流、熔断,**不写业务逻辑**
2. L4 BFF 层只做聚合、裁剪、协议转换,**不持有业务状态**
3. L5 业务服务之间通过 gRPC同步或 Kafka 事件(异步)通信,**不直接访问对方数据库**
4. L6 数据层每个微服务独占自身数据库,**禁止跨库联表**
---
## 4. 服务依赖图
```mermaid
graph TB
subgraph Gateway["网关层"]
APIGW[api-gateway]
PushGW[push-gateway]
end
subgraph BFF["BFF 层"]
TBFF[teacher-bff]
SBFF[student-bff]
PBFF[parent-bff]
end
subgraph Services["业务服务"]
IAM[iam]
CoreEdu[core-edu]
Content[content]
DataAna[data-ana]
Msg[msg]
AI[ai]
end
subgraph Shared["共享包"]
Proto[shared-proto]
SharedTS[shared-ts]
end
APIGW --> TBFF
APIGW --> SBFF
APIGW --> PBFF
PushGW --> Msg
TBFF --> IAM
TBFF --> CoreEdu
TBFF --> Content
TBFF --> DataAna
TBFF --> AI
SBFF --> IAM
SBFF --> CoreEdu
SBFF --> Content
SBFF --> DataAna
PBFF --> IAM
PBFF --> CoreEdu
CoreEdu -.事件.-> Content
CoreEdu -.事件.-> DataAna
CoreEdu -.事件.-> Msg
Content -.事件.-> DataAna
IAM -.事件.-> CoreEdu
IAM -.事件.-> Msg
AI -.gRPC.-> Content
AI -.gRPC.-> DataAna
IAM --> Proto
CoreEdu --> Proto
Content --> Proto
DataAna --> Proto
Msg --> Proto
AI --> Proto
IAM --> SharedTS
CoreEdu --> SharedTS
Content --> SharedTS
Msg --> SharedTS
```
### 4.1 服务间通信矩阵
| 调用方 → 被调用方 | 协议 | 场景 |
|-------------------|------|------|
| api-gateway → BFF | gRPC | 请求路由 |
| BFF → 业务服务 | gRPC | 同步查询聚合 |
| CoreEdu → Content | Kafka 事件 | 教学内容变更通知 |
| CoreEdu → DataAna | Kafka 事件 | 学情数据投递 |
| CoreEdu → Msg | Kafka 事件 | 通知触发 |
| IAM → CoreEdu | Kafka 事件 | 用户变更同步 |
| AI → Content | gRPC | 题库查询 |
| AI → DataAna | gRPC | 学情数据查询 |
| push-gateway → Msg | gRPC | 推送通道建立 |
---
## 5. 认证与权限
### 5.1 JWT RS256 认证流程
```mermaid
sequenceDiagram
participant U as 用户
participant GW as API Gateway
participant IAM as IAM 服务
participant SVC as 业务服务
rect rgb(240, 248, 255)
Note over U,IAM: 阶段 1: 登录签发
U->>GW: POST /auth/login {username, password}
GW->>IAM: gRPC Login(username, password)
IAM->>IAM: 校验密码 + 查询权限
IAM->>IAM: 生成 JWTRS256 私钥签发)
IAM-->>GW: {accessToken, refreshToken, userInfo}
GW-->>U: 200 {accessToken, refreshToken}
end
rect rgb(240, 255, 240)
Note over U,SVC: 阶段 2: 请求鉴权
U->>GW: GET /api/classes + Authorization: Bearer <token>
GW->>GW: RS256 公钥校验签名
GW->>GW: 校验 exp/iss/aud
GW->>GW: 提取 userId/role/dataScope
GW->>SVC: gRPC 请求 + 透传 userId/role/dataScope metadata
SVC->>SVC: 权限校验requirePermission
SVC-->>GW: 响应数据
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 条件。
---
## 6. 数据访问与缓存
### 6.1 CQRS 读写分离
```mermaid
graph LR
subgraph Write["写路径"]
Cmd[Command 命令] --> App[Application Service]
App --> Domain[Domain 领域模型]
Domain --> Repo[Repository 写模型]
Repo -->[(MySQL 主库)]
App --> Outbox[(Outbox 表<br/>同事务)]
end
subgraph Sync["同步链路"]
Outbox --> Relay[Relay Worker]
Relay --> Kafka[(Kafka)]
Kafka --> Proj[Projection]
Proj -->[(ClickHouse 宽表)]
Proj -->[(Redis 缓存)]
Proj -->[(ES 索引)]
end
subgraph Read["读路径"]
Query[Query 查询] --> ReadModel[Read Model]
ReadModel -->[(ClickHouse 宽表)]
ReadModel -->[(Redis 缓存)]
ReadModel -->[(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<br/>每 100ms]
Publish[发布到 Kafka]
Mark[标记 processed]
end
subgraph Bus["事件总线"]
Kafka[(Kafka topic)]
end
subgraph Consumers["消费者"]
Proj[Projection<br/>更新读模型]
OtherSvc[其他服务<br/>业务订阅]
end
Cmd --> Domain
Domain --> Repo
Repo --> BizTable
Repo --> OutboxTable
OutboxTable --> Poll
Poll --> Publish
Publish --> Kafka
Kafka --> Proj
Kafka --> OtherSvc
Proj -->[(ClickHouse/Redis/ES)]
```
### 7.2 事件 Topic 分类
| Topic 模式 | 示例 | 生产者 | 消费者 |
|-----------|------|--------|--------|
| `edu.identity.user.created` | 用户创建 | IAM | CoreEdu、Msg |
| `edu.identity.user.updated` | 用户更新 | IAM | CoreEdu、Msg |
| `edu.org.class.created` | 班级创建 | CoreEdu | DataAna |
| `edu.teaching.assignment.submitted` | 作业提交 | CoreEdu | DataAna、Msg |
| `edu.teaching.exam.published` | 考试发布 | CoreEdu | Msg |
| `edu.teaching.grade.recorded` | 成绩录入 | CoreEdu | DataAna、Msg |
| `edu.content.question.published` | 题目发布 | Content | AI、ES |
| `edu.insight.mastery.updated` | 掌握度更新 | DataAna | CoreEdu、Msg |
### 7.3 核心领域事件
| 事件 | 触发场景 | 消费者动作 |
|------|----------|-----------|
| UserRegistered | 新用户注册 | CoreEdu 初始化默认班级关联Msg 发送欢迎通知 |
| ExamPublished | 考试发布 | Msg 推送考试通知给学生DataAna 创建考试分析骨架 |
| HomeworkSubmitted | 学生提交作业 | DataAna 记录提交行为Msg 通知教师 |
| HomeworkGraded | 教师批改完成 | DataAna 更新掌握度Msg 通知学生 |
| MasteryUpdated | 掌握度计算完成 | CoreEdu 推荐个性化练习Msg 触发预警 |
| NotificationRequested | 通知请求 | Msg 投递通知到多渠道 |
---
## 8. 跨服务协作
### 8.1 同步 vs 异步决策
```mermaid
flowchart TD
Req[跨服务协作需求] --> C1{需要强一致性?}
C1 -- 是 --> C2{调用方需要立即结果?}
C2 -- 是 --> Sync[同步 gRPC 调用]
C2 -- 否 --> Saga[Saga 编排<br/>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 三支柱可观测性
```mermaid
graph TB
subgraph App["应用层"]
SVC[业务服务]
GW[网关]
BFF[BFF]
end
subgraph Collect["采集层"]
OTEL[OpenTelemetry SDK]
PROM[Prometheus Exporter]
end
subgraph Storage["存储层"]
LOKI[(Loki<br/>日志)]
TEMPO[(Tempo<br/>Trace)]
PROMDB[(Prometheus<br/>指标)]
end
subgraph Vis["可视化层"]
GRAFANA[Grafana<br/>统一面板]
ALERT[AlertManager<br/>告警]
end
SVC --> OTEL
GW --> OTEL
BFF --> OTEL
OTEL --> LOKI
OTEL --> TEMPO
SVC --> PROM
GW --> PROM
PROM --> PROMDB
LOKI --> GRAFANA
TEMPO --> GRAFANA
PROMDB --> GRAFANA
PROMDB --> ALERT
```
### 10.2 Trace 上下文传播
```mermaid
flowchart LR
A[客户端请求] --> B[API Gateway<br/>生成 traceId]
B --> C[BFF<br/>继承 traceId]
C --> D[业务服务<br/>继承 traceId]
D --> E[Kafka 事件<br/>traceId 写入 header]
E --> F[消费者服务<br/>继承 traceId]
F --> G[数据存储<br/>span 记录]
```
**规则**
- 所有跨服务调用必须透传 W3C Trace Context
- Kafka 事件必须将 traceId 写入消息 header
- 日志必须包含 traceId 用于关联查询
- 关键业务操作必须创建 span创建考试、提交作业、批改等
---
## 11. 契约与 API 架构
### 11.1 Protobuf 契约体系
```mermaid
graph TB
subgraph Proto["protobuf 契约仓库"]
Identity[identity/v1<br/>user/role/permission]
Org[org/v1<br/>class/subject/enrollment]
Teaching[teaching/v1<br/>course/assignment/exam]
Content[content/v1<br/>textbook/question]
Comm[comm/v1<br/>message/notification]
Insight[insight/v1<br/>report/mastery]
end
subgraph Gen["代码生成"]
Buf[buf generate]
TS[TS 生成代码<br/>@bufbuild/protobuf]
Go[Go 生成代码<br/>protobuf-go]
Py[Python 生成代码<br/>betterproto]
end
subgraph Services["消费服务"]
SvcTS[NestJS 服务]
SvcGo[Go 网关]
SvcPy[Python 服务]
end
Identity --> Buf
Org --> Buf
Teaching --> Buf
Content --> Buf
Comm --> Buf
Insight --> Buf
Buf --> TS
Buf --> Go
Buf --> Py
TS --> SvcTS
Go --> SvcGo
Py --> SvcPy
```
### 11.2 契约规则
| 规则 | 说明 |
|------|------|
| 包命名 | `edu.[context].[aggregate].v[version]` |
| 版本化 | 破坏性变更必须升版本v1 → v2 |
| 字段编号 | 禁止复用已删除字段编号,使用 reserved |
| 消息命名 | PascalCase |
| 字段命名 | snake_case |
| 注释 | 每个 message 和字段必须注释 |
| CI 强制 | buf lint + buf breaking 必须通过 |
### 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
```
---
## 12. 架构约束
### 12.1 服务独立性约束
| 约束 | 说明 |
|------|------|
| 数据库独占 | 每个微服务独占自身数据库,禁止跨库联表 |
| 契约先行 | 所有跨服务通信必须先定义 protobuf 契约 |
| Outbox 强制 | 所有领域事件必须通过 Outbox 模式发布 |
| 幂等消费 | 所有事件消费者必须实现幂等性 |
| 单一职责 | 每个服务只负责一个限界上下文 |
| 无状态服务 | 业务服务不持有会话状态Redis 承载) |
### 12.2 通信约束
| 场景 | 允许 | 禁止 |
|------|------|------|
| 客户端 → Gateway | REST + WebSocket | 直连业务服务 |
| Gateway → BFF | gRPC | REST |
| BFF → 业务服务 | gRPC | 直接访问 DB |
| 业务服务之间(同步) | gRPC + 必要时 | REST、直接 DB |
| 业务服务之间(异步) | Kafka 事件 | 直接 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 工作流编排 | 长流程编排、可观测、可回滚 | 已采纳 |
| ADR-014 | 采用 ClickHouse 读模型宽表 | 分析查询亚秒级响应 | 已采纳 |
---
## 14. 附录6 阶段路线图
### 14.1 阶段总览
```mermaid
graph LR
P1[P1 地基<br/>M1-M3] --> P2[P2 身份<br/>M4-M6]
P2 --> P3[P3 核心教学<br/>M7-M10]
P3 --> P4[P4 内容分析<br/>M11-M13]
P4 --> P5[P5 沟通AI<br/>M14-M16]
P5 --> P6[P6 硬化<br/>M17-M18]
```
### 14.2 服务与阶段映射
| 阶段 | 周期 | 交付服务 | 退出标准 |
|------|------|----------|----------|
| P1 地基 | M1-M3 | api-gateway、classes黄金模板、shared-proto | classes 域 CRUD 端到端跑通 |
| P2 身份 | M4-M6 | iam、teacher-bff、teacher-portal 骨架 | 教师可登录并看到空白 Dashboard |
| P3 核心教学 | M7-M10 | core-edu合并 classes、student-bff、student-portal | 考试→作答→批改→成绩全链路 |
| P4 内容分析 | M11-M13 | content、data-ana、parent-bff、parent-portal | 知识图谱查询 + 学情宽表 5s |
| P5 沟通AI | M14-M16 | msg、push-gateway、ai | 全校广播 + AI 辅助出题 |
| P6 硬化 | M17-M18 | admin-portal、Service Mesh | 99.9% 可用性 + 独立扩缩容 |
> 详细规划见 [路线图目录](./roadmap/README.md)

View File

@@ -0,0 +1,28 @@
# 路线图索引
> 本目录存放项目长远规划与架构事实004分离。
## 文档清单
| 文档 | 用途 |
|------|------|
| [tech-debt.md](./tech-debt.md) | 技术债清单(按 P0/P1/P2 优先级 + 已解决项) |
| [pending-features.md](./pending-features.md) | 待开发功能路线图6 阶段P1 地基 → P6 硬化) |
## 6 阶段路线图总览
| 阶段 | 周期 | 核心交付 | 退出标准 |
|------|------|----------|----------|
| **P1 地基** | M1-M3 | 仓库骨架 + Docker 全量 infra + API Gateway + 契约层 + CI/CD + 文档体系 + classes 黄金模板 | classes 域 CRUD 端到端跑通 + 全横切关注点落地 + 30 分钟可复制新服务 |
| **P2 身份** | M4-M6 | IAM 服务 + Teacher BFF(GraphQL) + 微前端骨架 | 教师可登录并看到空白 Dashboard |
| **P3 核心教学** | M7-M10 | CoreEdu 服务 + Outbox 模式 + 考试/作业/成绩域 | 教师创建考试→学生作答→教师批改→成绩统计 全链路 |
| **P4 内容分析** | M11-M13 | Content 服务(Neo4j) + DataAna(Python+CH) + CDC 链路 | 知识图谱查询 + 学情诊断宽表 5s 内返回 |
| **P5 沟通AI** | M14-M16 | Msg 服务 + Push Gateway + AI 网关 + ES 题库检索 | 全校广播推送 + AI 辅助出题 + 题库检索 < 200ms |
| **P6 硬化** | M17-M18 | Service Mesh + 全链路可观测 + 生产硬化 | 单服务可独立扩缩容 + 99.9% 可用性 |
## 维护规则
- 规划实现后从本目录删除,迁入 004 架构事实或 git 历史
- 不含架构事实,不含经验(经验查 [../troubleshooting/known-issues.md](../troubleshooting/known-issues.md)
- 每阶段完成后打 tag`v0.1.0-p1``v0.2.0-p2`...
- 发现的新需求一律记入 `tech-debt.md`不在当前阶段实现YAGNI 原则)

View File

@@ -0,0 +1,203 @@
# 待开发功能路线图
> 按 6 阶段组织的功能路线图,每阶段列出关键功能和交付物。
> 阶段依赖P1 → P2 → P3 → P4/P5可并行但建议串行 → P6
---
## P1 地基阶段M1-M3
**目标**:搭建新仓库地基,多语言 monorepo + Docker 基础设施 + API Gateway + classes 黄金模板服务 + 文档体系 + CI/CD端到端跑通 classes 域 CRUD。
**退出标准**classes 域 CRUD 端到端跑通 + 全横切关注点落地 + 30 分钟可复制新服务。
### 关键功能
| 模块 | 功能 |
|------|------|
| 仓库骨架 | 多语言 monorepopnpm + go.work + pyproject+ 大仓文档LICENSE/CHANGELOG/CONTRIBUTING/SECURITY |
| Docker 基础设施 | 全量 docker-compose.yml按 profiles 分阶段启用)+ 最小开发集MySQL+Redis |
| API GatewayGo | 路由转发 + JWT HS256 校验 + 请求 ID 注入 + 健康检查 |
| 契约层 | shared-proto 包 + classes.proto + buf lint/breaking + 三端代码生成配置 |
| classes 黄金模板TS/NestJS | CRUD + 全横切关注点(错误处理/可观测/安全/契约/测试/文档/配置/i18n/CI/Dockerfile |
| arch.db 多语言扫描器 | TS 扫描ts-morph+ Go 扫描(正则骨架)+ Python 扫描(正则骨架)+ 查询工具 |
| teacher-portal 测试页 | Next.js 单页验证 classes CRUD 端到端链路 |
| CI/CD | 三语言 workflowci-go.yml / ci-ts.yml / ci-py.yml |
### 交付物
- `docker-compose up -d` 全量容器健康
- 浏览器创建班级 → MySQL 落库 → 列表显示
- `buf lint` + `buf breaking` 通过,三端代码生成成功
- 三语言 CI workflow 全绿lint+test+build
- 单元 + 集成 + 契约 + E2E 四类测试齐备,覆盖率达标
- 004 + 2 个模块 README + known-issues + project_rules 齐全
- `npm run arch:query -- violations` 输出 0
- 30 分钟内复制 classes 模板跑起新服务
- 打 tag `v0.1.0-p1`
---
## P2 身份阶段M4-M6
**目标**:建 IAM 服务替换 P1 Gateway 内置鉴权;建首个完整 BFFTeacher与微前端骨架。
**退出标准**:教师登录 → 获取 JWT → 访问 teacher-portal → 侧边栏按 `viewports.L1` 渲染 → 看到空白 Dashboard。
### 关键功能
| 模块 | 功能 |
|------|------|
| IAM 服务TS/NestJS | 认证(登录/登出/JWT/2FA+ RBAC角色/权限/角色-权限 CRUD+ 视口配置4 层模型)+ DataScope 解析 + `getEffectivePermissions(userId)` |
| MySQL schema | users / roles / permissions / role_permissions / role_viewports / parent_student_relations / class_subject_teachers |
| JWT RS256 | IAM 私钥签发Gateway/服务公钥校验access 15min / refresh 7day |
| 权限缓存 | `getEffectivePermissions` 结果 Redis 缓存 TTL 5 分钟,角色变更主动失效 |
| Teacher BFFTS/GraphQL | GraphQL Yoga + DataLoader防 N+1+ 调 IAM 注入视口 |
| teacher-portal微前端宿主 | Module Federation + 路由骨架 + 侧边栏viewports.L1 驱动)+ 登录页 |
| API Gateway 升级 | 移除内置 JWT改调 IAM 校验;路由表扩展 `/api/v1/iam/*` |
### 交付物
- IAM 服务完整实现认证 + RBAC + 视口 + DataScope
- JWT RS256 非对称签名链路通畅
- Teacher BFF GraphQL 接口可用
- teacher-portal 微前端骨架 + 登录流程
- 教师登录后侧边栏按角色渲染
- 打 tag `v0.2.0-p2`
---
## P3 核心教学阶段M7-M10
**目标**:建 CoreEdu 服务实现考试全生命周期;落地 Outbox + Kafka 事件模式。
**退出标准**:教师创建考试 → 发布 → 学生作答提交 → 教师批改 → 事件发到 Kafka → 成绩统计更新 → 全链路可观测。
### 关键功能
| 模块 | 功能 |
|------|------|
| CoreEdu 服务TS/NestJS | 考试/作业/成绩域 CRUD + 批改业务编排 + Outbox 事件发布 |
| MySQL schema | exams / exam_questions / homework_assignments / homework_submissions / homework_answers / grade_records / outbox_events |
| Outbox 模式 | 业务事务同写 outbox_events 表;后台 relay worker 投递 Kafka |
| Outbox relayGo | 独立服务 `services/outbox-relay/`,轻量高吞吐 |
| Kafka | 启用业务 topicexam.published / homework.graded / grade.recorded |
| Teacher BFF 扩展 | 考试/作业/成绩的 GraphQL 查询与 mutation |
| teacher-portal 扩展 | 考试创建/作业批改/成绩查看页面 |
| student-portal微前端 | 学生作答作业页面Module Federation 子应用) |
| Temporal | 引入但仅做 1 个工作流(考试发布编排:创建作业→通知)试点 |
### 交付物
- CoreEdu 服务考试全生命周期链路通畅
- Outbox + Kafka 事件模式落地
- Outbox relay worker 稳定投递
- student-portal 微前端子应用接入
- 全链路 trace 可追OTel
- Outbox 模式回写黄金模板 README
- 打 tag `v0.3.0-p3`
---
## P4 内容分析阶段M11-M13
**目标**:建 Content 服务Neo4j 知识图谱)+ DataAna 服务Python+ClickHouse落地 CDC 链路。
**退出标准**教师查看知识图谱前置依赖Neo4j 秒级返回)→ 学生查看学情诊断ClickHouse 宽表 5s 内返回)→ CDC 链路延迟 < 5s。
### 关键功能
| 模块 | 功能 |
|------|------|
| Content 服务TS/NestJS | 教材/章节/知识点 CRUD仅 CRUD不实现检索+ 知识图谱查询Neo4j+ 题库 CRUD不实现检索 |
| MySQL schema | textbooks / chapters / knowledge_points / questions |
| Neo4j 数据 | 知识点前置依赖图(从 MySQL 同步) |
| DataAna 服务Python/FastAPI | 学情诊断 API + 错题本 API + 消费 Kafka 构建宽表 |
| ClickHouse | student_dashboard_view 宽表DataAna 消费 Kafka 填充) |
| CDC 链路 | Debezium 监听 MySQL binlog → Kafkamysql.cdc.*)→ DataAna 消费写 ClickHouse |
| BFF 扩展 | Teacher BFF 加知识图谱查询Student BFF 加学情诊断查询(双轨读) |
### 交付物
- Content 服务知识图谱查询秒级返回
- DataAna 学情诊断宽表 5s 内返回
- CDC 链路延迟 < 5s
- Neo4j 双写避免(消费事件同步)
- 双轨读策略落地(实时查主库 + 聚合查宽表)
- CDC 模式回写黄金模板 README
- 打 tag `v0.4.0-p4`
---
## P5 沟通与 AI 阶段M14-M16
**目标**:建 Msg 服务 + Push Gateway + AI 网关;全文检索迁 ES。
**退出标准**:教师发广播通知 → 全在线学生实时收到Push Gateway→ AI 辅助出题流式返回 → 题库全文检索 < 200ms。
### 关键功能
| 模块 | 功能 |
|------|------|
| Msg 服务TS/NestJS | 会话/消息 CRUD + 调 Push Gateway 推送 + 通知偏好 |
| Push GatewayGo | WebSocket 长连接管理 + 消费 Kafka 广播 + Redis PubSub 跨实例同步 |
| AI 网关Python/FastAPI | LLM Provider 适配OpenAI/Anthropic+ Prompt 模板管理 + 流式 SSE + 用量计费 |
| Elasticsearch | 题库全文检索(从 MySQL 同步)+ 全局搜索 API |
| Notifications 模块 | 多渠道(站内/SMS/邮件/微信),沿用旧项目 dispatcher 模式 |
| BFF/前端扩展 | Teacher BFF 加 AI 辅助出题 mutationteacher-portal 加 SSE 流式 AI 对话 |
### 交付物
- Msg 服务会话/消息 CRUD + 推送链路
- Push Gateway 单节点支撑 10w+ 连接
- AI 网关流式 SSE 三层透传AI → BFF → 前端)
- ES 题库全文检索 < 200ms
- 全校广播推送实时到达
- 长连接模式回写黄金模板 README
- 打 tag `v0.5.0-p5`
---
## P6 硬化阶段M17-M18
**目标**:生产硬化,达到可部署状态。
**退出标准**单服务可独立扩缩容HPA 生效)→ 全链路 trace 可追 → 模拟单服务宕机不影响核心链路 → 99.9% 可用性压测通过。
### 关键功能
| 模块 | 功能 |
|------|------|
| Service Mesh | Istio 服务网格mTLS + 流量治理 + 可观测) |
| 配置中心 | Consul 接入,配置热更新(限流阈值、功能开关) |
| 全链路可观测 | OpenTelemetry + Jaegertrace+ Prometheusmetrics+ Lokilogs |
| 限流/熔断 | Gateway 层限流(令牌桶)+ 服务间熔断Envoy |
| 灰度发布 | Istio 流量拆分(金丝雀) |
| K8s 部署 | 每服务 K8s manifest + HPA 自动扩缩容 |
| 生产 CI/CD | Git tag 触发镜像构建 + 滚动部署 |
| 灾备 | MySQL 主从 + Redis 哨兵 + Kafka 多副本 |
### 交付物
- Istio Service Mesh 全网格覆盖mTLS
- 全链路 trace + Grafana 仪表盘 + Loki 日志查询
- 限流熔断灰度发布可用
- K8s HPA 自动扩缩容生效
- 单服务宕机不影响核心链路
- 99.9% 可用性压测通过
- 降级方案若时间紧张Service Mesh 可降级为 K8s 原生 Service + Ingress
- 打 tag `v1.0.0-p6`
---
## 跨阶段不变约束
每阶段都必须遵守:
- 契约先行(先改 proto后写实现
- 文档同步004 + 模块 README + arch.db + known-issues 实时更新)
- CI 全绿才能合入 main
- 每阶段末打 tag
- Server/Handler 接口必须权限校验
- 单文件行数遵循语言规范TS ≤ 500/800/1000Go ≤ 800Python ≤ 800
- 阶段特有模式实现后回写黄金模板

View File

@@ -0,0 +1,47 @@
# 技术债清单
> 记录已知的架构问题和技术债,按优先级排序。
> 新项目从空白起步,随各阶段实施过程中发现的技术债记录于此。
## P0 - 高优先级(影响安全/性能/可维护性)
> 暂无。P1 实施过程中识别的高优先级技术债记录于此。
## P1 - 中优先级(影响开发效率/代码质量)
> 暂无。各阶段实施过程中识别的中优先级技术债记录于此。
## P2 - 低优先级(改进项)
> 暂无。各阶段实施过程中识别的低优先级改进项记录于此。
## 已解决项
> 暂无。已解决的技术债记录于此,含解决时间、方案、验证方式。
---
## 维护规则
### 优先级定义
| 优先级 | 含义 | 处理时机 |
|--------|------|----------|
| P0 | 影响安全/性能/可维护性 | 当前阶段必须解决,或立即修复 |
| P1 | 影响开发效率/代码质量 | 计划在下一阶段或独立迭代解决 |
| P2 | 改进项 | 时间允许时解决,不阻塞阶段推进 |
### 记录格式
每条技术债包含:
- **编号**: `TD-{P0|P1|P2}-{序号}`,如 `TD-P0-001`
- **状态**: 已识别 / 短期方案已实施 / 计划在某阶段实施 / 已解决
- **影响**: 简述对系统的影响
- **方案**: 短期方案 + 长期方案
- **关联文件/模块**: 便于定位
### 同步规则
- 发现技术债时立即记录不在当前阶段实现YAGNI 原则)
- 解决后移至"已解决项"分区,含解决时间与验证方式
- 每阶段末回顾技术债清单,调整优先级