koprogo_api/infrastructure/database/repositories/
gdpr_art30_repository_impl.rs

1use crate::application::ports::gdpr_art30_repository::GdprArt30Repository;
2use crate::domain::entities::gdpr_art30::{ProcessingActivity, ProcessorAgreement};
3use crate::infrastructure::database::pool::DbPool;
4use async_trait::async_trait;
5use sqlx::Row;
6
7pub struct PostgresGdprArt30Repository {
8    pool: DbPool,
9}
10
11impl PostgresGdprArt30Repository {
12    pub fn new(pool: DbPool) -> Self {
13        Self { pool }
14    }
15}
16
17#[async_trait]
18impl GdprArt30Repository for PostgresGdprArt30Repository {
19    async fn list_processing_activities(&self) -> Result<Vec<ProcessingActivity>, String> {
20        let rows = sqlx::query(
21            r#"
22            SELECT id, activity_name, controller_name, purpose, legal_basis,
23                   data_categories, data_subjects, recipients,
24                   retention_period, security_measures, created_at, updated_at
25            FROM data_processing_activities
26            ORDER BY created_at DESC
27            "#,
28        )
29        .fetch_all(&self.pool)
30        .await
31        .map_err(|e| format!("Failed to fetch processing activities: {}", e))?;
32
33        Ok(rows
34            .iter()
35            .map(|row| ProcessingActivity {
36                id: row.get("id"),
37                activity_name: row.get("activity_name"),
38                controller_name: row.get("controller_name"),
39                purpose: row.get("purpose"),
40                legal_basis: row.get("legal_basis"),
41                data_categories: row
42                    .try_get::<Option<Vec<String>>, _>("data_categories")
43                    .ok()
44                    .flatten()
45                    .unwrap_or_default(),
46                data_subjects: row
47                    .try_get::<Option<Vec<String>>, _>("data_subjects")
48                    .ok()
49                    .flatten()
50                    .unwrap_or_default(),
51                recipients: row
52                    .try_get::<Option<Vec<String>>, _>("recipients")
53                    .ok()
54                    .flatten()
55                    .unwrap_or_default(),
56                retention_period: row.get("retention_period"),
57                security_measures: row.get("security_measures"),
58                created_at: row.get("created_at"),
59                updated_at: row.get("updated_at"),
60            })
61            .collect())
62    }
63
64    async fn list_processor_agreements(&self) -> Result<Vec<ProcessorAgreement>, String> {
65        let rows = sqlx::query(
66            r#"
67            SELECT id, processor_name, service_description,
68                   dpa_signed_at, dpa_url, transfer_mechanism,
69                   data_categories, certifications, created_at, updated_at
70            FROM data_processor_agreements
71            ORDER BY processor_name ASC
72            "#,
73        )
74        .fetch_all(&self.pool)
75        .await
76        .map_err(|e| format!("Failed to fetch processor agreements: {}", e))?;
77
78        Ok(rows
79            .iter()
80            .map(|row| ProcessorAgreement {
81                id: row.get("id"),
82                processor_name: row.get("processor_name"),
83                service_description: row.get("service_description"),
84                dpa_signed_at: row.try_get("dpa_signed_at").ok().flatten(),
85                dpa_url: row.try_get("dpa_url").ok().flatten(),
86                transfer_mechanism: row.try_get("transfer_mechanism").ok().flatten(),
87                data_categories: row
88                    .try_get::<Option<Vec<String>>, _>("data_categories")
89                    .ok()
90                    .flatten()
91                    .unwrap_or_default(),
92                certifications: row.try_get("certifications").ok().flatten(),
93                created_at: row.get("created_at"),
94                updated_at: row.get("updated_at"),
95            })
96            .collect())
97    }
98}