feat: persist finance daily summaries
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
"""APScheduler background scheduler for upstream checks."""
|
||||
"""APScheduler background scheduler for upstream checks and daily tasks."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
@@ -8,6 +8,7 @@ from typing import Any
|
||||
|
||||
from apscheduler.executors.pool import ThreadPoolExecutor
|
||||
from apscheduler.schedulers.background import BackgroundScheduler
|
||||
from apscheduler.triggers.cron import CronTrigger
|
||||
from sqlalchemy.orm import Session
|
||||
|
||||
from app.database import SessionLocal
|
||||
@@ -365,6 +366,16 @@ def start_scheduler() -> None:
|
||||
max_instances=1,
|
||||
misfire_grace_time=3600,
|
||||
)
|
||||
# Daily finance summary at 00:05 Asia/Shanghai
|
||||
_scheduler.add_job(
|
||||
_compute_finance_daily_summary,
|
||||
trigger=CronTrigger(timezone="Asia/Shanghai", hour=0, minute=5),
|
||||
id="finance_daily_summary",
|
||||
replace_existing=True,
|
||||
coalesce=True,
|
||||
max_instances=1,
|
||||
misfire_grace_time=3600,
|
||||
)
|
||||
logger.info("scheduler started with %d upstream job(s)", len(upstreams))
|
||||
finally:
|
||||
db.close()
|
||||
@@ -383,6 +394,28 @@ def _cleanup_external_logs() -> None:
|
||||
db.close()
|
||||
|
||||
|
||||
def _compute_finance_daily_summary() -> None:
|
||||
"""Compute and save finance daily summary for yesterday (Asia/Shanghai).
|
||||
|
||||
Runs daily at 00:05 Asia/Shanghai. Delegates to save_summary_if_absent
|
||||
which handles the skip-if-exists logic and concurrent-save race.
|
||||
"""
|
||||
from app.services.finance_service import yesterday_shanghai, save_summary_if_absent
|
||||
|
||||
target = yesterday_shanghai()
|
||||
db = SessionLocal()
|
||||
try:
|
||||
saved = save_summary_if_absent(db, target)
|
||||
if saved:
|
||||
logger.info("finance daily summary for %s saved", target)
|
||||
else:
|
||||
logger.info("finance daily summary for %s already exists, skipping", target)
|
||||
except Exception:
|
||||
logger.exception("failed to compute finance daily summary for %s", target)
|
||||
finally:
|
||||
db.close()
|
||||
|
||||
|
||||
def stop_scheduler() -> None:
|
||||
if _scheduler.running:
|
||||
_scheduler.shutdown(wait=True)
|
||||
|
||||
Reference in New Issue
Block a user