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

@@ -109,6 +109,19 @@ func (r *UserKeysRepo) ListByOwner(ctx context.Context, subjectID string) ([]Use
return scanUserKeys(rows)
}
func (r *UserKeysRepo) ListByFingerprint(ctx context.Context, fingerprint string) ([]UserKeyRecord, error) {
rows, err := r.db.QueryContext(ctx, `
SELECT id, key_id, owner_subject_id, key_fingerprint, masked_preview,
display_name, logical_group_id, allowed_models,
admin_status, quota_status, last_used_at, created_at, expires_at, updated_at
FROM user_keys WHERE key_fingerprint = ? ORDER BY created_at DESC`, fingerprint)
if err != nil {
return nil, fmt.Errorf("list user_keys by fingerprint: %w", err)
}
defer rows.Close()
return scanUserKeys(rows)
}
func (r *UserKeysRepo) GetByID(ctx context.Context, keyID string) (*UserKeyRecord, error) {
row := r.db.QueryRowContext(ctx, `
SELECT id, key_id, owner_subject_id, key_fingerprint, masked_preview,