feat: P0-02/P0-03/P0-05 数据库时间语义与约束

P0-02: MatchStats 增加 source/source_record_id/retrieved_at/available_at
        context_builder 过滤统计数据时检查 available_at <= cutoff
P0-03: Prediction 增加 match_kickoff_at/prediction_created_at/prediction_cutoff_at
        明确区分比赛时间/预测创建时间/数据截止时间
P0-05: Prediction 增加 status 字段(success/failed/degraded)
        数据库 CHECK 约束

Alembic: 0005_prediction_status_and_stats_provenance

P1-02: injuries as_of 不再截断为 date,保持 datetime 精度
This commit is contained in:
shangfangjian
2026-09-15 02:04:25 +08:00
parent c657e04679
commit 0980c2242a
9 changed files with 122 additions and 13 deletions
+6
View File
@@ -14,6 +14,7 @@ import urllib.error
import urllib.parse
import urllib.request
from collections.abc import Iterable
from datetime import datetime, timezone
from sqlalchemy import select
@@ -223,6 +224,7 @@ class BzzoiroSource:
await db.flush()
existing_matches[match_key] = m # 防止同批重复
if nm.home_xg is not None or nm.away_xg is not None:
now = datetime.now(timezone.utc)
stats = MatchStats(
match_id=m.id,
home_xg=nm.home_xg,
@@ -238,6 +240,10 @@ class BzzoiroSource:
away_yellow_cards=nm.away_yellow_cards,
home_red_cards=nm.home_red_cards,
away_red_cards=nm.away_red_cards,
source="bzzoiro",
source_event_id=str(raw.get("id", "")),
retrieved_at=now,
available_at=now,
)
db.add(stats)
league_r["inserted"] += 1