use sqlx::PgPool;
use uuid::Uuid;
use crate::domain::candidates::ExtractionCandidate;
pub async fn create(
pool: &PgPool,
document_id: Option<Uuid>,
candidate_type: &str,
payload: &serde_json::Value,
) -> Result<ExtractionCandidate, sqlx::Error> {
let id = Uuid::new_v4();
sqlx::query_as::<_, ExtractionCandidate>(
r#"
INSERT INTO extraction_candidates (id, document_id, candidate_type, payload, status)
VALUES ($1, $2, $3, $4, 'pending')
RETURNING id, document_id, candidate_type, payload, status, created_at, updated_at
"#,
)
.bind(id)
.bind(document_id)
.bind(candidate_type)
.bind(payload)
.fetch_one(pool)
.await
}
pub async fn get(
pool: &PgPool,
id: Uuid,
) -> Result<Option<ExtractionCandidate>, sqlx::Error> {
sqlx::query_as::<_, ExtractionCandidate>(
r#"
SELECT id, document_id, candidate_type, payload, status, created_at, updated_at
FROM extraction_candidates
WHERE id = $1
"#,
)
.bind(id)
.fetch_optional(pool)
.await
}
pub async fn list_by_document(
pool: &PgPool,
document_id: Uuid,
status: Option<&str>,
) -> Result<Vec<ExtractionCandidate>, sqlx::Error> {
sqlx::query_as::<_, ExtractionCandidate>(
r#"
SELECT id, document_id, candidate_type, payload, status, created_at, updated_at
FROM extraction_candidates
WHERE document_id = $1
AND ($2::text IS NULL OR status = $2)
ORDER BY created_at ASC
"#,
)
.bind(document_id)
.bind(status)
.fetch_all(pool)
.await
}
pub async fn list_all(
pool: &PgPool,
status: Option<&str>,
limit: i64,
) -> Result<Vec<ExtractionCandidate>, sqlx::Error> {
sqlx::query_as::<_, ExtractionCandidate>(
r#"
SELECT id, document_id, candidate_type, payload, status, created_at, updated_at
FROM extraction_candidates
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 update_status(
pool: &PgPool,
id: Uuid,
status: &str,
) -> Result<Option<ExtractionCandidate>, sqlx::Error> {
sqlx::query_as::<_, ExtractionCandidate>(
r#"
UPDATE extraction_candidates
SET status = $2, updated_at = now()
WHERE id = $1
RETURNING id, document_id, candidate_type, payload, status, created_at, updated_at
"#,
)
.bind(id)
.bind(status)
.fetch_optional(pool)
.await
}