# api-gateway 对接契约

> 负责人：ai01
> 关联：[matrix.md](./matrix.md)、[iam.proto](../../../packages/shared-proto/proto/iam.proto)

---

## §1 我提供什么（对外接口）

### 1.1 gRPC 接口（如有）

无。api-gateway 是 HTTP 入口，不对外提供 gRPC。

### 1.2 HTTP 端点（如有）

| Method | Path           | 用途                                        | 认证                   |
| ------ | -------------- | ------------------------------------------- | ---------------------- |
| ANY    | /api/auth/*    | 代理到 iam 认证相关（登录/注册/刷新 token） | 公开（登录注册免认证） |
| ANY    | /api/teacher/* | 代理到 teacher-bff GraphQL（:3003）         | JWT 必需               |
| ANY    | /api/student/* | 代理到 student-bff GraphQL（:3009）         | JWT 必需               |
| ANY    | /api/parent/*  | 代理到 parent-bff GraphQL（:3010）          | JWT 必需               |
| ANY    | /api/admin/*   | 代理到 teacher-bff GraphQL admin namespace  | JWT 必需 + admin 角色  |
| GET    | /healthz       | 网关健康检查（liveness）                    | 公开                   |
| GET    | /readyz        | 网关就绪检查（readiness，含 iam 连通性）    | 公开                   |
| GET    | /metrics       | Prometheus 指标端点                         | 公开（内网）           |

### 1.3 GraphQL schema（如 BFF）

不适用。api-gateway 仅做 HTTP 反向代理 + JWT 验签，不解析 GraphQL。

### 1.4 Kafka 事件发布（如有）

无。api-gateway 不发布事件。

### 1.5 错误码前缀

`GW_`（如 GW_UNAUTHORIZED、GW_RATE_LIMITED、GW_CIRCUIT_OPEN、GW_BACKEND_UNAVAILABLE）

---

## §2 我消费什么（依赖上游）

### 2.1 gRPC 调用（同步）

| 被调用方   | Service.RPC                   | 用途                                     | mock 策略                                                         |
| ---------- | ----------------------------- | ---------------------------------------- | ----------------------------------------------------------------- |
| iam (ai06) | IamService.GetPublicKey       | 启动时拉取 RS256 公钥，用于 JWT 验签     | iam 就绪前使用本地固定 mock 公钥（与 mock 私钥配对签发 mock JWT） |
| iam (ai06) | IamService.GetEffectiveAccess | 权限校验（可选，部分路由需要细粒度权限） | iam 就绪前放行所有请求（仅校验 JWT 签名）                         |

### 2.2 Kafka 事件订阅（异步）

无。api-gateway 不订阅 Kafka 事件。

### 2.3 HTTP 调用（如有）

| 被调用方           | Method.Path   | 用途                        | mock 策略                                          |
| ------------------ | ------------- | --------------------------- | -------------------------------------------------- |
| teacher-bff (ai03) | POST /graphql | 反向代理教师端 GraphQL 请求 | teacher-bff 就绪前返回 502，前端使用本地 mock 数据 |
| student-bff (ai04) | POST /graphql | 反向代理学生端 GraphQL 请求 | student-bff 就绪前返回 502                         |
| parent-bff (ai05)  | POST /graphql | 反向代理家长端 GraphQL 请求 | parent-bff 就绪前返回 502                          |

---

## §3 就绪信号

### 3.1 我依赖的上游就绪标志

- [ ] iam gRPC 50052 启用（ai06）—— GetPublicKey 拉取验签公钥
- [ ] teacher-bff GraphQL :3003 启用（ai03）
- [ ] student-bff GraphQL :3009 启用（ai04）
- [ ] parent-bff GraphQL :3010 启用（ai05）

### 3.2 我的就绪标志（供下游消费）

- [ ] api-gateway HTTP :8080 启用（/healthz 返回 200）
- [ ] /readyz 返回 200（含 iam 连通性检查通过）
- [ ] JWT 验签链路打通（使用 iam 公钥校验 access_token）
- [ ] /api/auth/* 代理到 iam 认证链路可用
- [ ] /api/teacher/* /api/student/* /api/parent/* 反向代理到各 BFF 可用
- [ ] 限流（IP 级令牌桶）+ 熔断（各后端独立熔断器）生效

---

## §4 Mock 策略

### 4.1 我提供的 mock

在 api-gateway 真实就绪前，为下游（各前端 portal）提供以下 mock：

- **HTTP mock**：使用 MSW（Mock Service Worker）或本地 nginx 拦截
  - /api/auth/login 返回固定 JWT（mock 签发）+ UserInfo
  - /api/teacher/* /api/student/* /api/parent/* 直接返回各 BFF 的 mock GraphQL 响应
  - /healthz /readyz 返回 200
- **JWT mock**：前端开发期使用固定 mock JWT（api-gateway 就绪前不走真实验签）

### 4.2 我消费的 mock

在真实上游就绪前，api-gateway 使用以下 mock：

- **iam 公钥**：使用本地固定 mock RS256 公钥（与 mock 私钥配对），验签 mock JWT
- **iam 权限校验**：GetEffectiveAccess 返回 allowed=true，放行所有请求
- **各 BFF 代理**：BFF 就绪前返回 503 + Retry-After，前端降级到本地 mock 数据
