"""计划任务管理:列出 / 启用 / 禁用 / 改时间。""" from __future__ import annotations import json from fastapi import APIRouter, HTTPException from pydantic import BaseModel from app.core.db import ops as db_ops from app.core.scheduler import ( get_scheduler_status, is_trading_day, next_trading_day, seed_schedule_configs, ) router = APIRouter(prefix="/api/schedule", tags=["schedule"]) class ScheduleUpdate(BaseModel): enabled: bool | None = None time: str | None = None intervalSeconds: int | None = None condition: str | None = None @router.get("") def list_schedules(): return {"scheduler": get_scheduler_status(), "isTradingDay": is_trading_day(), "nextTradingDay": next_trading_day().isoformat()} @router.post("/reseed") def reseed(): seed_schedule_configs() return {"status": "ok"} @router.patch("/{key}") def update_schedule(key: str, body: ScheduleUpdate): target = None for r in db_ops.fetch_all_config(): if r.get("key") == key and r.get("category") == "schedule": target = r break if target is None: raise HTTPException(404, f"未知 schedule key: {key}") try: obj = json.loads(target.get("value", "") or "{}") except (json.JSONDecodeError, TypeError): obj = {} if body.enabled is not None: obj["enabled"] = body.enabled if body.time is not None: obj["time"] = body.time if body.intervalSeconds is not None: obj["intervalSeconds"] = body.intervalSeconds if body.condition is not None: if body.condition not in ("always", "trading_day"): raise HTTPException(400, f"condition 仅支持 always / trading_day") obj["condition"] = body.condition db_ops.upsert_config( key, json.dumps(obj, ensure_ascii=False), category="schedule", description=target.get("description", ""), ) return {"status": "ok", "key": key, "value": obj}