"""In-process job dispatch. SQS when JOBS_QUEUE_URL is set; otherwise run inline.""" from __future__ import annotations import importlib.util import json import logging import os import sys from pathlib import Path import boto3 from shared.holiday_flow import activate, deactivate from shared.schedule import ShiftSchedule logger = logging.getLogger(__name__) _SRC = Path(__file__).resolve().parents[1] _sqs = None _handlers: dict[str, object] = {} def _client(): global _sqs if _sqs is None: _sqs = boto3.client("sqs") return _sqs def _load_lambda_app(dirname: str): if dirname in _handlers: return _handlers[dirname] path = _SRC / dirname / "app.py" name = f"afterhours_{dirname.replace('-', '_')}" spec = importlib.util.spec_from_file_location(name, path) if spec is None or spec.loader is None: raise ImportError(f"cannot load {path}") mod = importlib.util.module_from_spec(spec) sys.modules[name] = mod spec.loader.exec_module(mod) _handlers[dirname] = mod return mod def enqueue_job(payload: dict) -> None: queue_url = os.environ.get("JOBS_QUEUE_URL", "").strip() body = json.dumps(payload, default=str) if not queue_url: run_job(payload) return _client().send_message(QueueUrl=queue_url, MessageBody=body) def _run_holiday(payload: dict) -> dict: action = payload.get("action") date = payload.get("date") if not date: return {"error": True, "reason": "missing_date"} schedule = ShiftSchedule() if action == "activate": return activate(schedule, date) if action == "deactivate": return deactivate(schedule, date) return {"error": True, "reason": "unknown_action", "action": action} def run_job(payload: dict) -> dict: event_type = payload.get("event", "") if event_type == "holiday": return _run_holiday(payload) forced = {**payload, "force": True} if event_type == "weekly_post": return _load_lambda_app("weekly-post").handler(forced, None) if event_type == "roster_sync": return _load_lambda_app("roster-sync").handler(forced, None) if event_type in {"ring_scheduler_daily", "ring_scheduler_weekend"}: return _load_lambda_app("ring-scheduler").handler(forced, None) raise ValueError(f"unknown job event {event_type!r}")