use sqlx::PgPool;
use uuid::Uuid;
use crate::domain::drift::DriftSignal;
pub struct NewDriftSignal<'a> {
pub drift_type: &'a str,
pub target_entity_id: Uuid,
pub target_entity_type: &'a str,
pub summary: &'a str,
pub severity: &'a str,
pub explanation: &'a str,
}
pub async fn create(pool: &PgPool, new: NewDriftSignal<'_>) -> Result<DriftSignal, sqlx::Error> {
let id = Uuid::new_v4();
sqlx::query_as::<_, DriftSignal>(
r#"
INSERT INTO drift_signals
(id, drift_type, target_entity_id, target_entity_type, summary, severity, explanation, status)
VALUES ($1, $2, $3, $4, $5, $6, $7, 'open')
RETURNING id, drift_type, target_entity_id, target_entity_type, summary, severity,
explanation, status, created_at
"#,
)
.bind(id)
.bind(new.drift_type)
.bind(new.target_entity_id)
.bind(new.target_entity_type)
.bind(new.summary)
.bind(new.severity)
.bind(new.explanation)
.fetch_one(pool)
.await
}
pub async fn get(pool: &PgPool, id: Uuid) -> Result<Option<DriftSignal>, sqlx::Error> {
sqlx::query_as::<_, DriftSignal>(
r#"
SELECT id, drift_type, target_entity_id, target_entity_type, summary, severity,
explanation, status, created_at
FROM drift_signals
WHERE id = $1
"#,
)
.bind(id)
.fetch_optional(pool)
.await
}
pub async fn list(
pool: &PgPool,
status: Option<&str>,
limit: i64,
) -> Result<Vec<DriftSignal>, sqlx::Error> {
sqlx::query_as::<_, DriftSignal>(
r#"
SELECT id, drift_type, target_entity_id, target_entity_type, summary, severity,
explanation, status, created_at
FROM drift_signals
WHERE ($1::text IS NULL OR status = $1)
ORDER BY created_at DESC
LIMIT $2
"#,
)
.bind(status)
.bind(limit)
.fetch_all(pool)
.await
}
pub async fn list_for_entity(
pool: &PgPool,
entity_id: Uuid,
) -> Result<Vec<DriftSignal>, sqlx::Error> {
sqlx::query_as::<_, DriftSignal>(
r#"
SELECT id, drift_type, target_entity_id, target_entity_type, summary, severity,
explanation, status, created_at
FROM drift_signals
WHERE target_entity_id = $1
ORDER BY created_at DESC
"#,
)
.bind(entity_id)
.fetch_all(pool)
.await
}
pub async fn update_status(
pool: &PgPool,
id: Uuid,
status: &str,
) -> Result<Option<DriftSignal>, sqlx::Error> {
sqlx::query_as::<_, DriftSignal>(
r#"
UPDATE drift_signals
SET status = $2
WHERE id = $1
RETURNING id, drift_type, target_entity_id, target_entity_type, summary, severity,
explanation, status, created_at
"#,
)
.bind(id)
.bind(status)
.fetch_optional(pool)
.await
}