1use chrono::{DateTime, Utc};
2use schemars::JsonSchema;
3use serde::{Deserialize, Serialize};
4use utoipa::{IntoParams, ToSchema};
5use uuid::Uuid;
6
7use crate::{
8 GroupResponse, ImportLibraryFileFromUrlRequest, LibraryFileUploadMetadata,
9 UpsertLibraryTextRequest,
10};
11
12#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema, JsonSchema)]
13#[serde(rename_all = "snake_case")]
14pub enum TaskKind {
15 SourceSync,
16 TextBatch,
17 FileBatch,
18 UrlBatch,
19 DeleteBatch,
20 Translation,
21 VectorRebuild,
22}
23
24impl TaskKind {
25 pub fn as_str(self) -> &'static str {
26 match self {
27 Self::SourceSync => "source_sync",
28 Self::TextBatch => "text_batch",
29 Self::FileBatch => "file_batch",
30 Self::UrlBatch => "url_batch",
31 Self::DeleteBatch => "delete_batch",
32 Self::Translation => "translation",
33 Self::VectorRebuild => "vector_rebuild",
34 }
35 }
36}
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema, JsonSchema)]
39#[serde(rename_all = "snake_case")]
40pub enum TaskStatus {
41 Queued,
42 Running,
43 Waiting,
44 Succeeded,
45 Failed,
46 Cancelled,
47}
48
49impl TaskStatus {
50 pub fn as_str(self) -> &'static str {
51 match self {
52 Self::Queued => "queued",
53 Self::Running => "running",
54 Self::Waiting => "waiting",
55 Self::Succeeded => "succeeded",
56 Self::Failed => "failed",
57 Self::Cancelled => "cancelled",
58 }
59 }
60}
61
62#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema, JsonSchema)]
63#[serde(rename_all = "snake_case")]
64pub enum TaskItemStatus {
65 Queued,
66 Running,
67 Waiting,
68 Succeeded,
69 Failed,
70 Cancelled,
71}
72
73impl TaskItemStatus {
74 pub fn as_str(self) -> &'static str {
75 match self {
76 Self::Queued => "queued",
77 Self::Running => "running",
78 Self::Waiting => "waiting",
79 Self::Succeeded => "succeeded",
80 Self::Failed => "failed",
81 Self::Cancelled => "cancelled",
82 }
83 }
84}
85
86#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
87pub struct TaskRef {
88 pub task_id: Uuid,
89 #[serde(default)]
90 pub item_ids: Vec<Uuid>,
91}
92
93#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
94pub struct TaskProgress {
95 pub total: i64,
96 pub queued: i64,
97 pub running: i64,
98 pub waiting: i64,
99 pub succeeded: i64,
100 pub failed: i64,
101 pub cancelled: i64,
102}
103
104#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema, JsonSchema)]
105#[serde(rename_all = "snake_case")]
106pub enum TaskOrigin {
107 Manual,
108 Rerun,
109}
110
111impl TaskOrigin {
112 pub fn as_str(self) -> &'static str {
113 match self {
114 Self::Manual => "manual",
115 Self::Rerun => "rerun",
116 }
117 }
118}
119
120#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
121pub struct TaskResponse {
122 pub task_id: Uuid,
123 pub kind: TaskKind,
124 pub status: TaskStatus,
125 pub origin: TaskOrigin,
126 pub group_path: Option<String>,
127 pub source_key: Option<String>,
128 pub stage: Option<String>,
129 pub waiting_reason: Option<String>,
130 pub dependency_key: Option<String>,
131 pub progress: TaskProgress,
132 pub failure_stage: Option<String>,
133 pub error_summary: Option<String>,
134 pub eta_seconds: Option<i64>,
135 pub created_at: DateTime<Utc>,
136 pub started_at: Option<DateTime<Utc>>,
137 pub finished_at: Option<DateTime<Utc>>,
138 pub updated_at: DateTime<Utc>,
139}
140
141#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
142pub struct TaskItemResponse {
143 pub item_id: Uuid,
144 pub ordinal: i32,
145 pub status: TaskItemStatus,
146 pub resource_id: Option<String>,
147 pub file_id: Option<Uuid>,
148 pub stage: Option<String>,
149 pub waiting_reason: Option<String>,
150 pub dependency_key: Option<String>,
151 pub next_attempt_at: Option<DateTime<Utc>>,
152 pub failure_stage: Option<String>,
153 pub error_message: Option<String>,
154 pub attempt_count: i32,
155 pub retryable: bool,
156 pub created_at: DateTime<Utc>,
157 pub started_at: Option<DateTime<Utc>>,
158 pub finished_at: Option<DateTime<Utc>>,
159}
160
161#[derive(Debug, Clone, Serialize, Deserialize, IntoParams, ToSchema)]
162#[into_params(parameter_in = Query)]
163pub struct TaskListQuery {
164 #[serde(default = "default_page")]
165 pub page: u32,
166 #[serde(default = "default_page_size")]
167 pub page_size: u32,
168 #[serde(default)]
169 pub query: Option<String>,
170 #[serde(default)]
171 pub kind: Option<TaskKind>,
172 #[serde(default)]
173 pub status: Option<TaskStatus>,
174 #[serde(default)]
175 pub stage: Option<String>,
176 #[serde(default)]
177 pub waiting_reason: Option<String>,
178 #[serde(default)]
179 pub dependency_key: Option<String>,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
183pub struct TaskPageResponse {
184 pub items: Vec<TaskResponse>,
185 pub pagination: crate::Pagination,
186}
187
188#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
189pub struct TaskItemsResponse {
190 pub items: Vec<TaskItemResponse>,
191 pub next_cursor: Option<String>,
192}
193
194#[derive(Debug, Clone, Serialize, Deserialize, IntoParams, ToSchema)]
195#[into_params(parameter_in = Query)]
196pub struct TaskItemsQuery {
197 #[serde(default = "default_item_limit")]
198 pub limit: u32,
199 #[serde(default)]
200 pub cursor: Option<String>,
201}
202
203#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
204pub struct ScopeSpec {
205 pub group_path: String,
206 pub name: String,
207 pub visibility: crate::Visibility,
208 #[serde(default)]
209 pub kind: Option<crate::GroupKind>,
210 #[serde(default)]
211 pub metadata_indexes: Vec<ScopeMetadataIndex>,
212}
213
214#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
215pub struct ScopeMetadataIndex {
216 pub source_key: String,
217 #[serde(flatten)]
218 pub definition: crate::CreateMetadataIndexRequest,
219}
220
221#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
222pub struct EnsureScopeResponse {
223 pub group: GroupResponse,
224 pub metadata_indexes: Vec<crate::MetadataIndexResponse>,
225}
226
227#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
228pub struct TextBatchRequest {
229 pub items: Vec<UpsertLibraryTextRequest>,
230}
231
232#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
233pub struct UrlBatchRequest {
234 pub items: Vec<ImportLibraryFileFromUrlRequest>,
235}
236
237#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
238pub struct DeleteBatchRequest {
239 pub items: Vec<crate::DocumentKey>,
240}
241
242#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
243pub struct FileBatchItem {
244 pub filename: String,
245 pub media_type: String,
246 pub content_base64: String,
247 #[serde(default, skip_serializing_if = "Option::is_none")]
248 pub declared_sha256: Option<String>,
249 #[serde(default)]
250 pub folder_id: Option<Uuid>,
251 #[serde(default)]
252 pub metadata: Option<LibraryFileUploadMetadata>,
253 #[serde(default)]
254 pub translation: Option<crate::TranslationDirective>,
255}
256
257#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
258pub struct FileBatchRequest {
259 pub items: Vec<FileBatchItem>,
260}
261
262#[derive(Debug, Clone, Serialize, Deserialize, ToSchema)]
263#[serde(tag = "kind", rename_all = "snake_case")]
264pub enum TaskSubmitRequest {
265 RetryFileBatch {
267 #[serde(default)]
268 group_path: Option<String>,
269 items: Vec<FileRetryItem>,
270 },
271 FileBatch {
273 #[serde(default)]
274 group_path: Option<String>,
275 items: Vec<FileBatchItem>,
276 },
277 TextBatch {
278 #[serde(default)]
279 group_path: Option<String>,
280 items: Vec<UpsertLibraryTextRequest>,
281 },
282 UrlBatch {
283 #[serde(default)]
284 group_path: Option<String>,
285 items: Vec<ImportLibraryFileFromUrlRequest>,
286 },
287 DeleteBatch {
288 #[serde(default)]
289 group_path: Option<String>,
290 items: Vec<crate::DocumentKey>,
291 },
292 SourceSync {
293 #[serde(default)]
294 group_path: Option<String>,
295 source_key: String,
296 },
297 TranslationBatch {
298 #[serde(default)]
299 group_path: Option<String>,
300 items: Vec<TranslationSubmitItem>,
301 },
302 VectorRebuild,
303}
304
305#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
306pub struct FileRetryItem {
307 pub file_id: Uuid,
308}
309
310#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
311pub struct TranslationSubmitItem {
312 pub document_id: i64,
313 #[serde(default)]
314 pub target_locales: Vec<String>,
315}
316
317#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
318pub struct TaskRetryResponse {
319 pub task: TaskRef,
320 pub retried_items: i64,
321}
322
323#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
324pub struct RerunTaskResponse {
325 pub task: TaskRef,
326}
327
328#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, ToSchema, JsonSchema)]
329#[serde(rename_all = "snake_case")]
330pub enum TaskPurgeMode {
331 Expired,
332 AllTerminal,
333}
334
335#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
336pub struct TaskMaintenanceSettings {
337 pub cleanup_enabled: bool,
338 pub retention_days: i64,
339 pub updated_at: DateTime<Utc>,
340}
341
342#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
343pub struct TaskMaintenanceStats {
344 pub total: i64,
345 pub queued: i64,
346 pub running: i64,
347 pub waiting: i64,
348 pub succeeded: i64,
349 pub failed: i64,
350 pub cancelled: i64,
351 pub active: i64,
352 pub expired_terminal: i64,
353}
354
355#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
356pub struct TaskMaintenanceOverview {
357 pub settings: TaskMaintenanceSettings,
358 pub stats: TaskMaintenanceStats,
359}
360
361#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
362pub struct UpdateTaskMaintenanceSettingsRequest {
363 pub cleanup_enabled: bool,
364 pub retention_days: i64,
365}
366
367#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
368pub struct CancelActiveTasksResponse {
369 pub cancelled_tasks: i64,
370}
371
372#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
373pub struct PurgeTasksRequest {
374 pub mode: TaskPurgeMode,
375}
376
377#[derive(Debug, Clone, Serialize, Deserialize, ToSchema, JsonSchema)]
378pub struct PurgeTasksResponse {
379 pub deleted_tasks: i64,
380}
381
382fn default_page() -> u32 {
383 1
384}
385
386fn default_page_size() -> u32 {
387 50
388}
389
390fn default_item_limit() -> u32 {
391 100
392}