AI Gateway Go 0.10.0 源码快照 + 旗舰版需求规划报告

M0-M7 已完成:核心网关(身份/RBAC/TOTP/OIDC/SAML/Provider/配额/路由/内容策略/审计/定价)+ 资源市场(MCP/Skills/数字员工)。
含 22 个 PostgreSQL 迁移、管理端/门户端前端源码、OpenAPI 契约、部署 compose。

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
ben
2026-08-12 11:45:54 +08:00
commit 5759c1862e
807 changed files with 114727 additions and 0 deletions
+84
View File
@@ -0,0 +1,84 @@
package operations
import (
"context"
"net/http"
"runtime"
"time"
"aigateway.local/core/internal/identity"
"aigateway.local/core/internal/platform/apiresponse"
"github.com/jackc/pgx/v5/pgxpool"
)
type AdminHTTPHandler struct {
pool *pgxpool.Pool
identity *identity.Service
version string
startedAt time.Time
reload func(context.Context) error
mux *http.ServeMux
}
func NewAdminHTTPHandler(pool *pgxpool.Pool, identityService *identity.Service, version string, startedAt time.Time, reload func(context.Context) error) *AdminHTTPHandler {
h := &AdminHTTPHandler{pool: pool, identity: identityService, version: version, startedAt: startedAt, reload: reload, mux: http.NewServeMux()}
h.mux.HandleFunc("GET /api/v1/admin/system-info", h.systemInfo)
h.mux.HandleFunc("GET /api/v1/admin/monitoring/overview", h.overview)
h.mux.HandleFunc("POST /api/v1/admin/reload", h.reloadSnapshots)
return h
}
func (h *AdminHTTPHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { h.mux.ServeHTTP(w, r) }
func (h *AdminHTTPHandler) account(w http.ResponseWriter, r *http.Request) (identity.Account, bool) {
account, err := h.identity.Authenticate(r.Context(), identity.KindAdmin, r.Header.Get("Authorization"))
if err != nil {
apiresponse.Error(w, http.StatusUnauthorized, "登录状态无效")
return identity.Account{}, false
}
return account, true
}
func (h *AdminHTTPHandler) systemInfo(w http.ResponseWriter, r *http.Request) {
if _, ok := h.account(w, r); !ok {
return
}
var providers, models, keys int64
if err := h.pool.QueryRow(r.Context(), `SELECT (SELECT count(*) FROM gateway.providers WHERE enabled),(SELECT count(*) FROM gateway.provider_models WHERE enabled),(SELECT count(*) FROM gateway.api_keys WHERE enabled)`).Scan(&providers, &models, &keys); err != nil {
apiresponse.Error(w, http.StatusServiceUnavailable, "系统信息查询失败")
return
}
apiresponse.OK(w, map[string]any{"version": h.version, "go_version": runtime.Version(), "uptime_seconds": int64(time.Since(h.startedAt).Seconds()), "database": "postgresql", "object_storage": false, "clickhouse": false, "enabled_providers": providers, "enabled_models": models, "enabled_api_keys": keys})
}
func (h *AdminHTTPHandler) overview(w http.ResponseWriter, r *http.Request) {
if _, ok := h.account(w, r); !ok {
return
}
var requests, failures, promptTokens, completionTokens, cost int64
var latency *float64
err := h.pool.QueryRow(r.Context(), `SELECT count(*),count(*) FILTER(WHERE coalesce(status_code,500)>=400),coalesce(sum(prompt_tokens),0),coalesce(sum(completion_tokens),0),coalesce(sum(cost_microunits),0),avg(latency_ms) FROM gateway.audit_events WHERE recorded_at>=clock_timestamp()-interval '24 hours'`).Scan(&requests, &failures, &promptTokens, &completionTokens, &cost, &latency)
if err != nil {
apiresponse.Error(w, http.StatusServiceUnavailable, "监控汇总查询失败")
return
}
apiresponse.OK(w, map[string]any{"window": "24h", "requests": requests, "failed_requests": failures, "prompt_tokens": promptTokens, "completion_tokens": completionTokens, "cost_microunits": cost, "avg_latency_ms": latency})
}
func (h *AdminHTTPHandler) reloadSnapshots(w http.ResponseWriter, r *http.Request) {
account, ok := h.account(w, r)
if !ok {
return
}
if !identity.HasPermission(account, identity.PermissionProviderManage) {
apiresponse.Error(w, http.StatusForbidden, "缺少运行时配置管理权限")
return
}
if h.reload != nil {
if err := h.reload(r.Context()); err != nil {
apiresponse.Error(w, http.StatusServiceUnavailable, "运行时快照刷新不完整: "+err.Error())
return
}
}
apiresponse.OK(w, map[string]bool{"reloaded": true})
}