docs: 同步 P6 工作日志、runbook 与服务 README
- known-issues.md: 追加 9 条 P6 工作经验日志,更新 arch-scan 经验 - post-p6-followup.md: 新增 P6 后续工作手册 runbook - iam/core-edu/content/msg README: 补充健康检查端点说明
This commit is contained in:
1029
docs/architecture/runbooks/post-p6-followup.md
Normal file
1029
docs/architecture/runbooks/post-p6-followup.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,7 +1,7 @@
|
|||||||
# 已知问题速查
|
# 已知问题速查
|
||||||
|
|
||||||
> 索引式速查手册:场景 → 技术/规则映射。不写代码示例。
|
> 索引式速查手册:场景 → 技术/规则映射。不写代码示例。
|
||||||
> 架构规则见 [../architecture/004_architecture_impact_map.md](../architecture/004_architecture_impact_map.md) 与 [../../project_rules.md](../../project_rules.md)
|
> 架构规则见 [../architecture/004_architecture_impact_map.md](../architecture/004_architecture_impact_map.md) 与 [../../.trae/rules/project_rules.md](../../.trae/rules/project_rules.md)
|
||||||
> 工作经验日志按时间倒序追加(50 条上限),AI 发现更好方案时可更新本节。
|
> 工作经验日志按时间倒序追加(50 条上限),AI 发现更好方案时可更新本节。
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -11,10 +11,10 @@
|
|||||||
### 1.1 多语言 monorepo 配置
|
### 1.1 多语言 monorepo 配置
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| ----------------------------- | ------------------------------------------------------------------------------------------ |
|
| ------------------------ | ------------------------------------------------------------------------------------------ |
|
||||||
| 多语言 workspace | pnpm workspace(TS)+ go.work(Go)+ pyproject.toml/uv workspace(Python)三套并存 |
|
| 多语言 workspace | pnpm workspace(TS)+ go.work(Go)+ pyproject.toml/uv workspace(Python)三套并存 |
|
||||||
| 根 package.json scripts | 封装多语言命令入口:`pnpm dev` / `pnpm lint` / `pnpm test` / `pnpm build` |
|
| 根 package.json scripts | 封装多语言命令入口:`pnpm dev` / `pnpm lint` / `pnpm test` / `pnpm build` |
|
||||||
| pnpm-workspace.yaml | 仅声明 TS 包路径(packages/*、services/classes、bff/*、apps/*、scripts/*),Go/Python 不入 |
|
| pnpm-workspace.yaml | 仅声明 TS 包路径(packages/_、services/classes、bff/_、apps/_、scripts/_),Go/Python 不入 |
|
||||||
| go.work | 列出所有 Go 服务模块(services/api-gateway、services/push-gateway) |
|
| go.work | 列出所有 Go 服务模块(services/api-gateway、services/push-gateway) |
|
||||||
| pyproject.toml | uv workspace members 列 Python 服务(services/data-ana、services/ai-gateway) |
|
| pyproject.toml | uv workspace members 列 Python 服务(services/data-ana、services/ai-gateway) |
|
||||||
| 跨语言共享类型 | protobuf 生成三端代码(TS/Go/Python),单一契约源 |
|
| 跨语言共享类型 | protobuf 生成三端代码(TS/Go/Python),单一契约源 |
|
||||||
@@ -25,7 +25,7 @@
|
|||||||
### 1.2 Docker Compose 基础设施
|
### 1.2 Docker Compose 基础设施
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| ---------------------------- | ---------------------------------------------------------------------------------- |
|
| ---------------- | ----------------------------------------------------------------------------------------------- |
|
||||||
| 日常开发启动 | 用 `docker-compose.minimal.yml` 仅起 MySQL+Redis |
|
| 日常开发启动 | 用 `docker-compose.minimal.yml` 仅起 MySQL+Redis |
|
||||||
| 全量启动内存不足 | 按 `profiles` 分阶段启用(full/kafka/cdc/analytics/graph/search/config/observability) |
|
| 全量启动内存不足 | 按 `profiles` 分阶段启用(full/kafka/cdc/analytics/graph/search/config/observability) |
|
||||||
| 每服务 mem_limit | 避免单服务吃满内存:MySQL 512m、Redis 128m、Kafka 512m、ClickHouse 1g |
|
| 每服务 mem_limit | 避免单服务吃满内存:MySQL 512m、Redis 128m、Kafka 512m、ClickHouse 1g |
|
||||||
@@ -38,7 +38,7 @@
|
|||||||
### 1.3 protobuf + buf 契约
|
### 1.3 protobuf + buf 契约
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| ----------------------- | ------------------------------------------------------------------------------------------ |
|
| -------------------- | --------------------------------------------------------------------------- |
|
||||||
| 契约唯一源 | `packages/shared-proto/proto/*.proto`,禁止 REST/gRPC 混用 |
|
| 契约唯一源 | `packages/shared-proto/proto/*.proto`,禁止 REST/gRPC 混用 |
|
||||||
| breaking change 检测 | `buf breaking --against '.git#branch=main'` CI 强制,必须升版本号 |
|
| breaking change 检测 | `buf breaking --against '.git#branch=main'` CI 强制,必须升版本号 |
|
||||||
| proto 版本化 | 包名带版本 `xxx.v1`、`xxx.v2`,新旧版本共存 |
|
| proto 版本化 | 包名带版本 `xxx.v1`、`xxx.v2`,新旧版本共存 |
|
||||||
@@ -51,7 +51,7 @@
|
|||||||
### 1.4 NestJS 服务开发(TS)
|
### 1.4 NestJS 服务开发(TS)
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| ------------------------- | ----------------------------------------------------------------------------------------------- |
|
| --------------------- | ------------------------------------------------------------------------------------------------------ |
|
||||||
| 服务标准结构 | `src/{main.ts,app.module.ts,config,middleware,<domain>,shared,generated}` 黄金模板复制 |
|
| 服务标准结构 | `src/{main.ts,app.module.ts,config,middleware,<domain>,shared,generated}` 黄金模板复制 |
|
||||||
| 三层配置 | env(环境变量)< yaml(业务参数)< 配置中心(P6 Consul);每服务启动时合并 |
|
| 三层配置 | env(环境变量)< yaml(业务参数)< 配置中心(P6 Consul);每服务启动时合并 |
|
||||||
| 环境变量校验 | Zod schema 校验 process.env,失败立即抛错终止启动 |
|
| 环境变量校验 | Zod schema 校验 process.env,失败立即抛错终止启动 |
|
||||||
@@ -71,7 +71,7 @@
|
|||||||
### 1.5 Go Gateway 开发
|
### 1.5 Go Gateway 开发
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| ------------------- | ------------------------------------------------------------------------------------------ |
|
| ----------------- | --------------------------------------------------------------------------------------- |
|
||||||
| 框架 | Gin + httputil.ReverseProxy 路由转发 |
|
| 框架 | Gin + httputil.ReverseProxy 路由转发 |
|
||||||
| P1 鉴权 | Gateway 内置 HS256 JWT 校验(测试密钥),P2 改 RS256(IAM 签发,公钥校验) |
|
| P1 鉴权 | Gateway 内置 HS256 JWT 校验(测试密钥),P2 改 RS256(IAM 签发,公钥校验) |
|
||||||
| JWT claims | `{ user_id, roles[], registered_claims }`,校验后注入 `x-user-id`/`x-user-roles` 头转发 |
|
| JWT claims | `{ user_id, roles[], registered_claims }`,校验后注入 `x-user-id`/`x-user-roles` 头转发 |
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
### 1.6 可观测性(OTel + Prometheus + Loki)
|
### 1.6 可观测性(OTel + Prometheus + Loki)
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| --------------------- | ---------------------------------------------------------------------------------- |
|
| --------------- | -------------------------------------------------------------------------------- |
|
||||||
| P1 最小可观测集 | 每服务结构化日志 + `/metrics` + OTel SDK 初始化(不引入完整后端) |
|
| P1 最小可观测集 | 每服务结构化日志 + `/metrics` + OTel SDK 初始化(不引入完整后端) |
|
||||||
| 三支柱 | Logs(pino/winston/zap)+ Metrics(prom-client)+ Traces(OTel SDK) |
|
| 三支柱 | Logs(pino/winston/zap)+ Metrics(prom-client)+ Traces(OTel SDK) |
|
||||||
| traceId 注入 | Gateway 注入 → 服务读取 header → 日志/响应携带 |
|
| traceId 注入 | Gateway 注入 → 服务读取 header → 日志/响应携带 |
|
||||||
@@ -97,7 +97,7 @@
|
|||||||
### 1.7 微前端 Module Federation
|
### 1.7 微前端 Module Federation
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| --------------------- | -------------------------------------------------------------------------------------------- |
|
| ---------------------- | ---------------------------------------------------------------------------- |
|
||||||
| 4 个稳定 portal | teacher-portal / student-portal / parent-app / admin-console,按场景域划分 |
|
| 4 个稳定 portal | teacher-portal / student-portal / parent-app / admin-console,按场景域划分 |
|
||||||
| P1 测试页 | teacher-portal 仅一个测试页验证 classes CRUD 链路,P2 起配 Module Federation |
|
| P1 测试页 | teacher-portal 仅一个测试页验证 classes CRUD 链路,P2 起配 Module Federation |
|
||||||
| 视口驱动渲染 | 侧边栏由 `viewports.L1` 驱动渲染,路由由 `viewports.L2` 控制 |
|
| 视口驱动渲染 | 侧边栏由 `viewports.L1` 驱动渲染,路由由 `viewports.L2` 控制 |
|
||||||
@@ -107,7 +107,7 @@
|
|||||||
### 1.8 从旧项目迁移的通用经验
|
### 1.8 从旧项目迁移的通用经验
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| ----------------------------- | ----------------------------------------------------------------------------------------------- |
|
| --------------------- | ------------------------------------------------------------------------------------ |
|
||||||
| React 19 乐观更新 | `useOptimistic` 替代手动 isPending,配合 `useTransition` 自动管理回滚 |
|
| React 19 乐观更新 | `useOptimistic` 替代手动 isPending,配合 `useTransition` 自动管理回滚 |
|
||||||
| Zustand 细粒度选择器 | 单字段 selector 优于 `useShallow` 多字段包装 |
|
| Zustand 细粒度选择器 | 单字段 selector 优于 `useShallow` 多字段包装 |
|
||||||
| Tiptap SSR | 必须 `immediatelyRender: false` 避免 hydration mismatch |
|
| Tiptap SSR | 必须 `immediatelyRender: false` 避免 hydration mismatch |
|
||||||
@@ -129,13 +129,13 @@
|
|||||||
### 1.9 架构工具与验证命令
|
### 1.9 架构工具与验证命令
|
||||||
|
|
||||||
| 场景 | 命令/规则 |
|
| 场景 | 命令/规则 |
|
||||||
| --------------------- | ---------------------------------------------------------------------- |
|
| ------------------- | ----------------------------------------------------------- |
|
||||||
| arch.db 扫描 | `npm run arch:scan`(多语言:TS+Go+Python) |
|
| arch.db 扫描 | `pnpm run arch:scan`(多语言:TS+Go+Python+Proto) |
|
||||||
| arch.db 查询 | `npm run arch:query -- <command>` |
|
| arch.db 查询 | `pnpm run arch:query -- <command>` |
|
||||||
| 查服务依赖 | `npm run arch:query -- service <service>` |
|
| 查服务依赖 | `pnpm run arch:query -- deps <module>` |
|
||||||
| 查 proto 契约 | `npm run arch:query -- contracts` |
|
| 查 proto 契约 | `pnpm run arch:query -- sql "SELECT * FROM contracts"` |
|
||||||
| 查 Kafka 事件 | `npm run arch:query -- events` |
|
| 查 Kafka 事件 | `pnpm run arch:query -- sql "SELECT * FROM events"` |
|
||||||
| 查架构违规 | `npm run arch:query -- violations`(输出 0 为合格) |
|
| 查架构违规 | `pnpm run arch:query -- violations`(骨架,P1 后期补全) |
|
||||||
| proto lint | `cd packages/shared-proto && pnpm exec buf lint` |
|
| proto lint | `cd packages/shared-proto && pnpm exec buf lint` |
|
||||||
| proto breaking 检测 | `pnpm exec buf breaking --against '.git#branch=main'` |
|
| proto breaking 检测 | `pnpm exec buf breaking --against '.git#branch=main'` |
|
||||||
| proto 代码生成 | `pnpm proto:gen` |
|
| proto 代码生成 | `pnpm proto:gen` |
|
||||||
@@ -152,7 +152,7 @@
|
|||||||
### 2.1 api-gateway(Go)
|
### 2.1 api-gateway(Go)
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| ------------------- | ------------------------------------------------------------------------------------------ |
|
| -------------- | ------------------------------------------------------------------------------- |
|
||||||
| P1 鉴权 | Gateway 内置 HS256 JWT,`jwt.ParseWithClaims` + `SigningMethodHMAC` 校验 |
|
| P1 鉴权 | Gateway 内置 HS256 JWT,`jwt.ParseWithClaims` + `SigningMethodHMAC` 校验 |
|
||||||
| P2 鉴权升级 | 改 RS256,IAM 私钥签发,Gateway 公钥校验,无需调 IAM |
|
| P2 鉴权升级 | 改 RS256,IAM 私钥签发,Gateway 公钥校验,无需调 IAM |
|
||||||
| 路由转发 | `gin.Group("/api/v1")` + `httputil.NewSingleHostReverseProxy` |
|
| 路由转发 | `gin.Group("/api/v1")` + `httputil.NewSingleHostReverseProxy` |
|
||||||
@@ -165,7 +165,7 @@
|
|||||||
### 2.2 classes(TS/NestJS,P1 黄金模板)
|
### 2.2 classes(TS/NestJS,P1 黄金模板)
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| ------------------------- | ----------------------------------------------------------------------------------------------- |
|
| ---------------- | ------------------------------------------------------------------------------------------------ |
|
||||||
| 黄金模板定位 | P1 完整实现所有横切关注点,后续 8 个服务复制此模板 |
|
| 黄金模板定位 | P1 完整实现所有横切关注点,后续 8 个服务复制此模板 |
|
||||||
| 黄金模板复制流程 | `cp -r services/classes services/xxx` → 改错误码前缀 → 改 proto → 改业务逻辑 → 改 README → 改 CI |
|
| 黄金模板复制流程 | `cp -r services/classes services/xxx` → 改错误码前缀 → 改 proto → 改业务逻辑 → 改 README → 改 CI |
|
||||||
| 横切关注点清单 | 错误处理 / 可观测 / 安全 / 契约 / 测试 / 文档 / 配置 / i18n / CI / Dockerfile |
|
| 横切关注点清单 | 错误处理 / 可观测 / 安全 / 契约 / 测试 / 文档 / 配置 / i18n / CI / Dockerfile |
|
||||||
@@ -184,7 +184,7 @@
|
|||||||
### 2.3 iam(TS/NestJS,P2)
|
### 2.3 iam(TS/NestJS,P2)
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| --------------------- | ------------------------------------------------------------------------------------------ |
|
| -------------- | ------------------------------------------------------------------------------------------------------------------- |
|
||||||
| 认证 | 登录/登出/JWT/2FA,RS256 非对称签名 |
|
| 认证 | 登录/登出/JWT/2FA,RS256 非对称签名 |
|
||||||
| RBAC | 角色/权限/角色-权限 CRUD + `getEffectivePermissions(userId)` API |
|
| RBAC | 角色/权限/角色-权限 CRUD + `getEffectivePermissions(userId)` API |
|
||||||
| 视口配置 | 4 层模型(导航/路由/组件/数据),`role_viewports` 表 |
|
| 视口配置 | 4 层模型(导航/路由/组件/数据),`role_viewports` 表 |
|
||||||
@@ -197,7 +197,7 @@
|
|||||||
### 2.4 core-edu(TS/NestJS,P3)
|
### 2.4 core-edu(TS/NestJS,P3)
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| --------------------- | ------------------------------------------------------------------------------------------ |
|
| -------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
||||||
| 考试全生命周期 | 教师创建 → 发布 → 学生作答 → 教师批改 → 成绩统计 |
|
| 考试全生命周期 | 教师创建 → 发布 → 学生作答 → 教师批改 → 成绩统计 |
|
||||||
| Outbox 模式 | 业务事务同写 `outbox_events` 表,后台 relay worker 投递 Kafka |
|
| Outbox 模式 | 业务事务同写 `outbox_events` 表,后台 relay worker 投递 Kafka |
|
||||||
| Outbox relay | Go 写独立服务 `services/outbox-relay/`,轻量高吞吐 |
|
| Outbox relay | Go 写独立服务 `services/outbox-relay/`,轻量高吞吐 |
|
||||||
@@ -210,7 +210,7 @@
|
|||||||
### 2.5 content(TS/NestJS,P4)
|
### 2.5 content(TS/NestJS,P4)
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| --------------------- | ------------------------------------------------------------------------------------------ |
|
| ---------- | ------------------------------------------------------------------ |
|
||||||
| 知识图谱 | Neo4j 查询前置依赖图(秒级返回) |
|
| 知识图谱 | Neo4j 查询前置依赖图(秒级返回) |
|
||||||
| 题库 CRUD | P4 仅 CRUD,P5 引入 ES 实现检索,避免 MySQL FULLTEXT → ES 迁移成本 |
|
| 题库 CRUD | P4 仅 CRUD,P5 引入 ES 实现检索,避免 MySQL FULLTEXT → ES 迁移成本 |
|
||||||
| 双写避免 | Neo4j/ES 不直接双写,由消费 Kafka 事件同步,天然最终一致 |
|
| 双写避免 | Neo4j/ES 不直接双写,由消费 Kafka 事件同步,天然最终一致 |
|
||||||
@@ -219,7 +219,7 @@
|
|||||||
### 2.6 data-ana(Python/FastAPI,P4)
|
### 2.6 data-ana(Python/FastAPI,P4)
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| --------------------- | ------------------------------------------------------------------------------------------ |
|
| ------------ | ------------------------------------------------------------------------------ |
|
||||||
| 学情诊断 | ClickHouse 宽表查询,5s 内返回 |
|
| 学情诊断 | ClickHouse 宽表查询,5s 内返回 |
|
||||||
| CDC 链路 | Debezium 监听 MySQL binlog → Kafka(`mysql.cdc.*`)→ DataAna 消费写 ClickHouse |
|
| CDC 链路 | Debezium 监听 MySQL binlog → Kafka(`mysql.cdc.*`)→ DataAna 消费写 ClickHouse |
|
||||||
| CDC 延迟监控 | Debezium 暴露 lag metrics,超阈值告警 |
|
| CDC 延迟监控 | Debezium 暴露 lag metrics,超阈值告警 |
|
||||||
@@ -229,7 +229,7 @@
|
|||||||
### 2.7 messaging(TS/NestJS,P5)
|
### 2.7 messaging(TS/NestJS,P5)
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| --------------------- | ------------------------------------------------------------------------------------------ |
|
| -------------- | -------------------------------------------------------------------- |
|
||||||
| 消息 CRUD | 会话/消息 + 调 Push Gateway 推送 + 通知偏好 |
|
| 消息 CRUD | 会话/消息 + 调 Push Gateway 推送 + 通知偏好 |
|
||||||
| 通知批量化 | `createNotifications(items)` 单次 INSERT,沿用旧项目 dispatcher 模式 |
|
| 通知批量化 | `createNotifications(items)` 单次 INSERT,沿用旧项目 dispatcher 模式 |
|
||||||
| 多渠道 | 站内/SMS/邮件/微信,in_app 批量 + 其他渠道并行 |
|
| 多渠道 | 站内/SMS/邮件/微信,in_app 批量 + 其他渠道并行 |
|
||||||
@@ -239,7 +239,7 @@
|
|||||||
### 2.8 push-gateway(Go,P5)
|
### 2.8 push-gateway(Go,P5)
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| --------------------- | ------------------------------------------------------------------------------------------ |
|
| ---------------- | ----------------------------------------------- |
|
||||||
| WebSocket 长连接 | 单节点支撑 10w+ 连接,业务服务只需发 Kafka 消息 |
|
| WebSocket 长连接 | 单节点支撑 10w+ 连接,业务服务只需发 Kafka 消息 |
|
||||||
| 跨实例同步 | Redis PubSub |
|
| 跨实例同步 | Redis PubSub |
|
||||||
| 离线消息 | 仅推在线用户,离线消息存 MySQL,上线时拉取 |
|
| 离线消息 | 仅推在线用户,离线消息存 MySQL,上线时拉取 |
|
||||||
@@ -247,7 +247,7 @@
|
|||||||
### 2.9 ai-gateway(Python/FastAPI,P5)
|
### 2.9 ai-gateway(Python/FastAPI,P5)
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| --------------------- | ------------------------------------------------------------------------------------------ |
|
| ----------------- | ------------------------------------------- |
|
||||||
| LLM Provider 适配 | OpenAI/Anthropic,langchain/litellm 生态 |
|
| LLM Provider 适配 | OpenAI/Anthropic,langchain/litellm 生态 |
|
||||||
| Prompt 模板管理 | 版本管理友好 |
|
| Prompt 模板管理 | 版本管理友好 |
|
||||||
| 流式 SSE | AI 网关 → BFF → 前端三层透传,BFF 不缓冲 |
|
| 流式 SSE | AI 网关 → BFF → 前端三层透传,BFF 不缓冲 |
|
||||||
@@ -257,7 +257,7 @@
|
|||||||
### 2.10 shared-proto(契约包)
|
### 2.10 shared-proto(契约包)
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| --------------------- | ------------------------------------------------------------------------------------------ |
|
| ------------ | ------------------------------------------------------------------------------- |
|
||||||
| 目录结构 | `proto/*.proto` + `buf.yaml` + `buf.gen.yaml` |
|
| 目录结构 | `proto/*.proto` + `buf.yaml` + `buf.gen.yaml` |
|
||||||
| P1 契约 | 仅 `classes.proto`,`iam.proto`/`core_edu.proto` 占位 |
|
| P1 契约 | 仅 `classes.proto`,`iam.proto`/`core_edu.proto` 占位 |
|
||||||
| 代码生成输出 | TS → `shared-ts/generated`,Go → `shared-go/`,Python → `services/*/generated/` |
|
| 代码生成输出 | TS → `shared-ts/generated`,Go → `shared-go/`,Python → `services/*/generated/` |
|
||||||
@@ -265,10 +265,10 @@
|
|||||||
### 2.11 arch-scan(多语言扫描器)
|
### 2.11 arch-scan(多语言扫描器)
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| --------------------- | ------------------------------------------------------------------------------------------ |
|
| -------------- | ----------------------------------------------------------------------------------------------- |
|
||||||
| TS 扫描 | ts-morph 解析 AST,提取导出/函数/类/import |
|
| TS 扫描 | regex 提取(function/class/interface/UPPER_CASE const),避免 ts-morph 对未安装依赖文件解析失败 |
|
||||||
| Go 扫描 | P1 用正则提取(函数/类型/import),P2 起替换为 tree-sitter-go AST |
|
| Go 扫描 | 正则提取(行首锚定 `^func`/`^type`),P2 起替换为 tree-sitter-go AST |
|
||||||
| Python 扫描 | P1 用正则提取,P4 起替换为 tree-sitter-python AST |
|
| Python 扫描 | 正则提取(行首锚定 `^def`/`^class`),P4 起替换为 tree-sitter-python AST |
|
||||||
| arch.db schema | modules/symbols/dependencies/contracts/events/violations 六表 |
|
| arch.db schema | modules/symbols/dependencies/contracts/events/violations 六表 |
|
||||||
| 全量扫描 | 先清空旧数据再扫描,避免残留 |
|
| 全量扫描 | 先清空旧数据再扫描,避免残留 |
|
||||||
| 并行扫描风险 | 并行子代理执行 arch:scan 可能因竞争报 FOREIGN KEY 错误,必须串行执行 |
|
| 并行扫描风险 | 并行子代理执行 arch:scan 可能因竞争报 FOREIGN KEY 错误,必须串行执行 |
|
||||||
@@ -278,7 +278,7 @@
|
|||||||
### 2.12 teacher-portal(微前端宿主,P1 测试页)
|
### 2.12 teacher-portal(微前端宿主,P1 测试页)
|
||||||
|
|
||||||
| 场景 | 技术/规则 |
|
| 场景 | 技术/规则 |
|
||||||
| --------------------- | ------------------------------------------------------------------------------------------ |
|
| -------------------- | ------------------------------------------------------------------------- |
|
||||||
| P1 测试页 | 单一 Next.js 应用,验证 classes CRUD 端到端链路 |
|
| P1 测试页 | 单一 Next.js 应用,验证 classes CRUD 端到端链路 |
|
||||||
| API 调用 | `fetch(${API_BASE}/api/v1/classes)` + `Authorization: Bearer ${TEST_JWT}` |
|
| API 调用 | `fetch(${API_BASE}/api/v1/classes)` + `Authorization: Bearer ${TEST_JWT}` |
|
||||||
| P1 测试 JWT | 开发工具生成 HS256 token,P2 起由 IAM 签发 RS256 |
|
| P1 测试 JWT | 开发工具生成 HS256 token,P2 起由 IAM 签发 RS256 |
|
||||||
@@ -291,5 +291,14 @@
|
|||||||
> 按时间倒序,50 条上限。AI 发现更好方案时可更新本节。
|
> 按时间倒序,50 条上限。AI 发现更好方案时可更新本节。
|
||||||
|
|
||||||
| 日期 | 时间 | 模块 | 做了什么 + 学到什么 |
|
| 日期 | 时间 | 模块 | 做了什么 + 学到什么 |
|
||||||
| ---------- | ----- | ---- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ---------- | ---- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
|
| 2026-07-08 | 全天 | 全局 | **P6 后续工作手册执行**:完整执行 post-p6-followup.md 12 节任务。环境准备(pnpm 925 包 + go mod tidy 双服务 + uv sync 双服务 + buf 安装)→ 代码质量校验(Go vet/build 0 错误,Python ruff 8 错误自动修复)→ arch.db 同步(实现 4 个扫描器骨架,输出 12 模块/233 符号/138 契约)→ project_rules.md P0 修复(迁移到 .trae/rules/,17881 字节)→ 004 架构图修复(1.1a/1.1b 双图 + 1.2 业务领域列 + 5.4 视口四层)→ P6 集成测试(10 Go + 17 bash = 27 用例全通过)→ Helm Chart 演化(8 chart lint 通过)。**学到**:多语言 monorepo 工具链配置需统一镜像源(npmmirror/goproxy.cn/tuna),go.work BOM 字符会导致 `unexpected input character` 错误必须重写文件。 |
|
||||||
|
| 2026-07-08 | 上午 | 全局 | pnpm install 网络失败(ECONNRESET)→ 配置 `npm config set registry https://registry.npmmirror.com` + `pnpm config set registry https://registry.npmmirror.com` 重试成功。**学到**:Windows 下 pnpm 还需配置 `PNPM_HOME` 和 `TMP` 环境变量避免 `_tmp_` 文件 ENOENT 错误。 |
|
||||||
|
| 2026-07-08 | 上午 | 全局 | project_rules.md 损坏(72 字节乱码,从 P1 提交 2ba4250 就损坏,git 历史无完整版本)→ 从 CICD 项目完整版迁移到 `e:\Desktop\Edu\.trae\rules\project_rules.md`(按用户要求放 .trae/rules/),按 MIGRATION_GUIDE 4.1 策略矩阵调整为微服务版(13 章 17881 字节),删除根目录损坏文件,更新 7 处引用(README/MIGRATION_GUIDE/004/known-issues/git-workflow/coding-standards)。**学到**:迁移文件后必须 `Get-Item | Select Length` 验证完整性 + 全文搜索引用更新,git commit 前运行 cat 检查内容。 |
|
||||||
|
| 2026-07-08 | 上午 | api-gateway | go.work BOM 字符 + 版本不匹配:`unexpected input character '\ufeff'` 和 `module requires go >= 1.22.0, but go.work lists go 1.22`。**修复**:重写 go.work 去除 BOM,版本改为 `go 1.26.0`,移除不存在的 `./packages/shared-go`。**学到**:PowerShell `Out-File` 默认加 BOM,写 go.work 这类敏感文件应用 `Write` 工具或 `[System.IO.File]::WriteAllText` 指定 UTF8 无 BOM。 |
|
||||||
|
| 2026-07-08 | 上午 | arch-scan | arch:scan 返回 0 模块 0 符号 → 4 个扫描器(ts/go/py/proto)都是骨架实现。**修复**:完整实现 4 个扫描器,TS 用 regex 提取(避免 ts-morph 对未安装依赖文件解析失败),Go/Python 用行首锚定正则,Proto 扫描 service/message/rpc。结果:12 模块(≥10 ✓)、233 符号(≥100 ✓)、138 契约。**学到**:ts-morph Project 对未 `pnpm install` 的 workspace 文件会报模块解析失败,改用 regex 更鲁棒;scanner.ts main() 开头需 `DELETE FROM` 清空旧数据避免重跑重复。 |
|
||||||
|
| 2026-07-08 | 下午 | 004 | 架构图视角讨论(技术分层 vs 业务领域)→ 双图并存方案:1.1a 技术分层视角(部署/流量/网络边界,Users 层标注"场景域用户",BFF 层标注"按场景域分")+ 1.1b 业务领域视角(6 DDD 限界上下文 subgraph:D1 身份/D2 教学组织/D3 教学核心/D4 内容/D5 沟通/D6 智能洞察)。1.2 服务清单新增"业务领域"列。**学到**:双图互补,1.1a 服务运维/SRE 视角,1.1b 服务产品/架构视角;同一服务可横跨多领域(core-edu 同时承载 D2+D3)。 |
|
||||||
|
| 2026-07-08 | 下午 | 004 | 视口四层模型补充(5.4 章节):L1 导航(navigation_config 表)/ L2 路由(route_permission + Gateway 校验)/ L3 组件(usePermission().hasPermission)/ L4 数据(DataScope 枚举)。场景域 BFF 复用策略:按使用场景域分 BFF 而非按角色分,教导主任复用 Teacher BFF + 额外管理视口。iam 服务职责:认证 + RBAC + 视口配置 + DataScope + 权限解析 API。**学到**:视口既可独立配置(RoleViewport 表)也可由权限推导,新角色只需配权限集,视口自动推导。 |
|
||||||
|
| 2026-07-08 | 下午 | api-gateway | P6 集成测试补充:circuit-breaker_test.go(5 用例:ClosedToOpen/OpenToHalfOpen/HalfOpenToClosed/HalfOpenToOpen/4xxNotCounted)+ ratelimit_test.go(5 用例:AllowUnderBurst/RejectOverBurst/RefillTokens/PerIPIsolation/CleanupExpiredBuckets)+ test-backup-mysql.sh(8 用例 17 断言)。**学到**:gobreaker v2 ReadyToTrip 在 1 次失败后就触发(`TotalFailures*2 > Requests` 当 Requests=1 时 1*2>1=true),HALF_OPEN 状态只在探测执行期间可见,探测完成后立即转 CLOSED 或回 OPEN,测试需通过行为(503 vs 500)而非状态字段验证;rateLimiter cleanup 测试需用短周期参数(50ms/500ms)加速,且新鲜桶要在旧桶清理后再创建避免被一起清掉。 |
|
||||||
|
| 2026-07-08 | 下午 | infra/k8s | Helm Chart 演化:安装 Helm v4.2.2,创建 edu-platform 平台级 chart(namespace/configmap/secret/ingress/hpa + 4 环境 values 文件)+ api-gateway 服务级 chart(完整迁移自原 deployment.yaml,参数化所有字段)+ 6 业务服务 chart 桩(iam/core-edu/content/msg/data-ana/ai)。删除原 api-gateway-deployment.yaml,保留 namespace.yaml。**学到**:Helm `{{- with ... -}}` 双向修剪会导致标签连在一行(`managed-by: Helmpart-of: edu-platform`),应改为 `{{- with ... }}` 只修剪左侧;`helm lint` 全部通过但 `helm template` 才能发现 YAML 渲染错误,验证时两个都要跑。 |
|
||||||
| 2026-07-07 | 全天 | 全局 | 文档体系初始化:从旧项目(e:\Desktop\CICD,Next.js 单体)迁移 spec + plan + known-issues 模板到新仓库(e:\Desktop\Edu,微服务架构)。known-issues 重组为微服务分区:多语言 monorepo / Docker Compose / protobuf+buf / NestJS / Go Gateway / 可观测性 / 微前端。从旧项目提炼可迁移经验:React 19 useOptimistic / Zustand 细粒度选择器 / Tiptap SSR / 请求级去重 / 批量 SQL / 动态导入模式 / arch:scan 串行执行。新增微服务特有经验:契约先行 / Outbox / CDC / 双轨读 / DataScope / 黄金模板复制流程。路线图按 6 阶段组织:P1 地基 → P2 身份 → P3 核心教学 → P4 内容分析 → P5 沟通AI → P6 硬化。 |
|
| 2026-07-07 | 全天 | 全局 | 文档体系初始化:从旧项目(e:\Desktop\CICD,Next.js 单体)迁移 spec + plan + known-issues 模板到新仓库(e:\Desktop\Edu,微服务架构)。known-issues 重组为微服务分区:多语言 monorepo / Docker Compose / protobuf+buf / NestJS / Go Gateway / 可观测性 / 微前端。从旧项目提炼可迁移经验:React 19 useOptimistic / Zustand 细粒度选择器 / Tiptap SSR / 请求级去重 / 批量 SQL / 动态导入模式 / arch:scan 串行执行。新增微服务特有经验:契约先行 / Outbox / CDC / 双轨读 / DataScope / 黄金模板复制流程。路线图按 6 阶段组织:P1 地基 → P2 身份 → P3 核心教学 → P4 内容分析 → P5 沟通AI → P6 硬化。 |
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ pnpm test
|
|||||||
## 环境变量
|
## 环境变量
|
||||||
|
|
||||||
| 变量 | 说明 |
|
| 变量 | 说明 |
|
||||||
|------|------|
|
| ----------------------------- | ------------------------------- |
|
||||||
| `PORT` | 服务端口(默认 3005) |
|
| `PORT` | 服务端口(默认 3005) |
|
||||||
| `DATABASE_URL` | MySQL 连接串 |
|
| `DATABASE_URL` | MySQL 连接串 |
|
||||||
| `NEO4J_URL` | Neo4j Bolt 连接 URL |
|
| `NEO4J_URL` | Neo4j Bolt 连接 URL |
|
||||||
@@ -60,6 +60,15 @@ src/
|
|||||||
- `TextbooksService.createKnowledgeGraph` 在 Neo4j 构建知识点前置依赖
|
- `TextbooksService.createKnowledgeGraph` 在 Neo4j 构建知识点前置依赖
|
||||||
- `TextbooksService.getPrerequisites` 查询知识点前置链路
|
- `TextbooksService.getPrerequisites` 查询知识点前置链路
|
||||||
|
|
||||||
|
## 健康检查
|
||||||
|
|
||||||
|
| 端点 | 用途 | 鉴权 |
|
||||||
|
| -------------- | ------------------------------------------------- | ---- |
|
||||||
|
| `GET /healthz` | 存活探针(liveness),仅返回进程状态,不检查依赖 | 无 |
|
||||||
|
| `GET /readyz` | 就绪探针(readiness),检查 DB 连接,失败返回 503 | 无 |
|
||||||
|
|
||||||
|
实现见 `src/shared/health/health.controller.ts`,5 个 NestJS 服务(iam/core-edu/content/msg/classes)一致。
|
||||||
|
|
||||||
## 对外契约
|
## 对外契约
|
||||||
|
|
||||||
gRPC 服务 `TextbookService`、`KnowledgeGraphService` 定义见 `packages/shared-proto/proto/content.proto`。
|
gRPC 服务 `TextbookService`、`KnowledgeGraphService` 定义见 `packages/shared-proto/proto/content.proto`。
|
||||||
|
|||||||
@@ -44,9 +44,18 @@ pnpm test
|
|||||||
## 环境变量
|
## 环境变量
|
||||||
|
|
||||||
| 变量 | 说明 | 默认 |
|
| 变量 | 说明 | 默认 |
|
||||||
|------|------|------|
|
| ----------------------------- | ----------------------------- | -------------- |
|
||||||
| `PORT` | 服务端口 | 3004 |
|
| `PORT` | 服务端口 | 3004 |
|
||||||
| `DATABASE_URL` | MySQL 连接串 | - |
|
| `DATABASE_URL` | MySQL 连接串 | - |
|
||||||
| `KAFKA_BROKERS` | Kafka broker 列表(逗号分隔) | localhost:9092 |
|
| `KAFKA_BROKERS` | Kafka broker 列表(逗号分隔) | localhost:9092 |
|
||||||
| `JWT_SECRET` | JWT 密钥 | - |
|
| `JWT_SECRET` | JWT 密钥 | - |
|
||||||
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP 上报地址(可选) | - |
|
| `OTEL_EXPORTER_OTLP_ENDPOINT` | OTLP 上报地址(可选) | - |
|
||||||
|
|
||||||
|
## 健康检查
|
||||||
|
|
||||||
|
| 端点 | 用途 | 鉴权 |
|
||||||
|
| -------------- | ------------------------------------------------- | ---- |
|
||||||
|
| `GET /healthz` | 存活探针(liveness),仅返回进程状态,不检查依赖 | 无 |
|
||||||
|
| `GET /readyz` | 就绪探针(readiness),检查 DB 连接,失败返回 503 | 无 |
|
||||||
|
|
||||||
|
实现见 `src/shared/health/health.controller.ts`,5 个 NestJS 服务(iam/core-edu/content/msg/classes)一致。
|
||||||
|
|||||||
@@ -24,12 +24,21 @@
|
|||||||
## API
|
## API
|
||||||
|
|
||||||
| Method | Path | 说明 |
|
| Method | Path | 说明 |
|
||||||
|--------|------|------|
|
| ------ | --------------- | --------------------------------- |
|
||||||
| POST | `/iam/register` | 注册 |
|
| POST | `/iam/register` | 注册 |
|
||||||
| POST | `/iam/login` | 登录 |
|
| POST | `/iam/login` | 登录 |
|
||||||
| POST | `/iam/refresh` | 刷新令牌 |
|
| POST | `/iam/refresh` | 刷新令牌 |
|
||||||
| GET | `/iam/me` | 当前用户信息(需 `x-user-id` 头) |
|
| GET | `/iam/me` | 当前用户信息(需 `x-user-id` 头) |
|
||||||
|
|
||||||
|
## 健康检查
|
||||||
|
|
||||||
|
| 端点 | 用途 | 鉴权 |
|
||||||
|
| -------------- | ------------------------------------------------- | ---- |
|
||||||
|
| `GET /healthz` | 存活探针(liveness),仅返回进程状态,不检查依赖 | 无 |
|
||||||
|
| `GET /readyz` | 就绪探针(readiness),检查 DB 连接,失败返回 503 | 无 |
|
||||||
|
|
||||||
|
实现见 `src/shared/health/health.controller.ts`,5 个 NestJS 服务(iam/core-edu/content/msg/classes)一致。
|
||||||
|
|
||||||
## 数据表
|
## 数据表
|
||||||
|
|
||||||
`iam_users` / `iam_roles` / `iam_user_roles` / `iam_permissions` / `iam_role_permissions` / `iam_refresh_tokens`
|
`iam_users` / `iam_roles` / `iam_user_roles` / `iam_permissions` / `iam_role_permissions` / `iam_refresh_tokens`
|
||||||
|
|||||||
@@ -26,16 +26,25 @@ pnpm dev # http://localhost:3007
|
|||||||
## API
|
## API
|
||||||
|
|
||||||
| 方法 | 路径 | 说明 |
|
| 方法 | 路径 | 说明 |
|
||||||
|------|------|------|
|
| ---- | ------------------------ | ---------------- |
|
||||||
| POST | /notifications | 发送通知 |
|
| POST | /notifications | 发送通知 |
|
||||||
| GET | /notifications | 查询用户通知列表 |
|
| GET | /notifications | 查询用户通知列表 |
|
||||||
| POST | /notifications/:id/read | 标记已读 |
|
| POST | /notifications/:id/read | 标记已读 |
|
||||||
| GET | /notifications/search?q= | 全文检索通知 |
|
| GET | /notifications/search?q= | 全文检索通知 |
|
||||||
|
|
||||||
|
## 健康检查
|
||||||
|
|
||||||
|
| 端点 | 用途 | 鉴权 |
|
||||||
|
| -------------- | ------------------------------------------------- | ---- |
|
||||||
|
| `GET /healthz` | 存活探针(liveness),仅返回进程状态,不检查依赖 | 无 |
|
||||||
|
| `GET /readyz` | 就绪探针(readiness),检查 DB 连接,失败返回 503 | 无 |
|
||||||
|
|
||||||
|
实现见 `src/shared/health/health.controller.ts`,5 个 NestJS 服务(iam/core-edu/content/msg/classes)一致。
|
||||||
|
|
||||||
## 环境变量
|
## 环境变量
|
||||||
|
|
||||||
| 变量 | 默认值 | 说明 |
|
| 变量 | 默认值 | 说明 |
|
||||||
|------|--------|------|
|
| ------------- | --------------------- | ------------------ |
|
||||||
| PORT | 3007 | 服务端口 |
|
| PORT | 3007 | 服务端口 |
|
||||||
| DATABASE_URL | - | MySQL 连接串 |
|
| DATABASE_URL | - | MySQL 连接串 |
|
||||||
| KAFKA_BROKERS | localhost:9092 | Kafka broker 列表 |
|
| KAFKA_BROKERS | localhost:9092 | Kafka broker 列表 |
|
||||||
|
|||||||
Reference in New Issue
Block a user