feat(settle): 킥오프+3h 대기 제거 — 소스가 FINISHED 주면 즉시 정산
settle 게이트를 '킥오프 지남'으로 변경. football-data가 FINISHED 보고 시 다음 폴링(최대 5분) 내 자동 종료·채점·메일. 경기 중(IN_PLAY)엔 자동 스킵. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>develop
parent
54ed8bf10d
commit
7a2affe10a
|
|
@ -129,19 +129,20 @@ async def generate_ai_predictions(only_missing: bool = True) -> None:
|
|||
|
||||
# ── 2.5) 결과 자동 정산 (관리자 입력 불필요) ────────────────
|
||||
async def settle_matches() -> None:
|
||||
"""킥오프 + result_settle_hours 경과한 미정산 경기를 외부 스코어로 자동 채점.
|
||||
"""킥오프가 지난 미정산 경기를, 소스가 FINISHED 로 보고하는 즉시 채점·종료.
|
||||
|
||||
외부 소스(openfootball/football-data)에서 확정 스코어를 수집해 apply_result
|
||||
호출 → 채점·유저 포인트 집계·finished_at 기록. 직후 결과 메일을 발송한다.
|
||||
소스에 스코어가 아직 없으면 다음 틱에 재시도.
|
||||
킥오프 이후의 미정산 경기를 폴링하되, 외부 소스(football-data)가 FINISHED 로
|
||||
확정 스코어를 줄 때만 apply_result → 채점·유저 포인트 집계·finished_at·메일.
|
||||
경기 중(IN_PLAY)에는 FINISHED 가 아니라 결과에 안 잡혀 자동 스킵된다(조기 종료 없음).
|
||||
아직 FINISHED 가 아니면 다음 틱(5분)에 재시도 → 종료 후 최대 1틱 내 반영.
|
||||
"""
|
||||
now = now_utc()
|
||||
cutoff = now - timedelta(hours=settings.result_settle_hours)
|
||||
async with SessionLocal() as db:
|
||||
pending = (
|
||||
await db.execute(select(Match).where(Match.result_outcome.is_(None)))
|
||||
).scalars().all()
|
||||
due = [m.match_id for m in pending if ensure_aware(m.kickoff_at) <= cutoff]
|
||||
# 킥오프가 지난 경기만 (소스가 FINISHED 줄 수 있는 시점)
|
||||
due = [m.match_id for m in pending if ensure_aware(m.kickoff_at) <= now]
|
||||
|
||||
if due:
|
||||
results = await fetch_results()
|
||||
|
|
@ -163,7 +164,7 @@ async def settle_matches() -> None:
|
|||
settled += 1
|
||||
log.info("settle: %s 자동 정산 %d-%d", mid, sc[0], sc[1])
|
||||
if settled == 0:
|
||||
log.info("settle: %d경기 정산 대기 — 외부 스코어 아직 없음", len(due))
|
||||
log.info("settle: %d경기 진행/대기 — 아직 FINISHED 아님", len(due))
|
||||
|
||||
await maybe_send_result_emails()
|
||||
|
||||
|
|
@ -284,14 +285,13 @@ async def main() -> None:
|
|||
sched.start()
|
||||
log.info(
|
||||
"scheduling-server started — schedule sync daily %02d:%02d · status every %ss · "
|
||||
"AI gen daily %02d:%02d %s · auto-settle 킥오프+%dh (every %ss) · 맞춘사람만=%s",
|
||||
"AI gen daily %02d:%02d %s · auto-settle on FINISHED (poll every %ss) · 맞춘사람만=%s",
|
||||
settings.schedule_sync_hour,
|
||||
settings.schedule_sync_minute,
|
||||
settings.status_tick_seconds,
|
||||
settings.ai_generate_hour,
|
||||
settings.ai_generate_minute,
|
||||
settings.timezone,
|
||||
settings.result_settle_hours,
|
||||
settings.settle_tick_seconds,
|
||||
settings.result_email_correct_only,
|
||||
)
|
||||
|
|
|
|||
Loading…
Reference in New Issue