from __future__ import annotations from datetime import datetime from typing import List, Optional from sqlalchemy import Boolean, DateTime, String, Text from sqlalchemy.orm import Mapped, mapped_column, relationship from sqlalchemy.sql import func from .database import Base class Schedule(Base): __tablename__ = "schedules" id: Mapped[str] = mapped_column(String, primary_key=True) name: Mapped[str] = mapped_column(String, nullable=False) playbook: Mapped[str] = mapped_column(String, nullable=False) target: Mapped[str] = mapped_column(String, nullable=False) schedule_type: Mapped[str] = mapped_column(String, nullable=False) schedule_time: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True)) recurrence_type: Mapped[Optional[str]] = mapped_column(String) recurrence_time: Mapped[Optional[str]] = mapped_column(String) recurrence_days: Mapped[Optional[str]] = mapped_column(Text) cron_expression: Mapped[Optional[str]] = mapped_column(String) enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True) tags: Mapped[Optional[str]] = mapped_column(Text) next_run: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True)) last_run: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True)) created_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now()) updated_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=False, server_default=func.now(), onupdate=func.now()) deleted_at: Mapped[Optional[datetime]] = mapped_column(DateTime(timezone=True)) runs: Mapped[List["ScheduleRun"]] = relationship( "ScheduleRun", back_populates="schedule", cascade="all, delete-orphan" ) logs: Mapped[List["Log"]] = relationship("Log", back_populates="schedule") def __repr__(self) -> str: # pragma: no cover - debug helper return f""