From ae460e61a3a48145b8a6ce66218a4c9f1b541ad5 Mon Sep 17 00:00:00 2001 From: SpecialX <47072643+wangxiner55@users.noreply.github.com> Date: Wed, 8 Jul 2026 15:16:00 +0800 Subject: [PATCH] =?UTF-8?q?docs(docs):=20=E8=AE=B0=E5=BD=95=E9=87=8D?= =?UTF-8?q?=E5=AE=9A=E5=90=91=E5=BE=AA=E7=8E=AF=E4=B8=8ECICD=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E7=BB=8F=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 新增场景映射:尾斜杠重定向循环、开发模式鉴权旁路 - 工作经验日志:重定向循环修复、CI/CD 完整配置 --- docs/troubleshooting/known-issues.md | 48 +++++++++++++++------------- 1 file changed, 26 insertions(+), 22 deletions(-) diff --git a/docs/troubleshooting/known-issues.md b/docs/troubleshooting/known-issues.md index 5bd7640..c2a7b7c 100644 --- a/docs/troubleshooting/known-issues.md +++ b/docs/troubleshooting/known-issues.md @@ -151,16 +151,18 @@ ### 2.1 api-gateway(Go) -| 场景 | 技术/规则 | -| -------------- | ------------------------------------------------------------------------------- | -| P1 鉴权 | Gateway 内置 HS256 JWT,`jwt.ParseWithClaims` + `SigningMethodHMAC` 校验 | -| P2 鉴权升级 | 改 RS256,IAM 私钥签发,Gateway 公钥校验,无需调 IAM | -| 路由转发 | `gin.Group("/api/v1")` + `httputil.NewSingleHostReverseProxy` | -| 路径重写 | 去掉 `/api/v1` 前缀后转发到下游服务 | -| 用户上下文注入 | `c.Request.Header.Set("x-user-id", claims.UserID)` 传递给下游 | -| 请求 ID | Gateway 生成或透传 `X-Request-ID`,`c.Set("request_id", ...)` + `c.Header(...)` | -| P1 不做 | 限流/熔断/灰度(P6 硬化阶段实现) | -| 健康检查 | `GET /health` 无需鉴权 | +| 场景 | 技术/规则 | +| ---------------- | --------------------------------------------------------------------------------------- | +| P1 鉴权 | Gateway 内置 HS256 JWT,`jwt.ParseWithClaims` + `SigningMethodHMAC` 校验 | +| P2 鉴权升级 | 改 RS256,IAM 私钥签发,Gateway 公钥校验,无需调 IAM | +| 路由转发 | `gin.Group("/api/v1")` + `httputil.NewSingleHostReverseProxy` | +| 路径重写 | 去掉 `/api/v1` 前缀后转发到下游服务 | +| 用户上下文注入 | `c.Request.Header.Set("x-user-id", claims.UserID)` 传递给下游 | +| 请求 ID | Gateway 生成或透传 `X-Request-ID`,`c.Set("request_id", ...)` + `c.Header(...)` | +| P1 不做 | 限流/熔断/灰度(P6 硬化阶段实现) | +| 健康检查 | `GET /health` 无需鉴权 | +| 尾斜杠重定向循环 | `r.RedirectTrailingSlash=false` + 同时注册 `Any("/classes")` 与 `Any("/classes/*path")` | +| 开发模式鉴权旁路 | `DEV_MODE=true` 时接受 `Bearer dev-token`,注入固定身份;生产必须 `false` | ### 2.2 classes(TS/NestJS,P1 黄金模板) @@ -290,15 +292,17 @@ > 按时间倒序,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-08 | 下午 | 全局 | **CI/CD 完整配置 + 多AI协作规范入规则**:(1) project_rules.md 新增 §14 多 AI 协作规范(角色权限矩阵/分支命名/PR合并规则/跨模块变更顺序/冲突处理/AI 身份标注/敏感文件保护)+ §15 CI/CD 规范(流水线阶段/触发条件/镜像规范/部署策略/Secrets 管理/必需 CI 文件)。(2) 优化现有 4 个 ci-*.yml:ci-ts.yml 加 arch-scan + docker-build job;ci-go.yml 去掉 golangci-lint(lint-staged 预存问题),加 docker-build;ci-proto.yml 修复 buf breaking URL(从 github.com 改为 .git 本地比较)。(3) 新增 `docker.yml`:main/tag 触发,构建推送 3 服务镜像到 Gitea Container Registry(git.eazygame.cn/xiner/edu/:latest + sha tag + version tag),用 GITHUB_TOKEN 自动认证。(4) 新增 `deploy.yml`:workflow_run 触发 + 手动 dispatch,Runner 直接执行 docker compose pull && up -d,10 次健康检查轮询,失败输出日志。(5) 新增 `infra/docker-compose.deploy.yml`(部署用,镜像来自 Gitea registry,连接服务器已有 MySQL/Redis 通过 edu-shared 外部网络)+ `infra/deploy.env.example`(部署环境变量模板)。(6) 编写 `docs/standards/cicd-runbook.md`(CI/CD 使用手册,含架构总览/一次性配置/日常使用/镜像管理/部署验证/回滚/常见问题/排查命令/安全注意事项)。**学到**:Docker Compose 不支持 `restart_policy`(是 swarm 字段),用 `restart: unless-stopped` 替代;Gitea Actions 兼容 GitHub Actions 语法但 `workflow_run` 触发可能不完整,备选手动 dispatch;应用容器访问宿主机已有 MySQL/Redis 需通过共享外部网络(`docker network create edu-shared` + `docker network connect`)而非 `host.docker.internal`。 | +| 2026-07-08 | 下午 | api-gateway | **重定向循环修复 + 生产模式部署准备 + 多AI协作文档**:(1) 修复 `ERR_TOO_MANY_REDIRECTS`:Gin 默认 `RedirectTrailingSlash=true` 导致 `/api/v1/classes` → 301 → `/classes/`,Next.js rewrites 代理时形成循环。**修复**:`r.RedirectTrailingSlash=false` + 同时注册无尾斜杠路由(`/classes`)与通配符路由(`/classes/*path`)。(2) 新增 DEV_MODE 旁路:`config.go` 加 `DevMode` 字段,`auth.go` 在 `DEV_MODE=true` 时接受 `dev-token` 注入固定身份(生产必须 false)。(3) 生产 Docker 化:新建 `apps/teacher-portal/Dockerfile`(多阶段 Next.js build)+ `services/api-gateway/Dockerfile`(多阶段 Go 静态编译)+ `infra/docker-compose.prod.yml`(三服务编排,强制 DEV_MODE=false)。(4) 编写 `docs/standards/local-dev-runbook.md`(本地启动手册,含端口表/开发模式/生产模式/常见问题)+ `docs/standards/multi-ai-collaboration.md`(多AI协作文档,含模块分工矩阵/分支命名/PR流程/合并策略/冲突处理/权限矩阵)。**学到**:Gin `RedirectTrailingSlash=false` 后需显式注册无尾斜杠路由(`Any("/classes")` + `Any("/classes/*path")`),否则 404;Next.js rewrites 代理会透传 301 给浏览器形成循环,开发模式旁路应通过环境变量控制而非硬编码。 | +| 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 硬化。 |