feat(proxy): T-P0 代理层骨架(包结构/DDL/门控挂载/单进程校验)

- gateway/proxy/ 十文件:config(ProxyConfig:元->毫元加载期换算 D-P1、差异化售价、
  桶/峰谷/限流/semcache 配置)/ errors(8 类 HTTP 语义异常)/ ledger(四表两索引 DDL,
  WAL,ReviewQueue 连接纪律)/ auth·pricing·normalizer·semcache·upstream(§6 签名占位)
  / routes(/proxy/v1/models OpenAI 形状)/ __init__(build_proxy_router 组装点)
- settings DEFAULTS 增 proxy 段(enabled 默认 False,D-P7)
- api.py 首次 include_router(enabled 门控 + 装配失败不拖垮主应用)
- serve.py workers>1 拒绝启动(D-P9:WEB_CONCURRENCY/UVICORN_WORKERS 校验)
- 测试 +4(门控 404/DDL 幂等/毫元换算/池模型列表),全量 322 passed
This commit is contained in:
tzt
2026-09-05 08:35:31 +08:00
parent 3cc9851623
commit b109576707
15 changed files with 580 additions and 1 deletions
+11
View File
@@ -201,6 +201,17 @@ try:
# Vue SPA 静态资源(html=True:对不存在的路径 fallback 到 index.html,支持 SPA 路由)
app.mount("/static", StaticFiles(directory=str(_STATIC_DIR), html=True), name="static")
# 校园 AI 代理层(T-P0D-P7proxy.enabled=False 时不注册任何 /proxy 路由,
# 行为与现状逐字节一致——含本 if 判断在内对既有路径零影响)
try:
from gateway.proxy import build_proxy_router
from gateway.proxy.config import build_proxy_config
_proxy_cfg = build_proxy_config(settings_store().to_dict())
if _proxy_cfg.enabled:
app.include_router(build_proxy_router(_proxy_cfg, get_pool()))
except Exception as _pe: # pragma: no cover - 代理层装配失败不拖垮主应用
print(f"[gateway] 代理层未启用({_pe}")
@app.get("/", response_class=HTMLResponse, tags=["ui"])
async def index():
"""Vue SPA 的 index.htmlFastAPI API 路由优先,此处仅作 fallback)。"""