refactor: fix P0/P1/P2 security and performance issues

P0 fixes:
- CORS: replace wildcard methods/headers with configurable lists
- deps.py: remove unsafe global _warned_unset variable

P1 fixes:
- http_client: read default timeout from Settings
- bzzoiro: replace sync urllib with async httpx
- bzzoiro: normalize validation failures use warning level only
- db pool: read pool config from Settings (default 5+10)
- backtest: add asyncio.Semaphore(8) for concurrent execution
- predict/context_builder: add backtest parameter for cutoff buffer

P2 improvements:
- injuries: enforce int conversion for player_id/fixture_id
- injuries: use system temp dir for cache
- utils.py: extract shared actual_1x2/is_correct_1x2
- validation: downgrade 1x2 mismatch log to debug
- docker-compose: use env vars for all credentials
- .env.example: add POSTGRES_USER/PASSWORD/PORT, API_PORT
This commit is contained in:
shangfangjian
2026-09-16 02:38:25 +08:00
parent fa69795d69
commit 983b620659
14 changed files with 154 additions and 109 deletions
+6 -2
View File
@@ -103,6 +103,7 @@ async def predict_match(
prompt_version: str | None = None,
mode: str = "multi",
use_cache: bool = True,
backtest: bool = False,
) -> "PredictResult | MultiPredictResult":
"""预测入口。mode=multi(默认)走多 agent;mode=single 走单次调用。
@@ -110,6 +111,7 @@ async def predict_match(
use_cache: 是否允许返回进程内缓存结果。回测必须传 False——
缓存命中不会新建 prediction 行,调用方会对同一个 prediction_id
反复 settle,把不同比赛的真实比分覆盖到同一条记录上。
backtest: 是否回测模式。True 时 build_context 使用 match_date-1天 作为 cutoff。
"""
if mode == "single":
return await _predict_single(
@@ -118,6 +120,7 @@ async def predict_match(
model=model,
prompt_version=prompt_version,
use_cache=use_cache,
backtest=backtest,
)
from src.llm.agents.orchestrator import predict_match_multi
@@ -131,6 +134,7 @@ async def _predict_single(
model: str | None = None,
prompt_version: str | None = None,
use_cache: bool = True,
backtest: bool = False,
) -> PredictResult:
"""单次调用路径(原有实现)。"""
if provider is None:
@@ -147,8 +151,8 @@ async def _predict_single(
logger.debug("predict cache hit match=%s", match_id)
return cached
# 1. 拼上下文
ctx = await build_context(match_id)
# 1. 拼上下文(P2-6: backtest 时使用 match_date-1天 作为 cutoff)
ctx = await build_context(match_id, backtest=backtest)
# 1.5 计算快照元数据(用于可复现性)
now = datetime.now(timezone.utc)