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 reference_number: String, pub job_id: Uuid, pub applicant_user_id: Uuid, pub cover_note: Option, pub status: String, pub applied_at: DateTime, pub updated_at: DateTime, } #[derive(Debug, Serialize, Deserialize)] pub struct CreateApplicationPayload { pub job_id: Uuid, pub applicant_user_id: Uuid, pub cover_note: Option, } pub struct ApplicationRepository; impl ApplicationRepository { pub async fn create( pool: &PgPool, payload: CreateApplicationPayload, ) -> Result { let app = sqlx::query_as::<_, Application>( r#" INSERT INTO job_applications (job_id, applicant_user_id, cover_note) VALUES ($1, $2, $3) RETURNING * "#, ) .bind(payload.job_id) .bind(payload.applicant_user_id) .bind(payload.cover_note) .fetch_one(pool) .await?; Ok(app) } pub async fn get_by_id(pool: &PgPool, id: Uuid) -> Result, sqlx::Error> { sqlx::query_as::<_, Application>("SELECT * FROM job_applications WHERE id = $1") .bind(id) .fetch_optional(pool) .await } pub async fn list_by_job_id( pool: &PgPool, job_id: Uuid, status: Option, page: i64, limit: i64, ) -> Result, sqlx::Error> { let offset = (page - 1) * limit; let apps = sqlx::query_as::<_, Application>( r#" SELECT * FROM job_applications WHERE job_id = $1 AND ($2::VARCHAR IS NULL OR status = $2) ORDER BY applied_at DESC LIMIT $3 OFFSET $4 "#, ) .bind(job_id) .bind(status) .bind(limit) .bind(offset) .fetch_all(pool) .await?; Ok(apps) } pub async fn list_by_user_id( pool: &PgPool, applicant_user_id: Uuid, page: i64, limit: i64, ) -> Result, sqlx::Error> { let offset = (page - 1) * limit; let apps = sqlx::query_as::<_, Application>( r#" SELECT * FROM job_applications WHERE applicant_user_id = $1 ORDER BY applied_at DESC LIMIT $2 OFFSET $3 "#, ) .bind(applicant_user_id) .bind(limit) .bind(offset) .fetch_all(pool) .await?; Ok(apps) } pub async fn update_status( pool: &PgPool, id: Uuid, status: &str, ) -> Result { let app = sqlx::query_as::<_, Application>( "UPDATE job_applications SET status = $1, updated_at = NOW() WHERE id = $2 RETURNING *", ) .bind(status) .bind(id) .fetch_one(pool) .await?; Ok(app) } }