koprogo_api/application/ports/
convocation_recipient_repository.rs

1use crate::domain::entities::{AttendanceStatus, ConvocationRecipient};
2use async_trait::async_trait;
3use uuid::Uuid;
4
5#[async_trait]
6pub trait ConvocationRecipientRepository: Send + Sync {
7    /// Create a new convocation recipient
8    async fn create(
9        &self,
10        recipient: &ConvocationRecipient,
11    ) -> Result<ConvocationRecipient, String>;
12
13    /// Create multiple recipients at once (bulk insert)
14    async fn create_many(
15        &self,
16        recipients: &[ConvocationRecipient],
17    ) -> Result<Vec<ConvocationRecipient>, String>;
18
19    /// Find recipient by ID
20    async fn find_by_id(&self, id: Uuid) -> Result<Option<ConvocationRecipient>, String>;
21
22    /// Find all recipients for a convocation
23    async fn find_by_convocation(
24        &self,
25        convocation_id: Uuid,
26    ) -> Result<Vec<ConvocationRecipient>, String>;
27
28    /// Find recipient by convocation and owner
29    async fn find_by_convocation_and_owner(
30        &self,
31        convocation_id: Uuid,
32        owner_id: Uuid,
33    ) -> Result<Option<ConvocationRecipient>, String>;
34
35    /// Find recipients by owner (all convocations sent to this owner)
36    async fn find_by_owner(&self, owner_id: Uuid) -> Result<Vec<ConvocationRecipient>, String>;
37
38    /// Find recipients by attendance status
39    async fn find_by_attendance_status(
40        &self,
41        convocation_id: Uuid,
42        status: AttendanceStatus,
43    ) -> Result<Vec<ConvocationRecipient>, String>;
44
45    /// Find recipients who need reminder (email sent but not opened, reminder not sent yet)
46    async fn find_needing_reminder(
47        &self,
48        convocation_id: Uuid,
49    ) -> Result<Vec<ConvocationRecipient>, String>;
50
51    /// Find recipients with failed emails
52    async fn find_failed_emails(
53        &self,
54        convocation_id: Uuid,
55    ) -> Result<Vec<ConvocationRecipient>, String>;
56
57    /// Update recipient
58    async fn update(
59        &self,
60        recipient: &ConvocationRecipient,
61    ) -> Result<ConvocationRecipient, String>;
62
63    /// Delete recipient
64    async fn delete(&self, id: Uuid) -> Result<bool, String>;
65
66    /// Count recipients by convocation
67    async fn count_by_convocation(&self, convocation_id: Uuid) -> Result<i64, String>;
68
69    /// Count recipients who opened email
70    async fn count_opened(&self, convocation_id: Uuid) -> Result<i64, String>;
71
72    /// Count recipients by attendance status
73    async fn count_by_attendance_status(
74        &self,
75        convocation_id: Uuid,
76        status: AttendanceStatus,
77    ) -> Result<i64, String>;
78
79    /// Get tracking summary for a convocation (opened count, attendance counts)
80    async fn get_tracking_summary(
81        &self,
82        convocation_id: Uuid,
83    ) -> Result<RecipientTrackingSummary, String>;
84}
85
86/// Tracking summary for convocation recipients
87#[derive(Debug, Clone)]
88pub struct RecipientTrackingSummary {
89    pub total_count: i64,
90    pub opened_count: i64,
91    pub will_attend_count: i64,
92    pub will_not_attend_count: i64,
93    pub attended_count: i64,
94    pub did_not_attend_count: i64,
95    pub pending_count: i64,
96    pub failed_email_count: i64,
97}