from __future__ import annotations from datetime import datetime from typing import Any, Dict, List, Optional from sqlalchemy import Boolean, DateTime, Integer, JSON, 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) description: Mapped[str] = mapped_column(Text, nullable=True) playbook: Mapped[str] = mapped_column(String, nullable=False) target_type: Mapped[str] = mapped_column(String, default="group", nullable=True) target: Mapped[str] = mapped_column(String, nullable=False) extra_vars: Mapped[Dict[str, Any]] = mapped_column(JSON, nullable=True) schedule_type: Mapped[str] = mapped_column(String, nullable=False) schedule_time: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=True) recurrence_type: Mapped[str] = mapped_column(String, nullable=True) recurrence_time: Mapped[str] = mapped_column(String, nullable=True) recurrence_days: Mapped[str] = mapped_column(Text, nullable=True) cron_expression: Mapped[str] = mapped_column(String, nullable=True) timezone: Mapped[str] = mapped_column(String, default="America/Montreal", nullable=True) start_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=True) end_at: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=True) enabled: Mapped[bool] = mapped_column(Boolean, nullable=False, default=True) tags: Mapped[str] = mapped_column(Text, nullable=True) next_run: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=True) last_run: Mapped[datetime] = mapped_column(DateTime(timezone=True), nullable=True) last_status: Mapped[str] = mapped_column(String, default="never", nullable=True) retry_on_failure: Mapped[int] = mapped_column(Integer, default=0, nullable=True) timeout: Mapped[int] = mapped_column(Integer, default=3600, nullable=True) # Type de notification: "none" (aucune), "all" (toujours), "errors" (erreurs seulement) notification_type: Mapped[str] = mapped_column(String, default="all", nullable=True) run_count: Mapped[int] = mapped_column(Integer, default=0, nullable=True) success_count: Mapped[int] = mapped_column(Integer, default=0, nullable=True) failure_count: Mapped[int] = mapped_column(Integer, default=0, nullable=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[datetime] = mapped_column(DateTime(timezone=True), nullable=True) runs: Mapped[List["ScheduleRun"]] = relationship( "ScheduleRun", back_populates="schedule", cascade="all, delete-orphan" ) def __repr__(self) -> str: # pragma: no cover - debug helper return f""