use chrono::Utc;
use serde::{Deserialize, Serialize};
use super::event::AuditEvent;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct DataSubjectReport {
pub data_subject_id: String,
pub events: Vec<AuditEvent>,
pub generated_at: chrono::DateTime<Utc>,
pub event_count: usize,
}
impl DataSubjectReport {
pub fn to_json(&self) -> Result<String, serde_json::Error> {
serde_json::to_string(self)
}
}
pub struct GdprService;
impl GdprService {
pub fn data_subject_report(events: &[AuditEvent], data_subject_id: &str) -> DataSubjectReport {
let mut matching: Vec<AuditEvent> = events
.iter()
.filter(|e| e.data_subject_id.as_deref() == Some(data_subject_id))
.cloned()
.collect();
matching.sort_by_key(|e| e.timestamp);
let event_count = matching.len();
DataSubjectReport {
data_subject_id: data_subject_id.to_string(),
events: matching,
generated_at: Utc::now(),
event_count,
}
}
pub fn pseudonymise(events: &mut [AuditEvent], data_subject_id: &str) -> usize {
let mut count = 0usize;
for event in events.iter_mut() {
if event.data_subject_id.as_deref() == Some(data_subject_id) {
event.actor.actor_id = "[redacted]".to_string();
event.actor.ip_address = Some("[redacted]".to_string());
event.actor.session_id = Some("[redacted]".to_string());
event.data_subject_id = Some("[redacted]".to_string());
count += 1;
}
}
count
}
}