1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5
6#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
8#[serde(rename_all = "lowercase")]
9pub enum JobType {
10 #[default]
11 Shell,
12 Agent,
13}
14
15impl JobType {
16 pub fn as_str(&self) -> &'static str {
17 match self {
18 Self::Shell => "shell",
19 Self::Agent => "agent",
20 }
21 }
22
23 pub fn parse(raw: &str) -> Self {
24 if raw.eq_ignore_ascii_case("agent") {
25 Self::Agent
26 } else {
27 Self::Shell
28 }
29 }
30}
31
32#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq, Default)]
34#[serde(rename_all = "lowercase")]
35pub enum SessionTarget {
36 #[default]
37 Isolated,
38 Main,
39}
40
41impl SessionTarget {
42 pub fn as_str(&self) -> &'static str {
43 match self {
44 Self::Isolated => "isolated",
45 Self::Main => "main",
46 }
47 }
48
49 pub fn parse(raw: &str) -> Self {
50 if raw.eq_ignore_ascii_case("main") {
51 Self::Main
52 } else {
53 Self::Isolated
54 }
55 }
56}
57
58#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
60#[serde(tag = "kind", rename_all = "lowercase")]
61pub enum Schedule {
62 Cron {
64 expr: String,
65 #[serde(default)]
66 tz: Option<String>,
67 },
68 At { at: DateTime<Utc> },
70 Every { every_ms: u64 },
72}
73
74#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
76pub struct DeliveryConfig {
77 #[serde(default)]
78 pub mode: String,
79 #[serde(default)]
80 pub channel: Option<String>,
81 #[serde(default)]
82 pub to: Option<String>,
83 #[serde(default = "default_true")]
84 pub best_effort: bool,
85}
86
87impl Default for DeliveryConfig {
88 fn default() -> Self {
89 Self {
90 mode: "none".to_string(),
91 channel: None,
92 to: None,
93 best_effort: true,
94 }
95 }
96}
97
98fn default_true() -> bool {
99 true
100}
101
102#[derive(Debug, Clone, Serialize, Deserialize)]
104pub struct CronJob {
105 pub id: String,
106 pub expression: String,
107 pub schedule: Schedule,
108 pub command: String,
109 pub prompt: Option<String>,
110 pub name: Option<String>,
111 pub job_type: JobType,
112 pub session_target: SessionTarget,
113 pub model: Option<String>,
114 pub enabled: bool,
115 pub delivery: DeliveryConfig,
116 pub delete_after_run: bool,
117 pub created_at: DateTime<Utc>,
118 pub next_run: DateTime<Utc>,
119 pub last_run: Option<DateTime<Utc>>,
120 pub last_status: Option<String>,
121 pub last_output: Option<String>,
122}
123
124#[derive(Debug, Clone, Serialize, Deserialize)]
126pub struct CronRun {
127 pub id: i64,
128 pub job_id: String,
129 pub started_at: DateTime<Utc>,
130 pub finished_at: DateTime<Utc>,
131 pub status: String,
132 pub output: Option<String>,
133 pub duration_ms: Option<i64>,
134}
135
136#[derive(Debug, Clone, Default, Serialize, Deserialize)]
138pub struct CronJobPatch {
139 pub schedule: Option<Schedule>,
140 pub command: Option<String>,
141 pub prompt: Option<String>,
142 pub name: Option<String>,
143 pub enabled: Option<bool>,
144 pub delivery: Option<DeliveryConfig>,
145 pub model: Option<String>,
146 pub session_target: Option<SessionTarget>,
147 pub delete_after_run: Option<bool>,
148}