""" Schedule dispatcher: routes schedule_id to the correct run function. Also used by manual trigger API. """ import logging from sqlalchemy.orm import Session from app.core.database import SessionLocal logger = logging.getLogger(__name__) def dispatch_schedule(schedule_id: int, log_id: int = None, db: Session = None): """ Dispatch to correct schedule function. When called from watchdog, db and log_id are provided. When called from manual API, creates its own session and log. """ own_db = db is None own_log = False log_obj = None if own_db: db = SessionLocal() if log_id is None: from app.core.utils import now_tw from app.models.schedule import ScheduleLog, Schedule schedule = db.get(Schedule, schedule_id) if not schedule: if own_db: db.close() return log_obj = ScheduleLog( schedule_id=schedule_id, schedule_name=schedule.name, started_at=now_tw(), status="running", ) db.add(log_obj) db.commit() db.refresh(log_obj) log_id = log_obj.id own_log = True final_status = "error" try: if schedule_id == 1: from app.services.scheduler.schedule_tenant import run_tenant_check run_tenant_check(log_id, db) elif schedule_id == 2: from app.services.scheduler.schedule_account import run_account_check run_account_check(log_id, db) elif schedule_id == 3: from app.services.scheduler.schedule_system import run_system_status run_system_status(log_id, db) else: logger.warning(f"Unknown schedule_id: {schedule_id}") final_status = "ok" except Exception as e: logger.exception(f"dispatch_schedule({schedule_id}) error: {e}") raise finally: # When called from manual trigger (own_log), finalize the log entry if own_log and log_obj is not None: from app.core.utils import now_tw log_obj.ended_at = now_tw() log_obj.status = final_status db.commit() if own_db: db.close()