Skip to main content

imagegen_bridge_core/
job.rs

1//! Durable asynchronous generation job contracts.
2
3use schemars::JsonSchema;
4use serde::{Deserialize, Serialize};
5
6use crate::{BridgeError, ImageRequest, ImageResponse};
7
8/// Durable lifecycle state for one asynchronous image operation.
9#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
10#[serde(rename_all = "snake_case")]
11pub enum ImageJobStatus {
12    /// Accepted and waiting for bounded worker capacity.
13    Queued,
14    /// Claimed by a worker; provider completion may be ambiguous after a crash.
15    Running,
16    /// Completed with a verified response.
17    Succeeded,
18    /// Completed with a structured bridge error.
19    Failed,
20    /// Cancelled before or during execution.
21    Cancelled,
22    /// Process stopped while a paid provider call may have been in flight.
23    Interrupted,
24}
25
26impl ImageJobStatus {
27    /// Whether no more execution will occur without a new submission.
28    #[must_use]
29    pub const fn terminal(self) -> bool {
30        matches!(
31            self,
32            Self::Succeeded | Self::Failed | Self::Cancelled | Self::Interrupted
33        )
34    }
35}
36
37/// Bounded latest progress snapshot for a durable job.
38#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
39#[serde(deny_unknown_fields)]
40pub struct ImageJobProgress {
41    /// Stable stage label without prompt or image content.
42    pub stage: String,
43    /// Number of bounded partial-image events observed.
44    pub partial_images: u32,
45}
46
47/// List-safe durable job state without request image bodies.
48#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
49#[serde(deny_unknown_fields)]
50pub struct ImageJobSummary {
51    /// Stable `UUIDv7` job identifier.
52    pub id: String,
53    /// Current durable lifecycle state.
54    pub status: ImageJobStatus,
55    /// Unix creation timestamp.
56    pub created: u64,
57    /// Unix timestamp of the last durable transition.
58    pub updated: u64,
59    /// Worker claim timestamp.
60    #[serde(skip_serializing_if = "Option::is_none")]
61    pub started: Option<u64>,
62    /// Terminal transition timestamp.
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub completed: Option<u64>,
65    /// Latest bounded progress snapshot.
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub progress: Option<ImageJobProgress>,
68    /// User-selected gallery favorite state.
69    pub favorite: bool,
70    /// Soft-delete timestamp; deleted jobs are hidden from ordinary lists.
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub deleted: Option<u64>,
73}
74
75/// Complete durable job record returned by detail lookup.
76#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
77#[serde(deny_unknown_fields)]
78pub struct ImageJob {
79    /// List-safe lifecycle summary.
80    #[serde(flatten)]
81    pub summary: ImageJobSummary,
82    /// Original normalized request retained for recovery and inspection.
83    pub request: ImageRequest,
84    /// Verified terminal result.
85    #[serde(skip_serializing_if = "Option::is_none")]
86    pub result: Option<ImageResponse>,
87    /// Structured terminal error.
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub error: Option<BridgeError>,
90    /// Whether cancellation has been durably requested.
91    pub cancel_requested: bool,
92}
93
94/// Cursor-paginated job/history result.
95#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
96#[serde(deny_unknown_fields)]
97pub struct ImageJobPage {
98    /// Stable newest-first page.
99    pub items: Vec<ImageJobSummary>,
100    /// Opaque cursor for the next page.
101    #[serde(skip_serializing_if = "Option::is_none")]
102    pub next_cursor: Option<String>,
103}
104
105/// Mutable gallery fields for one retained durable job.
106#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, JsonSchema)]
107#[serde(deny_unknown_fields)]
108pub struct ImageJobUpdate {
109    /// Set or clear the favorite marker.
110    #[serde(skip_serializing_if = "Option::is_none")]
111    pub favorite: Option<bool>,
112    /// Soft-delete or restore a terminal history item.
113    #[serde(skip_serializing_if = "Option::is_none")]
114    pub deleted: Option<bool>,
115}