from fastapi import FastAPI from app.core.constants import ActorValue from app.core.config import get_settings from app.modules.feishu.constants import FeishuReceiveIdType def attach_scheduler(app: FastAPI) -> None: """Attach optional APScheduler jobs to the FastAPI application.""" settings = get_settings() if not settings.scheduler_enabled: return from apscheduler.schedulers.background import BackgroundScheduler from app.core.database import SessionLocal from app.core.task_queue import enqueue_daily_brief_push, enqueue_project_weekly_push from app.modules.reports.service import ReportService scheduler = BackgroundScheduler(timezone="Asia/Shanghai") def run_daily_brief() -> None: db = SessionLocal() try: report = ReportService(db).daily_brief() app.state.last_daily_brief = report if ( settings.feishu_app_id and settings.feishu_app_secret and settings.feishu_default_chat_id ): if settings.task_queue_enabled: app.state.last_daily_brief_dispatch = enqueue_daily_brief_push( receive_id=settings.feishu_default_chat_id, receive_id_type=FeishuReceiveIdType.CHAT_ID, actor=ActorValue.SCHEDULER, ) return ReportService(db).push_report( report, receive_id=settings.feishu_default_chat_id, receive_id_type=FeishuReceiveIdType.CHAT_ID, actor=ActorValue.SCHEDULER, ) finally: db.close() def run_project_weekly() -> None: db = SessionLocal() try: report = ReportService(db).project_weekly() app.state.last_project_weekly = report if ( settings.feishu_app_id and settings.feishu_app_secret and settings.feishu_default_chat_id ): if settings.task_queue_enabled: app.state.last_project_weekly_dispatch = enqueue_project_weekly_push( receive_id=settings.feishu_default_chat_id, receive_id_type=FeishuReceiveIdType.CHAT_ID, actor=ActorValue.SCHEDULER, ) return ReportService(db).push_report( report, receive_id=settings.feishu_default_chat_id, receive_id_type=FeishuReceiveIdType.CHAT_ID, actor=ActorValue.SCHEDULER, ) finally: db.close() scheduler.add_job( run_daily_brief, trigger="cron", hour=settings.daily_brief_cron_hour, minute=settings.daily_brief_cron_minute, id="daily_brief_push", replace_existing=True, ) scheduler.add_job( run_project_weekly, trigger="cron", day_of_week=settings.weekly_project_report_day_of_week, hour=settings.weekly_project_report_cron_hour, minute=settings.weekly_project_report_cron_minute, id="project_weekly_push", replace_existing=True, ) @app.on_event("startup") def start_scheduler() -> None: scheduler.start() @app.on_event("shutdown") def stop_scheduler() -> None: scheduler.shutdown(wait=False)