koprogo_api/infrastructure/web/handlers/
gdpr_art30_handlers.rs1use crate::infrastructure::web::{AppState, AuthenticatedUser};
2use actix_web::{get, web, HttpResponse, Responder};
3use serde::Serialize;
4
5#[derive(Debug, Serialize)]
6pub struct DataProcessingActivityDto {
7 pub id: String,
8 pub activity_name: String,
9 pub controller_name: String,
10 pub purpose: String,
11 pub legal_basis: String,
12 pub data_categories: Vec<String>,
13 pub data_subjects: Vec<String>,
14 pub recipients: Vec<String>,
15 pub retention_period: String,
16 pub security_measures: String,
17 pub created_at: String,
18 pub updated_at: String,
19}
20
21#[derive(Debug, Serialize)]
22pub struct DataProcessorAgreementDto {
23 pub id: String,
24 pub processor_name: String,
25 pub service_description: String,
26 pub dpa_signed_at: Option<String>,
27 pub dpa_url: Option<String>,
28 pub transfer_mechanism: Option<String>,
29 pub data_categories: Vec<String>,
30 pub certifications: Option<Vec<String>>,
31 pub created_at: String,
32 pub updated_at: String,
33}
34
35#[derive(Debug, Serialize)]
36pub struct ProcessingActivitiesResponse {
37 pub activities: Vec<DataProcessingActivityDto>,
38 pub total: i64,
39}
40
41#[derive(Debug, Serialize)]
42pub struct ProcessorsResponse {
43 pub processors: Vec<DataProcessorAgreementDto>,
44 pub total: i64,
45}
46
47#[get("/admin/gdpr/processing-register")]
49pub async fn list_processing_activities(
50 data: web::Data<AppState>,
51 auth: AuthenticatedUser,
52) -> impl Responder {
53 if auth.role != "superadmin" {
54 return HttpResponse::Forbidden().json(serde_json::json!({
55 "error": "Access denied. SuperAdmin role required."
56 }));
57 }
58
59 match data.gdpr_art30_use_cases.list_processing_activities().await {
60 Ok(activities) => {
61 let dtos: Vec<DataProcessingActivityDto> = activities
62 .into_iter()
63 .map(|a| DataProcessingActivityDto {
64 id: a.id.to_string(),
65 activity_name: a.activity_name,
66 controller_name: a.controller_name,
67 purpose: a.purpose,
68 legal_basis: a.legal_basis,
69 data_categories: a.data_categories,
70 data_subjects: a.data_subjects,
71 recipients: a.recipients,
72 retention_period: a.retention_period,
73 security_measures: a.security_measures,
74 created_at: a.created_at.to_rfc3339(),
75 updated_at: a.updated_at.to_rfc3339(),
76 })
77 .collect();
78 let total = dtos.len() as i64;
79 HttpResponse::Ok().json(ProcessingActivitiesResponse {
80 activities: dtos,
81 total,
82 })
83 }
84 Err(e) => HttpResponse::InternalServerError().json(
85 serde_json::json!({ "error": format!("Failed to fetch processing activities: {}", e) }),
86 ),
87 }
88}
89
90#[get("/admin/gdpr/processors")]
92pub async fn list_sub_processors(
93 data: web::Data<AppState>,
94 auth: AuthenticatedUser,
95) -> impl Responder {
96 if auth.role != "superadmin" {
97 return HttpResponse::Forbidden().json(serde_json::json!({
98 "error": "Access denied. SuperAdmin role required."
99 }));
100 }
101
102 match data.gdpr_art30_use_cases.list_processor_agreements().await {
103 Ok(processors) => {
104 let dtos: Vec<DataProcessorAgreementDto> = processors
105 .into_iter()
106 .map(|p| DataProcessorAgreementDto {
107 id: p.id.to_string(),
108 processor_name: p.processor_name,
109 service_description: p.service_description,
110 dpa_signed_at: p.dpa_signed_at.map(|dt| dt.to_rfc3339()),
111 dpa_url: p.dpa_url,
112 transfer_mechanism: p.transfer_mechanism,
113 data_categories: p.data_categories,
114 certifications: p.certifications,
115 created_at: p.created_at.to_rfc3339(),
116 updated_at: p.updated_at.to_rfc3339(),
117 })
118 .collect();
119 let total = dtos.len() as i64;
120 HttpResponse::Ok().json(ProcessorsResponse {
121 processors: dtos,
122 total,
123 })
124 }
125 Err(e) => HttpResponse::InternalServerError()
126 .json(serde_json::json!({ "error": format!("Failed to fetch sub-processors: {}", e) })),
127 }
128}