1use chrono::{DateTime, Utc};
4use serde::{Deserialize, Serialize};
5use zart_scheduler::{ExecutionRecord, ExecutionSortField, ListExecutionsParams, SortOrder};
6
7#[derive(Debug, Deserialize)]
11#[serde(rename_all = "camelCase")]
12pub struct StartExecutionRequest {
13 #[serde(default)]
15 pub execution_id: Option<String>,
16 pub task_name: String,
18 #[serde(default)]
20 pub payload: serde_json::Value,
21}
22
23#[derive(Debug, Deserialize)]
25#[serde(rename_all = "camelCase")]
26pub struct ListQuery {
27 pub status: Option<String>,
28 pub task_name: Option<String>,
29 pub from: Option<DateTime<Utc>>,
30 pub to: Option<DateTime<Utc>>,
31 pub search: Option<String>,
32 pub sort_by: Option<String>,
33 pub sort_order: Option<String>,
34 #[serde(default = "default_limit")]
35 pub limit: usize,
36 #[serde(default)]
37 pub offset: usize,
38}
39
40impl ListQuery {
41 pub fn into_params(self) -> ListExecutionsParams {
42 let status = self
43 .status
44 .as_deref()
45 .and_then(|s| s.parse::<zart_scheduler::ExecutionStatus>().ok());
46 let sort_by = match self.sort_by.as_deref() {
47 Some("status") => ExecutionSortField::Status,
48 Some("taskName") => ExecutionSortField::TaskName,
49 _ => ExecutionSortField::ScheduledAt,
50 };
51 let sort_order = match self.sort_order.as_deref() {
52 Some("asc") => SortOrder::Asc,
53 _ => SortOrder::Desc,
54 };
55 ListExecutionsParams {
56 status,
57 task_name: self.task_name,
58 from: self.from,
59 to: self.to,
60 search: self.search,
61 sort_by,
62 sort_order,
63 limit: self.limit,
64 offset: self.offset,
65 }
66 }
67}
68
69fn default_limit() -> usize {
70 20
71}
72
73#[derive(Debug, Deserialize)]
75#[serde(rename_all = "camelCase")]
76pub struct WaitQuery {
77 pub timeout_secs: Option<u64>,
79}
80
81#[derive(Debug, Serialize)]
85#[serde(rename_all = "camelCase")]
86pub struct ExecutionResponse {
87 pub name: String,
89 pub durable_execution_id: String,
91 pub payload: serde_json::Value,
93 pub status: String,
95 pub scheduled_at: DateTime<Utc>,
97 pub completed_at: Option<DateTime<Utc>>,
99 pub version: i32,
101 pub result: Option<serde_json::Value>,
103}
104
105impl From<ExecutionRecord> for ExecutionResponse {
106 fn from(r: ExecutionRecord) -> Self {
107 Self {
108 name: r.task_name,
109 durable_execution_id: r.execution_id,
110 payload: r.payload,
111 status: r.status.to_string(),
112 scheduled_at: r.scheduled_at,
113 completed_at: r.completed_at,
114 version: r.version,
115 result: r.result,
116 }
117 }
118}
119
120#[derive(Debug, Serialize)]
122#[serde(rename_all = "camelCase")]
123pub struct StartExecutionResponse {
124 pub execution_id: String,
125 pub task_id: String,
126}
127
128#[derive(Debug, Serialize)]
130pub struct ErrorResponse {
131 pub error: String,
132}
133
134#[derive(Debug, Deserialize)]
138#[serde(rename_all = "camelCase")]
139pub struct RetryStepRequest {
140 pub step_name: String,
141 #[serde(default)]
142 pub triggered_by: Option<String>,
143}
144
145#[derive(Debug, Deserialize)]
147#[serde(rename_all = "camelCase")]
148pub struct RestartRequest {
149 #[serde(default)]
150 pub payload: Option<serde_json::Value>,
151 #[serde(default)]
152 pub triggered_by: Option<String>,
153}
154
155#[derive(Debug, Deserialize)]
157#[serde(rename_all = "camelCase")]
158pub struct RerunRequest {
159 #[serde(default)]
160 pub rerun_steps: Vec<String>,
161 #[serde(default)]
162 pub preserve_steps: Vec<String>,
163 #[serde(default)]
164 pub triggered_by: Option<String>,
165}
166
167#[derive(Debug, Serialize)]
171#[serde(rename_all = "camelCase")]
172pub struct RetryStepResponse {
173 pub new_task_id: String,
174}
175
176#[derive(Debug, Serialize)]
178#[serde(rename_all = "camelCase")]
179pub struct RestartResponse {
180 pub new_run_id: String,
181}
182
183#[derive(Debug, Serialize)]
185#[serde(rename_all = "camelCase")]
186pub struct RerunResponse {
187 pub new_run_number: u32,
188 pub effective_rerun: Vec<String>,
189}
190
191#[derive(Debug, Serialize)]
193#[serde(rename_all = "camelCase")]
194pub struct RunRecordResponse {
195 pub run_id: String,
196 pub execution_id: String,
197 pub run_index: i32,
198 pub payload: serde_json::Value,
199 pub status: String,
200 pub result: Option<serde_json::Value>,
201 pub started_at: DateTime<Utc>,
202 pub completed_at: Option<DateTime<Utc>>,
203 pub trigger: String,
204}
205
206#[derive(Debug, Deserialize)]
210#[serde(rename_all = "camelCase")]
211pub struct PauseRequest {
212 #[serde(default)]
213 pub execution_id: Option<String>,
214 #[serde(default)]
215 pub task_name: Option<String>,
216 #[serde(default)]
217 pub step_pattern: Option<String>,
218 #[serde(default)]
219 pub expires_at: Option<DateTime<Utc>>,
220 #[serde(default)]
221 pub triggered_by: Option<String>,
222}
223
224#[derive(Debug, Serialize)]
226#[serde(rename_all = "camelCase")]
227pub struct PauseRuleResponse {
228 pub rule_id: String,
229 #[serde(default)]
230 pub execution_id: Option<String>,
231 #[serde(default)]
232 pub task_name: Option<String>,
233 #[serde(default)]
234 pub step_pattern: Option<String>,
235 pub created_at: DateTime<Utc>,
236 #[serde(default)]
237 pub expires_at: Option<DateTime<Utc>>,
238 #[serde(default)]
239 pub created_by: Option<String>,
240 #[serde(default)]
241 pub deleted_at: Option<DateTime<Utc>>,
242}
243
244#[derive(Debug, Serialize)]
246#[serde(rename_all = "camelCase")]
247pub struct ResumeResponse {
248 pub rules_deleted: usize,
249}
250
251#[derive(Debug, Serialize)]
253#[serde(rename_all = "camelCase")]
254pub struct StatsResponse {
255 pub scheduled: i64,
256 pub running: i64,
257 pub completed: i64,
258 pub failed: i64,
259 pub cancelled: i64,
260}
261
262impl From<zart_scheduler::ExecutionStats> for StatsResponse {
263 fn from(s: zart_scheduler::ExecutionStats) -> Self {
264 Self {
265 scheduled: s.scheduled,
266 running: s.running,
267 completed: s.completed,
268 failed: s.failed,
269 cancelled: s.cancelled,
270 }
271 }
272}
273
274#[derive(Debug, Serialize)]
276#[serde(rename_all = "camelCase")]
277pub struct ExecutionDetailResponse {
278 pub execution: ExecutionResponse,
279 pub runs: Vec<RunRecordResponse>,
280 pub steps: Vec<StepDetailResponse>,
281}
282
283#[derive(Debug, Serialize)]
285#[serde(rename_all = "camelCase")]
286pub struct StepDetailResponse {
287 pub step_id: String,
288 pub name: String,
289 pub kind: String,
290 pub status: String,
291 pub retry_attempt: i32,
292 pub result: Option<serde_json::Value>,
293 pub last_error: Option<String>,
294 pub retryable: bool,
295 pub scheduled_at: DateTime<Utc>,
296 pub completed_at: Option<DateTime<Utc>>,
297 pub attempts: Vec<StepAttemptResponse>,
298}
299
300#[derive(Debug, Serialize)]
302#[serde(rename_all = "camelCase")]
303pub struct StepAttemptResponse {
304 pub attempt_number: i32,
305 pub status: String,
306 pub result: Option<serde_json::Value>,
307 pub error: Option<String>,
308 pub started_at: DateTime<Utc>,
309 pub completed_at: Option<DateTime<Utc>>,
310}