use crate::runtime::native_catalog::NativeModel;
use uuid::Uuid;
pub(crate) fn workflow_project_bind(project_id: &str) -> String {
let trimmed = project_id.trim();
if trimmed.is_empty() || Uuid::parse_str(trimmed).is_err() {
String::new()
} else {
trimmed.to_string()
}
}
pub(crate) fn workflow_scope_predicate(
m: &NativeModel,
tenant_bind: &str,
project_bind: &str,
) -> String {
format!(
"{tenant_id} = {tenant_bind}::UUID AND \
({project_bind} = '' OR {project_id} = NULLIF({project_bind}, '')::UUID)",
tenant_id = m.q("tenant_id"),
project_id = m.q("project_id"),
)
}
pub(crate) fn workflow_select_projection(m: &NativeModel) -> String {
[
m.text("workflow_id"),
m.text("tenant_id"),
m.text_or_empty("project_id"),
m.select("workflow_type"),
m.select("status"),
m.select("current_step"),
m.select("total_steps"),
m.text_or_empty("payload"),
m.text_or_empty("compensations"),
m.text_or_empty("correlation_id"),
m.text_or_empty("saga_id"),
m.text_or_empty("pending_signal"),
m.text_or_empty("last_error"),
format!(
"EXTRACT(EPOCH FROM {})::BIGINT AS next_run_at_epoch",
m.q("next_run_at")
),
format!(
"EXTRACT(EPOCH FROM {})::BIGINT AS last_transition_at_epoch",
m.q("last_transition_at")
),
]
.join(", ")
}