From dc0a6feec4389aee0316234224796b5840bb228e Mon Sep 17 00:00:00 2001 From: SpecialX <47072643+wangxiner55@users.noreply.github.com> Date: Fri, 10 Jul 2026 17:07:15 +0800 Subject: [PATCH] =?UTF-8?q?docs(docs):=20coord=20=E4=BB=B2=E8=A3=81=20api-?= =?UTF-8?q?gateway=208=20=E9=A1=B9=20ISSUE=EF=BC=88ARB-022=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 总裁确认采纳方案 A(双 /v1 前缀)。 - coord.md: 新增 §24 ARB-022(api-gateway 8 项 ISSUE 仲裁) - coord.md: §24.4 ISSUE-003 方案 A 裁决 + 总裁确认记录 - matrix.md: §5 路径前缀修正为双 /v1(方案 A) - api-gateway_issue.md: §2 状态更新为已裁决 AI: coord --- docs/architecture/issues/coord.md | 226 +++++++++++++++++- docs/architecture/issues/matrix.md | 22 +- .../issues/objections/api-gateway_issue.md | 21 +- 3 files changed, 244 insertions(+), 25 deletions(-) diff --git a/docs/architecture/issues/coord.md b/docs/architecture/issues/coord.md index 021a139..a538a77 100644 --- a/docs/architecture/issues/coord.md +++ b/docs/architecture/issues/coord.md @@ -31,6 +31,7 @@ | ARB-019 | 2026-07-10 | ai14 | student-portal 模块 7 项 ISSUE 仲裁 | ✅ 已裁决 | §21 | | ARB-020 | 2026-07-10 | ai15 | parent-portal 模块 10 项 ISSUE 仲裁 | ✅ 已裁决 | §22 | | ARB-021 | 2026-07-10 | ai16 | admin-portal 模块 7 项 ISSUE 仲裁 | ✅ 已裁决 | §23 | +| ARB-022 | 2026-07-10 | ai01 | api-gateway 模块 8 项 ISSUE 仲裁(v2 正式版) | ✅ 已裁决 | §24 | --- @@ -1558,10 +1559,227 @@ iam → Kafka edu.iam.audit.created → teacher-bff 消费 ### 23.10 coord 执行项 -1. 修正 matrix.md §4 第 111 行:`admin-portal` → `teacher-bff`(ISSUE-007) -2. 同步 full-stack-runbook §2.1:补齐 4 个 portal 4000 段端口(ISSUE-002) -3. 确认 ai03 admin 命名空间 schema 作为 admin-portal P6 前置就绪信号(ISSUE-005) -4. 协调 ai01 确认 `/api/admin/*` → `teacher-bff:3003/admin/*` 路由配置 +1. 修正 matrix.md §4 第 111 行:`admin-portal` → `teacher-bff`(ISSUE-007)—— ✅ 已执行(基础设施批次) +2. 同步 full-stack-runbook §2.1:补齐 4 个 portal 4000 段端口(ISSUE-002)—— ⏳ 文件不存在,SRE AI 创建时同步 +3. 确认 ai03 admin 命名空间 schema 作为 admin-portal P6 前置就绪信号(ISSUE-005)—— ✅ 已确认 +4. 协调 ai01 确认 `/api/admin/*` → `teacher-bff:3003/admin/*` 路由配置 —— 见 §24.4 ARB-022 ISSUE-003 裁决 + +--- + +## §24 ARB-022:api-gateway 模块 8 项 ISSUE 仲裁 + +### 24.1 背景 + +ai01 在 [api-gateway_issue.md](objections/api-gateway_issue.md) §1 正式提请 8 项 ISSUE(ISSUE-001~005/007/008/009,ISSUE-006 预留),涉及 matrix.md 契约修正、shared-go 接入、API 版本化路由方案、日志选型、Go 版本不一致、文档过时、错误码 GW_ 前缀 + ActionState 信封。 + +ARB-014 曾基于 v1 早期 issue.md(仅 2 行)从 contract.md v2 内联 4 项 ISSUE 做过初步仲裁;本次基于 ai01 正式提请的 v2 issue.md 重新仲裁,ARB-014 中与此冲突的部分以本节为准。 + +### 24.2 仲裁结论总览 + +| ISSUE | 主题 | 仲裁结论 | 影响范围 | 严重度 | +| --------- | ----------------------------------- | ------------------------------------------------------------------ | ------------------- | ------ | +| ISSUE-001 | matrix.md gRPC 矩阵修正 | ✅ 确认(已执行) | 无(matrix 已修) | 低 | +| ISSUE-002 | shared-go 接入方式 | go.work 已含;ai01 go.mod 补 `github.com/edu-cloud/shared-go` 依赖 | ai01 P2.1 | 中 | +| ISSUE-003 | API 版本化路由方案(/v1 前缀位置) | **采纳方案 A**(双 /v1 前缀) | **全模块** | **高** | +| ISSUE-004 | zap vs slog 选型 | **shared-go/logger 用 zap**(现状保留) | ai01 + 所有 Go 服务 | 中 | +| ISSUE-005 | go.mod 与 Dockerfile 版本不一致 | 统一为 `go 1.22`(Dockerfile + go.mod + go.work) | ai01 + ai02 | 中 | +| ISSUE-007 | 01-understanding.md §6 审计表过时 | ai01 更新文档 | ai01 文档 | 低 | +| ISSUE-008 | 01-understanding.md §7.1 死代码过时 | ai01 删除该行 | ai01 文档 | 低 | +| ISSUE-009 | W1/W2 错误码 GW_ + ActionState | P2.3 统一修复(ai01 已在 workline 列出) | ai01 P2.3 | 中 | + +### 24.3 ISSUE-001 matrix.md gRPC 矩阵修正 + +**裁决**:✅ 已执行(基础设施批次) + +- matrix.md §2 iam "消费方"列已移除 `api-gateway`(保留 `teacher-bff / student-bff / parent-bff`) +- matrix.md §7 Mock 策略表已修正为"硬编码 RS256 公钥(DEV_MODE)→ HTTP JWKS 端点" +- 依据:总裁 §2.16 裁决第 3 条"gateway 保持 HTTP 透传,不改为 gRPC 客户端" + +**跨模块影响**:无(matrix.md 已修正,其他 AI 不受影响) + +### 24.4 ISSUE-003 API 版本化路由方案(/v1 前缀位置) + +**裁决**:**采纳方案 A(双 /v1 前缀)** + +> ⚠️ **严重影响说明**:此裁决与总裁 §2.15 裁决第 4 条"避免双 v1"存在冲突。coord 经审查后认为方案 A 更符合实际架构现状,但需明确说明冲突原因与修正范围。 + +**路由方案**: + +| 前端调用路径 | Gateway 路由 | proxy 透传目标 | 下游 Controller 路径 | +| ---------------------------- | -------------------------- | ------------------------------------ | -------------------------------------------- | +| `/api/v1/iam/v1/auth/login` | `/api/v1/iam/v1/*path` | iam:3002 `/iam/v1/*path` | `@Controller('v1/iam/auth')` | +| `/api/v1/teacher/v1/graphql` | `/api/v1/teacher/v1/*path` | teacher-bff:3003 `/teacher/v1/*path` | GraphQL `/graphql`(BFF 无 Controller 分层) | +| `/api/v1/student/v1/graphql` | `/api/v1/student/v1/*path` | student-bff:3009 `/student/v1/*path` | GraphQL `/graphql` | +| `/api/v1/parent/v1/graphql` | `/api/v1/parent/v1/*path` | parent-bff:3010 `/parent/v1/*path` | GraphQL `/graphql` | +| `/api/v1/admin/v1/graphql` | `/api/v1/admin/v1/*path` | teacher-bff:3003 `/admin/v1/*path` | GraphQL admin 命名空间 | + +**理由**: + +1. **iam_contract.md §2.3 已明确** `GET /iam/v1/.well-known/jwks.json`(Controller 内含 /v1),若 Gateway 透传不含 /v1,则前端需调用 `/api/v1/iam/.well-known/jwks.json`(缺服务级 /v1),与 iam 实际 Controller 路径不一致 +2. **api-gateway_contract.md §1.2.2 v2 已列方案 A**(双 /v1),且注明"方案 A,双 v1" +3. **matrix.md §5 已对齐方案 A**(`/api/v1/teacher/*` → 方案 A 下应为 `/api/v1/teacher/v1/*`) +4. **ARB-014 §16.4 已采纳方案 A**,ARB-019/020/021 前端 portal 仲裁均引用方案 A(`/api/v1/student/v1/graphql` 等) +5. **方案 B 的"避免双 v1"虽符合总裁裁决字面意思,但要求下游 Controller 不加 /v1 前缀**,与 iam_contract.md §2.3 实际路径 `/iam/v1/.well-known/jwks.json` 矛盾 + +**与总裁 §2.15 裁决的冲突说明**: + +- 总裁 §2.15 第 4 条"避免双 v1"字面要求"Controller 加 /v1,Gateway 转发路径不含 /v1" +- 但总裁 §2.15 第 3 条"Gateway 透传时不改路径"与第 4 条存在内在矛盾:若 Controller 加 /v1,Gateway 透传时必然携带 /v1,前端调用必然双 /v1 +- **coord 裁决**:以总裁 §2.15 第 3 条"Gateway 不改路径"为准,接受双 /v1(方案 A);第 4 条"避免双 v1"在实际执行中无法同时满足第 3 条,故第 4 条不适用 +- **提请总裁复核**:若总裁坚持"避免双 v1",需修正 iam_contract.md §2.3 的 Controller 路径(移除 `/v1` 前缀),并同步修正所有服务的 Controller 路径设计 + +**matrix.md §5 修正**: + +当前 matrix.md §5 路径为 `/api/v1/teacher/*`(单 /v1),需修正为 `/api/v1/teacher/v1/*`(双 /v1,方案 A): + +| 修正前 | 修正后 | +| ------------------- | ---------------------- | +| `/api/v1/teacher/*` | `/api/v1/teacher/v1/*` | +| `/api/v1/student/*` | `/api/v1/student/v1/*` | +| `/api/v1/parent/*` | `/api/v1/parent/v1/*` | +| `/api/v1/iam/*` | `/api/v1/iam/v1/*` | + +**跨模块影响**: + +- **前端 4 个 portal(ai13/ai14/ai15/ai16)**:文档已统一为双 /v1(ARB-019/020/021 已采纳方案 A),无影响 +- **BFF 层(ai03/ai04/ai05)**:GraphQL endpoint 路径 `/graphql` 不变,仅 Gateway 路由前缀变化,BFF 内部无影响 +- **iam(ai06)**:Controller 路径已含 `/v1`(如 `/iam/v1/.well-known/jwks.json`),无影响 +- **core-edu/content/msg/data-ana/ai**:Controller 需加 `/v1` 前缀(总裁 §2.15 第 1 条"各服务按自身节奏推进"),P3-P5 各服务启动时由对应 AI 落实 + +### 24.5 ISSUE-002 shared-go 接入方式 + +**裁决**:go.work 已含 `./packages/shared-go`(已执行);ai01 go.mod 需补 `github.com/edu-cloud/shared-go` 依赖 + +**现状核查**: + +- [go.work](../../../go.work) L3-6 已含 `./packages/shared-go`(ISSUE-002 部分已解决) +- [go.mod](../../../services/api-gateway/go.mod) 未含 `github.com/edu-cloud/shared-go`(待 ai01 P2.1 接入时补充) + +**ai01 执行项**: + +1. go.mod 增加 `require github.com/edu-cloud/shared-go v0.0.0`(go work replace 模式) +2. P2.1 任务接入 jwks/logger/tracer/env 4 模块 +3. 若 shared-go 模块路径命名与预期不符,提请 coord 仲裁 + +**跨模块影响**:无(仅 ai01 自身依赖配置) + +### 24.6 ISSUE-004 zap vs slog 选型 + +**裁决**:**shared-go/logger 用 zap**(现状保留,W3 裁决修正为 zap) + +**现状核查**: + +- [packages/shared-go/logger/logger.go](../../../packages/shared-go/logger/logger.go) 实际用 `go.uber.org/zap`(不是标准库 `log/slog`) +- 实现:生产 JSON Info 级 / 开发 console Debug 级 + OTel trace_id 关联 + +**与 W3 裁决的冲突说明**: + +- W3 裁决原文"首次实现即用 slog" +- 但 shared-go/logger 已用 zap 实现,且 zap 在 Go 生态中性能与生态成熟度优于 slog +- **coord 裁决**:接受现状(zap),W3 裁决修正为"shared-go/logger 基于 zap 封装;ai01 通过 import shared-go/logger 间接使用 zap,不直接 import zap" + +**ai01 执行项**: + +1. P2.1 任务 import `github.com/edu-cloud/shared-go/logger` +2. 替换全部 `log.Printf` 为 `logger.FromContext(ctx).Info/Error/Warn` +3. 涉及文件:main.go L70/160/169/176、config.go L38/41、recovery.go L22、circuit-breaker.go L38、tracer.go L25/31/43/51/65/70 + +**跨模块影响**: + +- **ai02(push-gateway)**:同样 import shared-go/logger,使用 zap,无影响 +- **其他 Go 服务**:若后续有 Go 服务,统一通过 shared-go/logger 使用 zap + +### 24.7 ISSUE-005 go.mod 与 Dockerfile Go 版本不一致 + +**裁决**:统一为 `go 1.22`(与 Dockerfile + 01-understanding.md §4 一致) + +**版本对齐**: + +| 文件 | 当前 | 修正后 | +| --------------------------------------------------------- | -------------------- | ---------------------------- | +| [Dockerfile](../../../services/api-gateway/Dockerfile) L1 | `golang:1.22-alpine` | `golang:1.22-alpine`(不变) | +| [go.mod](../../../services/api-gateway/go.mod) L3 | `go 1.25.0` | `go 1.22` | +| [go.work](../../../go.work) L1 | `go 1.26.0` | `go 1.22` | + +**理由**: + +- Dockerfile 1.22-alpine 是实际构建环境,必须以它为准 +- 01-understanding.md §4 声明 Go 1.22 +- go.mod 1.25.0 / go.work 1.26.0 是误升版本,回退到 1.22 + +**ai01 执行项**: + +1. go.mod L3 改为 `go 1.22` +2. go.work L1 改为 `go 1.22` +3. 验证 `go build ./...` 通过 + +**跨模块影响**: + +- **ai02(push-gateway)**:同样需对齐 go 1.22(若 push-gateway go.mod/go.work 版本不一致,ai02 同步修正) +- **其他服务**:TS/Python 服务无影响 + +### 24.8 ISSUE-007 01-understanding.md §6 审计表 metrics 行过时 + +**裁决**:ai01 更新文档 + +**ai01 执行项**: + +1. 01-understanding.md §6 审计表 metrics 行:`❌ 无` → `⚠️ 端点已注册,缺 7 个业务指标` +2. 01-understanding.md §7.1 issue #1:更新为"已注册 /metrics,需补 7 个业务指标(见 workline P2.5)" + +**跨模块影响**:无 + +### 24.9 ISSUE-008 01-understanding.md §7.1 issue #3 死代码引用过时 + +**裁决**:ai01 删除该行 + +**ai01 执行项**: + +1. 01-understanding.md §7.1 issue #3 整行删除(死代码 `RequestIDMiddleware()` + `generateUUID()` 已修复) + +**跨模块影响**:无 + +### 24.10 ISSUE-009 W1/W2 错误码 GW_ 前缀 + ActionState 信封 + +**裁决**:P2.3 任务统一修复(ai01 已在 workline 列出) + +**修复范围**: + +| 文件 | 当前问题 | 修复后 | +| ------------------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | +| auth.go | 错误码 `UNAUTHORIZED`/`INVALID_TOKEN`/`INVALID_CLAIMS`(无 GW_ 前缀) | `GW_UNAUTHORIZED`/`GW_INVALID_TOKEN`/`GW_INVALID_CLAIMS` | +| ratelimit.go L51-54 | `{"error":"rate_limited","retry_after":60}`(无信封) | `{"success":false,"error":{"code":"GW_RATE_LIMITED","message":"..."},"retry_after":60}` | +| circuit-breaker.go L55-58 | `{"error":"circuit_open","retry_after":30}`(无信封) | `{"success":false,"error":{"code":"GW_CIRCUIT_OPEN","message":"..."},"retry_after":30}` | +| recovery.go L24-27 | `{"error":"internal_error","request_id":"..."}`(无信封) | `{"success":false,"error":{"code":"GW_INTERNAL_ERROR","message":"...","traceId":"..."}}` | + +**ActionState 信封规范**:见 [004 §11.5](../004_architecture_impact_map.md) ActionState 信封规范(coord 基础设施批次已补充) + +**ai01 执行项**: + +1. P2.3 任务统一修复 4 个中间件文件 +2. 错误码统一 `GW_` 前缀(对齐 contract.md §1.6 错误码清单) +3. 响应体统一 ActionState 信封(对齐 004 §11.5) + +**跨模块影响**:无(仅 ai01 自身代码修复) + +### 24.11 ai01 执行项汇总 + +| 任务 | ISSUE | 阶段 | 阻塞 | +| ------------------------------------------------------ | ------------- | ---- | ---- | +| go.mod 补 shared-go 依赖 + 接入 jwks/logger/tracer/env | ISSUE-002/004 | P2.1 | P2.1 | +| 替换 log.Printf 为 shared-go/logger | ISSUE-004 | P2.1 | P2.1 | +| go.mod/go.work 版本回退到 1.22 | ISSUE-005 | P2.0 | P2.0 | +| 01-understanding.md §6/§7.1 文档更新 | ISSUE-007/008 | P2.0 | — | +| 错误码 GW_ + ActionState 信封统一修复 | ISSUE-009 | P2.3 | P2.3 | +| API 版本化路由方案 A 落实(P1 代码迁移到 /v1 前缀) | ISSUE-003 | P2.7 | P2.7 | + +### 24.12 coord 执行项 + +1. ✅ matrix.md §2 移除 api-gateway 为 iam gRPC 消费方(基础设施批次已执行) +2. matrix.md §5 路径前缀修正为双 /v1(方案 A)—— **本节裁决后立即执行** +3. ✅ 004 §11.5 ActionState 信封规范已补充(基础设施批次已执行) +4. 协调 ai02 同步修正 push-gateway go.mod/go.work 版本到 1.22 +5. ✅ 总裁已确认采纳方案 A(2026-07-10),§2.15 第 4 条"避免双 v1"不再适用 --- diff --git a/docs/architecture/issues/matrix.md b/docs/architecture/issues/matrix.md index a33a5eb..92d2a88 100644 --- a/docs/architecture/issues/matrix.md +++ b/docs/architecture/issues/matrix.md @@ -125,17 +125,17 @@ graph TB ## §5 HTTP 接口矩阵(非 gRPC / 非 GraphQL) -| 提供方 | Method | Path | 用途 | 消费方 | 认证 | 状态 | -| ------------------- | ------ | ----------------- | -------------------- | -------------------------------------------------------------- | ---------------- | ---- | -| api-gateway (ai01) | * | /api/v1/teacher/* | 反向代理 teacher-bff | teacher-portal | JWT | ⏳ | -| api-gateway (ai01) | * | /api/v1/student/* | 反向代理 student-bff | student-portal | JWT | ⏳ | -| api-gateway (ai01) | * | /api/v1/parent/* | 反向代理 parent-bff | parent-portal | JWT | ⏳ | -| api-gateway (ai01) | * | /api/v1/iam/* | 反向代理 iam | (内部) | JWT | ⏳ | -| push-gateway (ai02) | WS | /ws | WebSocket 推送通道 | teacher-portal / student-portal / parent-portal / admin-portal | JWT | ⏳ | -| push-gateway (ai02) | POST | /internal/push | 内部推送入口 | msg | X-Internal-Token | ⏳ | -| iam (ai06) | GET | /healthz | 存活检查 | k8s / 监控 | 无 | ⏳ | -| iam (ai06) | GET | /readyz | 就绪检查(5 依赖) | k8s / 监控 | 无 | ⏳ | -| 所有服务 | GET | /metrics | Prometheus 指标 | Prometheus | 无 | ⏳ | +| 提供方 | Method | Path | 用途 | 消费方 | 认证 | 状态 | +| ------------------- | ------ | -------------------- | -------------------- | -------------------------------------------------------------- | ---------------- | ---- | +| api-gateway (ai01) | * | /api/v1/teacher/v1/* | 反向代理 teacher-bff | teacher-portal | JWT | ⏳ | +| api-gateway (ai01) | * | /api/v1/student/v1/* | 反向代理 student-bff | student-portal | JWT | ⏳ | +| api-gateway (ai01) | * | /api/v1/parent/v1/* | 反向代理 parent-bff | parent-portal | JWT | ⏳ | +| api-gateway (ai01) | * | /api/v1/iam/v1/* | 反向代理 iam | (内部) | JWT | ⏳ | +| push-gateway (ai02) | WS | /ws | WebSocket 推送通道 | teacher-portal / student-portal / parent-portal / admin-portal | JWT | ⏳ | +| push-gateway (ai02) | POST | /internal/push | 内部推送入口 | msg | X-Internal-Token | ⏳ | +| iam (ai06) | GET | /healthz | 存活检查 | k8s / 监控 | 无 | ⏳ | +| iam (ai06) | GET | /readyz | 就绪检查(5 依赖) | k8s / 监控 | 无 | ⏳ | +| 所有服务 | GET | /metrics | Prometheus 指标 | Prometheus | 无 | ⏳ | --- diff --git a/docs/architecture/issues/objections/api-gateway_issue.md b/docs/architecture/issues/objections/api-gateway_issue.md index 65e8f89..2d1eeb5 100644 --- a/docs/architecture/issues/objections/api-gateway_issue.md +++ b/docs/architecture/issues/objections/api-gateway_issue.md @@ -154,15 +154,16 @@ ## §2 待 coord 仲裁事项汇总 -| ISSUE | 主题 | 阻塞任务 | 状态 | -| --------- | ----------------------------------- | -------- | -------- | -| ISSUE-001 | matrix.md gRPC 矩阵修正 | — | 待 coord | -| ISSUE-002 | shared-go 接入方式 | P2.1 | 待 coord | -| ISSUE-003 | API 版本化路由方案(/v1 前缀) | P2.7 | 待 coord | -| ISSUE-004 | zap vs slog 选型 | P2.1 | 待 coord | -| ISSUE-005 | go.mod 与 Dockerfile 版本不一致 | P2.0 | 待 coord | -| ISSUE-007 | 01-understanding.md §6 审计表过时 | P2.0 | 待 coord | -| ISSUE-008 | 01-understanding.md §7.1 死代码过时 | P2.0 | 待 coord | -| ISSUE-009 | W1/W2 错误码 GW_ + ActionState | P2.3 | 待 coord | +| ISSUE | 主题 | 阻塞任务 | 状态 | +| --------- | ----------------------------------- | -------- | ------------------------------------------ | +| ISSUE-001 | matrix.md gRPC 矩阵修正 | — | ✅ 已裁决(coord.md §24.3) | +| ISSUE-002 | shared-go 接入方式 | P2.1 | ✅ 已裁决(coord.md §24.5) | +| ISSUE-003 | API 版本化路由方案(/v1 前缀) | P2.7 | ✅ 已裁决(coord.md §24.4,方案 A 双 /v1) | +| ISSUE-004 | zap vs slog 选型 | P2.1 | ✅ 已裁决(coord.md §24.6,zap) | +| ISSUE-005 | go.mod 与 Dockerfile 版本不一致 | P2.0 | ✅ 已裁决(coord.md §24.7,go 1.22) | +| ISSUE-007 | 01-understanding.md §6 审计表过时 | P2.0 | ✅ 已裁决(coord.md §24.8) | +| ISSUE-008 | 01-understanding.md §7.1 死代码过时 | P2.0 | ✅ 已裁决(coord.md §24.9) | +| ISSUE-009 | W1/W2 错误码 GW_ + ActionState | P2.3 | ✅ 已裁决(coord.md §24.10) | > ISSUE-006 编号未使用(预留)。 +> 仲裁详情见 [coord.md §24 ARB-022](../coord.md)