feat(v3): add CRM gateway /v1/chat/completions with key auth + governance check
Some checks failed
CI / Build & Test (push) Has been cancelled
CI / Lint (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / Docker Build (push) Has been cancelled
CI / Release (push) Has been cancelled

- POST /v1/chat/completions public route on CRM (not host pass-through)
- Bearer token → sha256 fingerprint → ListByFingerprint → governance check
- paused → 403 forbidden, retired/deleted → 403
- ProxyRouteChatCompletions to upstream
- NewAPIHandler/NewAPIHandlerWithAuth: optional dsn param for gateway SQLite access
- ListByFingerprint in user_keys_repo
This commit is contained in:
phamnazage-jpg
2026-06-07 12:19:24 +08:00
parent 6eec70d6a3
commit c86c8a17ca
8 changed files with 280 additions and 51 deletions

View File

@@ -0,0 +1,46 @@
# V3-1 网关治理执行计划
> 目标:在 CRM 新增公开 `/v1/chat/completions` 入口,用户在入口用 portal key 认证CRM 校验 `admin_status` 后再转发到宿主,实现 0 延迟的 pause/resume 治理阻断。
## 改动概览
| 文件 | 改动 |
| ------------------------------------------------ | ------------------------------------------------------------------------------- |
| `internal/app/http_api.go` | 新增 `POST /v1/chat/completions` 公开路由(无 admin auth调用治理校验 + 转发 |
| `internal/app/route_proxy_api.go` | 新增 user-key 认证和治理校验的入口函数 |
| `internal/app/openaicompat_handler.go`(新文件) | OpenAI-compatible 请求解析 + user-key auth 提取 |
| `deploy/tksea-portal/nginx/` 或部署脚本 | 加 `location /v1 { proxy_pass http://127.0.0.1:18190; }` |
## 执行分步
### Step 1: 新增公开 `/v1/chat/completions` 路由
`internal/app/http_api.go` 中,在 `NewAPIHandlerWithAuth` 函数注册路由处(在 admin auth 区块之外)添加:
```go
mux.Handle("POST /v1/chat/completions", http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
handlePublicChatCompletions(w, r, actions.UserKeyHandler)
}))
```
注意必须放在 `requireAdminAccess` 包的外面,这样用户不需要 admin token。
### Step 2: 实现 `handlePublicChatCompletions`
```go
func handlePublicChatCompletions(w http.ResponseWriter, r *http.Request, ukh *UserKeyHandler) {
// 1. 提取 Bearer token → user_key_id
// 2. 查 user_keys 表,校验 admin_status != "paused"
// 3. 获取 key 的 subject_id 和 logical_group_id
// 4. 调用 buildRouteChatCompletionsAction 或 buildProxyRouteChatCompletionsAction 转发
// - 传入 gateway_api_key = managed key来自 user_key 的 managed subscription
// - 传入 subject_id = user_key 的 owner_subject_id
// - 传入 model = 请求体中的 model
// - 传入 messages = 请求体中的 messages
// 5. 返回 OpenAI-compatible chat completion 响应形状
}
```
### Step 3: deploy 脚本更新
更新 nginx 配置,让 `location /v1` 指向 CRM 的 18190。