nxtgauge-backend-rust/crates/db/src/models/application.rs

135 lines
3.5 KiB
Rust
Raw Normal View History

use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use sqlx::{FromRow, PgPool};
use uuid::Uuid;
#[derive(Debug, Serialize, Deserialize, FromRow)]
pub struct Application {
pub id: Uuid,
pub job_id: Uuid,
pub job_seeker_id: Uuid,
pub cover_letter: Option<String>,
pub resume_url: Option<String>,
pub status: String, // APPLIED, SHORTLISTED, INTERVIEW, OFFERED, HIRED, REJECTED, WITHDRAWN
pub applied_at: DateTime<Utc>,
pub updated_at: DateTime<Utc>,
pub contact_viewed: bool,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct CreateApplicationPayload {
pub job_id: Uuid,
pub job_seeker_id: Uuid,
pub cover_letter: Option<String>,
pub resume_url: Option<String>,
}
pub struct ApplicationRepository;
impl ApplicationRepository {
pub async fn create(
pool: &PgPool,
payload: CreateApplicationPayload,
) -> Result<Application, sqlx::Error> {
let app = sqlx::query_as!(
Application,
r#"
INSERT INTO applications (job_id, job_seeker_id, cover_letter, resume_url)
VALUES ($1, $2, $3, $4)
RETURNING *
"#,
payload.job_id,
payload.job_seeker_id,
payload.cover_letter,
payload.resume_url
)
.fetch_one(pool)
.await?;
Ok(app)
}
pub async fn get_by_id(pool: &PgPool, id: Uuid) -> Result<Option<Application>, sqlx::Error> {
sqlx::query_as!(Application, "SELECT * FROM applications WHERE id = $1", id)
.fetch_optional(pool)
.await
}
pub async fn list_by_job_id(
pool: &PgPool,
job_id: Uuid,
status: Option<String>,
page: i64,
limit: i64,
) -> Result<Vec<Application>, sqlx::Error> {
let offset = (page - 1) * limit;
let apps = sqlx::query_as!(
Application,
r#"
SELECT * FROM applications
WHERE job_id = $1 AND ($2::VARCHAR IS NULL OR status = $2)
ORDER BY applied_at DESC
LIMIT $3 OFFSET $4
"#,
job_id,
status,
limit,
offset
)
.fetch_all(pool)
.await?;
Ok(apps)
}
pub async fn list_by_job_seeker_id(
pool: &PgPool,
job_seeker_id: Uuid,
page: i64,
limit: i64,
) -> Result<Vec<Application>, sqlx::Error> {
let offset = (page - 1) * limit;
let apps = sqlx::query_as!(
Application,
r#"
SELECT * FROM applications
WHERE job_seeker_id = $1
ORDER BY applied_at DESC
LIMIT $2 OFFSET $3
"#,
job_seeker_id,
limit,
offset
)
.fetch_all(pool)
.await?;
Ok(apps)
}
pub async fn update_status(
pool: &PgPool,
id: Uuid,
status: &str,
) -> Result<Application, sqlx::Error> {
let app = sqlx::query_as!(
Application,
"UPDATE applications SET status = $1, updated_at = NOW() WHERE id = $2 RETURNING *",
status,
id
)
.fetch_one(pool)
.await?;
Ok(app)
}
pub async fn mark_contact_viewed(pool: &PgPool, id: Uuid) -> Result<(), sqlx::Error> {
sqlx::query!(
"UPDATE applications SET contact_viewed = true WHERE id = $1",
id
)
.execute(pool)
.await?;
Ok(())
}
}