use crate::database::universal_types::{UniversalBool, UniversalTimestamp, UniversalUuid};
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CronSchedule {
pub id: UniversalUuid,
pub workflow_name: String,
pub cron_expression: String,
pub timezone: String,
pub enabled: UniversalBool,
pub catchup_policy: String,
pub start_date: Option<UniversalTimestamp>,
pub end_date: Option<UniversalTimestamp>,
pub next_run_at: UniversalTimestamp,
pub last_run_at: Option<UniversalTimestamp>,
pub created_at: UniversalTimestamp,
pub updated_at: UniversalTimestamp,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NewCronSchedule {
pub workflow_name: String,
pub cron_expression: String,
pub timezone: Option<String>,
pub enabled: Option<UniversalBool>,
pub catchup_policy: Option<String>,
pub start_date: Option<UniversalTimestamp>,
pub end_date: Option<UniversalTimestamp>,
pub next_run_at: UniversalTimestamp,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
pub enum CatchupPolicy {
Skip,
RunAll,
}
impl From<CatchupPolicy> for String {
fn from(policy: CatchupPolicy) -> Self {
match policy {
CatchupPolicy::Skip => "skip".to_string(),
CatchupPolicy::RunAll => "run_all".to_string(),
}
}
}
impl From<String> for CatchupPolicy {
fn from(s: String) -> Self {
match s.as_str() {
"run_all" => CatchupPolicy::RunAll,
"run_once" => CatchupPolicy::Skip,
_ => CatchupPolicy::Skip,
}
}
}
impl From<&str> for CatchupPolicy {
fn from(s: &str) -> Self {
Self::from(s.to_string())
}
}
#[derive(Debug, Clone)]
pub struct ScheduleConfig {
pub name: String,
pub cron: String,
pub workflow: String,
pub timezone: String,
pub catchup_policy: CatchupPolicy,
pub start_date: Option<DateTime<Utc>>,
pub end_date: Option<DateTime<Utc>>,
}
impl Default for ScheduleConfig {
fn default() -> Self {
Self {
name: String::new(),
cron: String::new(),
workflow: String::new(),
timezone: "UTC".to_string(),
catchup_policy: CatchupPolicy::Skip,
start_date: None,
end_date: None,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use crate::database::universal_types::current_timestamp;
#[test]
fn test_cron_schedule_creation() {
let now = current_timestamp();
let schedule = CronSchedule {
id: UniversalUuid::new_v4(),
workflow_name: "test_workflow".to_string(),
cron_expression: "0 2 * * *".to_string(),
timezone: "UTC".to_string(),
enabled: UniversalBool::new(true),
catchup_policy: "skip".to_string(),
start_date: None,
end_date: None,
next_run_at: now,
last_run_at: None,
created_at: now,
updated_at: now,
};
assert_eq!(schedule.workflow_name, "test_workflow");
assert_eq!(schedule.cron_expression, "0 2 * * *");
assert!(schedule.enabled.is_true());
}
#[test]
fn test_catchup_policy_conversions() {
assert_eq!(CatchupPolicy::from("skip"), CatchupPolicy::Skip);
assert_eq!(CatchupPolicy::from("run_all"), CatchupPolicy::RunAll);
assert_eq!(CatchupPolicy::from("run_once"), CatchupPolicy::Skip);
assert_eq!(String::from(CatchupPolicy::Skip), "skip");
assert_eq!(String::from(CatchupPolicy::RunAll), "run_all");
}
}