koprogo_api/infrastructure/database/repositories/
board_alert_repository_impl.rs1use crate::application::error::AppError;
2use crate::application::ports::BoardAlertRepository;
3use crate::domain::entities::{AlertSeverity, BoardAlert};
4use crate::infrastructure::database::pool::DbPool;
5use async_trait::async_trait;
6use sqlx::Row;
7use uuid::Uuid;
8
9pub struct PostgresBoardAlertRepository {
10 pool: DbPool,
11}
12
13impl PostgresBoardAlertRepository {
14 pub fn new(pool: DbPool) -> Self {
15 Self { pool }
16 }
17}
18
19fn row_to_alert(row: sqlx::postgres::PgRow) -> BoardAlert {
20 let severity_str: String = row.get("severity");
21 let severity = severity_str.parse().unwrap_or(AlertSeverity::Info);
22
23 BoardAlert {
24 id: row.get("id"),
25 building_id: row.get("building_id"),
26 raised_by_board_member_id: row.get("raised_by_board_member_id"),
27 text: row.get("text"),
28 severity,
29 target_meeting_id: row.get("target_meeting_id"),
30 created_at: row.get("created_at"),
31 }
32}
33
34#[async_trait]
35impl BoardAlertRepository for PostgresBoardAlertRepository {
36 async fn create(&self, alert: &BoardAlert) -> Result<BoardAlert, AppError> {
37 sqlx::query(
38 r#"
39 INSERT INTO board_alerts
40 (id, building_id, raised_by_board_member_id, text, severity, target_meeting_id, created_at)
41 VALUES ($1, $2, $3, $4, $5, $6, $7)
42 "#,
43 )
44 .bind(alert.id)
45 .bind(alert.building_id)
46 .bind(alert.raised_by_board_member_id)
47 .bind(&alert.text)
48 .bind(alert.severity.to_string())
49 .bind(alert.target_meeting_id)
50 .bind(alert.created_at)
51 .execute(&self.pool)
52 .await
53 .map_err(|e| AppError::Database(format!("Failed to create board alert: {}", e)))?;
54
55 Ok(alert.clone())
56 }
57
58 async fn find_by_target_meeting(&self, meeting_id: Uuid) -> Result<Vec<BoardAlert>, AppError> {
59 let rows = sqlx::query(
60 r#"
61 SELECT id, building_id, raised_by_board_member_id, text, severity, target_meeting_id, created_at
62 FROM board_alerts
63 WHERE target_meeting_id = $1
64 ORDER BY created_at ASC
65 "#,
66 )
67 .bind(meeting_id)
68 .fetch_all(&self.pool)
69 .await
70 .map_err(|e| AppError::Database(format!("Failed to list board alerts: {}", e)))?;
71
72 Ok(rows.into_iter().map(row_to_alert).collect())
73 }
74}