use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use uuid::Uuid;
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum SourceKind {
GitFlake,
FlakeOutput,
}
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
#[serde(rename_all = "snake_case")]
pub enum SourceStatus {
Pending,
Ready,
Failed,
Suspended,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Source {
pub id: Uuid,
pub name: String,
pub kind: SourceKind,
pub flake_ref: String,
pub status: SourceStatus,
pub last_rev: Option<String>,
pub last_reconciled_at: Option<DateTime<Utc>>,
pub last_error: Option<String>,
#[serde(default)]
pub managed_jobs: HashMap<String, String>,
pub created_at: DateTime<Utc>,
}
impl Source {
pub fn new(name: String, kind: SourceKind, flake_ref: String) -> Self {
Self {
id: Uuid::new_v4(),
name,
kind,
flake_ref,
status: SourceStatus::Pending,
last_rev: None,
last_reconciled_at: None,
last_error: None,
managed_jobs: HashMap::new(),
created_at: Utc::now(),
}
}
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CreateSourceRequest {
pub name: String,
pub flake_ref: String,
#[serde(default = "default_kind")]
pub kind: SourceKind,
}
fn default_kind() -> SourceKind {
SourceKind::GitFlake
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct FlakeMetadata {
pub rev: Option<String>,
pub last_modified: u64,
pub url: String,
}
#[derive(Debug, thiserror::Error)]
pub enum SourceError {
#[error("metadata fetch failed for '{flake_ref}': {reason}")]
MetadataFetchFailed { flake_ref: String, reason: String },
#[error("eval failed for '{flake_ref}': {reason}")]
EvalFailed { flake_ref: String, reason: String },
#[error("validation failed for source '{name}': {errors:?}")]
ValidationFailed { name: String, errors: Vec<String> },
#[error("job operation failed for '{job_name}' in source '{source_name}': {reason}")]
JobOperationFailed {
source_name: String,
job_name: String,
reason: String,
},
#[error("operation timed out for '{flake_ref}' after {timeout_secs}s")]
Timeout {
flake_ref: String,
timeout_secs: u64,
},
}