use chrono::NaiveDateTime;
#[derive(Debug, Clone, sqlx::FromRow)]
pub struct Workflow {
pub workflow_id: String,
pub version: i64,
pub name: String,
pub description: Option<String>,
pub priority: i64,
pub status: String,
pub rollout_percentage: i64,
pub condition_json: String,
pub tasks_json: String,
pub tags_json: String,
pub loop_json: Option<String>,
pub continue_on_error: bool,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
}
#[derive(Debug, Clone, sqlx::FromRow)]
pub struct Channel {
pub channel_id: String,
pub version: i64,
pub name: String,
pub description: Option<String>,
pub channel_type: String,
pub protocol: String,
pub methods_json: Option<String>,
pub route_pattern: Option<String>,
pub topic: Option<String>,
pub consumer_group: Option<String>,
pub transport_config_json: String,
pub workflow_id: Option<String>,
pub config_json: String,
pub status: String,
pub priority: i64,
pub tags_json: String,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
}
impl Channel {
pub fn methods(&self) -> Option<Vec<String>> {
self.methods_json
.as_deref()
.and_then(|m| serde_json::from_str(m).ok())
}
}
#[derive(Debug, Clone, sqlx::FromRow)]
pub struct Connector {
pub id: String,
pub name: String,
pub connector_type: String,
pub config_json: String,
pub enabled: bool,
pub tags_json: String,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
}
#[derive(Debug, Clone, sqlx::FromRow)]
pub struct Trace {
pub id: String,
pub channel: String,
pub channel_id: Option<String>,
pub mode: String,
pub status: String,
pub input_json: Option<String>,
pub result_json: Option<String>,
pub error_message: Option<String>,
pub duration_ms: Option<f64>,
pub started_at: Option<NaiveDateTime>,
pub completed_at: Option<NaiveDateTime>,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
pub task_trace_json: Option<String>,
pub access_token_hash: Option<String>,
}
#[derive(Debug, Clone, sqlx::FromRow)]
pub struct TraceListRow {
pub id: String,
pub channel: String,
pub channel_id: Option<String>,
pub mode: String,
pub status: String,
pub error_message: Option<String>,
pub duration_ms: Option<f64>,
pub started_at: Option<NaiveDateTime>,
pub completed_at: Option<NaiveDateTime>,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
}
#[derive(Debug, Clone, sqlx::FromRow)]
pub struct TraceDlqEntry {
pub id: String,
pub trace_id: String,
pub channel: String,
pub payload_json: String,
pub metadata_json: String,
pub error_message: String,
pub retry_count: i64,
pub max_retries: i64,
pub next_retry_at: NaiveDateTime,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
}
#[derive(Debug, Clone, sqlx::FromRow)]
pub struct TraceDlqSummary {
pub id: String,
pub trace_id: String,
pub channel: String,
pub error_message: String,
pub retry_count: i64,
pub max_retries: i64,
pub next_retry_at: NaiveDateTime,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
}
#[derive(Debug, Clone, sqlx::FromRow)]
pub struct PackageReceipt {
pub name: String,
pub version: String,
pub content_hash: String,
pub state: String,
pub principal: String,
pub created_at: NaiveDateTime,
pub updated_at: NaiveDateTime,
}
#[derive(Debug, Clone, sqlx::FromRow)]
pub struct AuditLogEntry {
pub id: String,
pub principal: String,
pub action: String,
pub resource_type: String,
pub resource_id: String,
pub details: Option<String>,
pub created_at: NaiveDateTime,
}
#[cfg(test)]
mod tests {
#[test]
fn row_structs_are_not_wire_types() {
const SOURCE: &str = include_str!("rows.rs");
let mut rest = SOURCE;
while let Some(start) = rest.find("#[derive(") {
rest = &rest[start + "#[derive(".len()..];
let end = rest.find(")]").expect("unterminated #[derive(...)]");
let derives = &rest[..end];
for banned in ["Serialize", "ToSchema"] {
assert!(
!derives.contains(banned),
"`{banned}` derived on a row struct in models/rows.rs \
(derive list: `{derives}`). A row struct is a picture of a table, \
not a wire shape — give it a DTO in models/dto.rs and a \
`From`/`TryFrom` instead."
);
}
rest = &rest[end..];
}
}
}