Files
Edu/docs/architecture/issues/objections/api-gateway_issue.md
SpecialX c6362f4b04
Some checks failed
CI / quality-ts (push) Failing after 53s
CI / quality-go (push) Failing after 7s
CI / quality-proto (push) Failing after 3s
CI / deploy (push) Has been skipped
docs(docs): 更新 issue 仲裁状态 + 生成集成测试阶段规划
- 14 个 issue.md 状态字段更新为"已裁决"
  - 对应 coord.md ARB-001~022 章节
  - 共 104 处状态字段更新
- 新增 integration-test-phase.md
  - 集成测试与部署验证阶段(P7)规划
  - 6 个批次任务分解
  - 8 条核心 E2E 链路定义
  - 验收标准和退出标准

Coord-AI
2026-07-10 22:05:37 +08:00

19 KiB
Raw Blame History

api-gateway 问题记录

负责人ai01 关联:coord.mdcontracts/api-gateway_contract.mdworklines/api-gateway_workline.md 依据:coord-final-decisions.md §3.8 W1-W8、president-final-rulings.md §2.15/§2.16/§2.19 规则AI 遇到问题时在此追加条目coord 仲裁后更新状态


§0 模块边界确认(审查结论)

0.1 边界定义(来自 01-understanding.md §2

  • 层级L3 网关层004 §3.1 六层架构)
  • 职责所有外部请求的统一入口、JWT 校验、用户身份注入(x-user-id/x-user-roles/x-data-scope、限流、熔断、CORS、安全头、请求 ID 注入、反向代理
  • 不负责
    • WebSocket 长连接管理push-gateway 负责)
    • 用户身份认证逻辑iam 负责,本服务只校验 JWT 签名)
    • 权限点解析(下游服务 Controller @RequirePermission 自校验,本服务只透传身份头)
    • 业务数据持久化(无 DB
  • 通信方式:入口 HTTP/REST出口 HTTP 反向代理(httputil.ReverseProxy),不消费 gRPC不接入 Kafka

边界审查结论:边界定义清晰,与 02-architecture-design.md §7 交互点清单、contracts/api-gateway_contract.md v2 一致。本服务是纯同步 HTTP 反向代理,不持有业务状态。

0.2 W1-W8 裁决遵循情况核查2026-07-10

对照 coord-final-decisions.md §3.8 W1-W8 裁决逐项核查当前代码P1 交付态):

# 裁决项 强制最终方案 当前代码状态 遵循 对应 ISSUE
W1 错误码前缀 GW_*GW_UNAUTHORIZED 等) auth.goUNAUTHORIZED/INVALID_TOKEN/INVALID_CLAIMS(无 GW_ 前缀) ISSUE-009
W2 错误信封 首次实现即对齐 ActionState ratelimit.go L51-54 响应 {"error":"rate_limited","retry_after":60}(无 success/error.code 结构);circuit-breaker.go L55-58 同样无信封;recovery.go L24-27 无信封auth.go 部分对齐 ISSUE-009
W3 slog 首次实现即用 slog 全部用 log.Printfmain.go L70/160/169/176、config.go L38/41、recovery.go L22、circuit-breaker.go L38、tracer.go L25/31/43/51/65/70 ISSUE-004
W4 /readyz 首次实现即真实健康检查(轮询下游 /healthz health.go L19-23 直接返回 200有 TODO 注释"P7 接入服务发现后"
W5 业务 metrics 首次实现即基础业务指标 main.go L56 已注册 /metrics 端点promhttp.Handler但未注册 7 个业务指标(无 internal/observability/metrics.go 文件) ⚠️ ISSUE-007
W6 tracer 资源属性 首次实现即完整version/env/host tracer.go L47-49 只有 service.name,缺 service.version/deployment.environment/host.name
W7 DevMode 防护 首次实现即生产防护DEV_MODE 仅非生产环境生效) config.go Load()ENV 环境变量读取DevMode=true 时无生产防护
W8 per-服务实例熔断 保持共享 downstream 熔断per-实例 P6 单独评估 main.go L61 middleware.CircuitBreaker("downstream") 共享熔断

核查结论W1/W2/W3/W4/W6/W7 共 6 项未遵循裁决W5 部分遵循W8 已遵循。未遵循项需在 P2.0-P2.6 任务中修复(见 workline.md §3

0.3 架构文档与代码不一致问题

# 文件 问题 修复建议
D1 02-architecture-design.md §1 中间件链图标注顺序 Auth → CircuitBreaker,但 main.go L61-63 实际顺序为 CircuitBreaker → Auth 统一文档与代码(建议代码保持 CircuitBreaker 在 Auth 之前,避免未鉴权请求消耗下游配额,更新文档图)
D2 README.md L38 提到 GET /health 兼容端点,但 main.go 未注册 /health 路由 删除 README L38 描述(已在 workline P2.0 列出)
D3 proxy.go L24 连续两次 TrimPrefixL23 去 /api/v1L24 再去 /api),第二次无效果(首字符已是 / 删除 L24 冗余 TrimPrefix("/api")(已在 workline P2.0 列出)
D4 01-understanding.md §3.1 提到"P2 起 RS256 公钥校验时通过 IAM /auth/jwks 端点拉公钥",但 contract.md v2 §2.3 已修正为 GET /.well-known/jwks.json 统一为 /.well-known/jwks.jsonRFC 8414 标准路径)

§1 问题列表

ISSUE-001-ai01matrix.md gRPC 矩阵错误声明 api-gateway 消费 iam gRPC

  • 提请方ai01
  • 日期2026-07-10
  • 类型:契约不明确
  • 描述matrix.md §2 gRPC 接口提供方矩阵中iam 的"消费方"列包含 api-gateway,暗示 api-gateway 消费 iam gRPC。但依据 president-final-rulings.md §2.16 裁决"gateway 保持 HTTP 透传,不改为 gRPC 客户端"api-gateway 通过 HTTP JWKS 端点(GET /.well-known/jwks.json)拉取 RS256 公钥,不消费任何 gRPC。同时 matrix.md §7 Mock 策略表中"api-gateway 消费 iam.GetPublicKey"也需修正为 HTTP JWKS。
  • 建议方案
    1. matrix.md §2 iam 行"消费方"列移除 api-gateway
    2. matrix.md §7 Mock 策略表中 api-gateway 行改为"硬编码 RS256 公钥DEV_MODE→ HTTP JWKS 端点"
  • 状态:已裁决(见 coord.md §24.3

ISSUE-002-ai01shared-go 接入方式与时机

  • 提请方ai01
  • 日期2026-07-10
  • 类型:前置依赖缺失
  • 描述:依据 president-final-rulings.md §2.19 裁决ai01 应直接 import packages/shared-gojwks/logger/tracer/env 4 模块)。但当前 go.work L3-4 仅声明 ./services/api-gateway./services/push-gateway,未包含 ./packages/shared-gogo.mod 也无 github.com/edu-cloud/shared-go 依赖。需确认 shared-go 包骨架是否已建立、模块路径命名、go.work 接入方式。
  • 建议方案
    1. coord 确认 packages/shared-go 骨架已建立(批次 0.14 任务)
    2. go.work 增加 ./packages/shared-go
    3. ai01 go.mod 增加 github.com/edu-cloud/shared-go 依赖
    4. P2.1 任务接入 jwks/logger/tracer/env
  • 状态:已裁决(见 coord.md §24.5

ISSUE-003-ai01API 版本化路由方案(/v1 前缀位置)

  • 提请方ai01
  • 日期2026-07-10
  • 类型:契约不明确
  • 描述:依据 president-final-rulings.md §2.15 裁决,全服务统一加 /v1 前缀Controller 内加 v1 前缀Gateway 透传时不改路径。但当前 main.go 路由为 /api/v1/iam/*path(无服务级 /v1),而 contract.md v2 §1.2.2 路由表列为 /api/v1/iam/v1/*path(方案 A双 v1。裁决第 4 条"避免双 v1"与 contract v2 路由表存在矛盾,需 coord 仲裁最终方案:
    • 方案 AGateway 路由 /api/v1/iam/v1/*pathproxy 透传 /iam/v1/*path(前端调用 /api/v1/iam/v1/auth/login
    • 方案 BGateway 路由 /api/v1/iam/*pathproxy 透传 /iam/*path,下游 Controller 内加 /v1(前端调用 /api/v1/iam/v1/auth/loginGateway 不含 /v1
    • 方案 C其他
  • 建议方案:采纳方案 BGateway 路由不含服务级 /v1,由下游 Controller 添加),符合裁决第 4 条"避免双 v1"和第 3 条"Gateway 不改路径直接透传"
  • 状态:已裁决(见 coord.md §24.4

ISSUE-004-ai01zap vs slog 选型

  • 提请方ai01
  • 日期2026-07-10
  • 类型:契约不明确
  • 描述W3 裁决"首次实现即用 slog",但 shared-go/logger 的实现选型zap 还是 slog影响 ai01 接入方式。若 shared-go 用 zapai01 需通过 shared-go/logger 间接使用 zap若 shared-go 用 slogai01 可直接用标准库 log/slog 或 shared-go 封装。需 coord 仲裁 shared-go/logger 最终选型。
  • 建议方案shared-go/logger 基于 log/slog 封装标准库零依赖W3 裁决原文即 slogai01 直接 import shared-go/logger
  • 状态:已裁决(见 coord.md §24.6

ISSUE-005-ai01go.mod 与 Dockerfile Go 版本不一致

  • 提请方ai01
  • 日期2026-07-10
  • 类型:其他
  • 描述go.mod L3 声明 go 1.25.0go.work L1 声明 go 1.26.0,但 Dockerfile L1 用 golang:1.22-alpine。三者不一致,可能导致构建环境与本地开发环境行为差异。
  • 建议方案:统一为 go 1.22(与 Dockerfile 一致,与 01-understanding.md §4 声明一致),或升级 Dockerfile 到 golang:1.25-alpine 并同步 go.mod/go.work
  • 状态:已裁决(见 coord.md §24.7

ISSUE-007-ai0101-understanding.md §6 审计表 metrics 行过时

  • 提请方ai01
  • 日期2026-07-10
  • 类型:其他
  • 描述01-understanding.md §6 审计表 metrics 行标注 ❌ 无§7.1 issue #1 也说"无 /metrics 端点Prometheus 404"。但实际 main.go L56 已注册 r.GET("/metrics", gin.WrapH(promhttp.Handler()))/metrics 端点已存在。文档过时,需更新为"⚠️ 端点已注册,但缺 7 个业务指标"。
  • 建议方案:更新 01-understanding.md §6 审计表 metrics 行为 ⚠️ 端点已注册,缺业务指标§7.1 issue #1 更新为"已注册 /metrics需补 7 个业务指标"
  • 状态:已裁决(见 coord.md §24.8

ISSUE-008-ai0101-understanding.md §7.1 issue #3 死代码引用过时

  • 提请方ai01
  • 日期2026-07-10
  • 类型:其他
  • 描述01-understanding.md §7.1 issue #3 引用"auth.go L124-139 死代码 RequestIDMiddleware() + generateUUID()",但实际 auth.go 当前仅 121 行L124-139 不存在,死代码已删除。文档引用过时。
  • 建议方案:删除 01-understanding.md §7.1 issue #3 整行(死代码已修复)
  • 状态:已裁决(见 coord.md §24.9

ISSUE-009-ai01W1/W2 错误码 GW_ 前缀 + ActionState 信封未遵循

  • 提请方ai01
  • 日期2026-07-10
  • 类型:其他
  • 描述W1 裁决要求错误码统一 GW_ 前缀W2 裁决要求错误响应统一 ActionState 信封 {success:false,error:{code,message}}。但当前代码:
    • auth.go 错误码用 UNAUTHORIZED/INVALID_TOKEN/INVALID_CLAIMS(无 GW_ 前缀但响应体已部分对齐信封L44-50 有 success/error.code/error.message
    • ratelimit.go L51-54 响应 {"error":"rate_limited","retry_after":60}(无 GW_ 前缀,无信封)
    • circuit-breaker.go L55-58 响应 {"error":"circuit_open","retry_after":30}(无 GW_ 前缀,无信封)
    • recovery.go L24-27 响应 {"error":"internal_error","request_id":"..."}(无 GW_ 前缀,无信封)
  • 建议方案P2.3 任务统一修复(见 workline.md P2.3),所有错误码改为 GW_*,所有响应体改为 {success:false,error:{code:"GW_*",message:"..."},...}
  • 状态:已裁决(见 coord.md §24.10

§2 待 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.6zap
ISSUE-005 go.mod 与 Dockerfile 版本不一致 P2.0 已裁决coord.md §24.7go 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