koprogo_api/application/ports/
challenge_repository.rs

1use crate::domain::entities::{Challenge, ChallengeProgress, ChallengeStatus};
2use async_trait::async_trait;
3use uuid::Uuid;
4
5/// Repository trait for Challenge persistence operations
6#[async_trait]
7pub trait ChallengeRepository: Send + Sync {
8    /// Create a new challenge
9    async fn create(&self, challenge: &Challenge) -> Result<Challenge, String>;
10
11    /// Find challenge by ID
12    async fn find_by_id(&self, id: Uuid) -> Result<Option<Challenge>, String>;
13
14    /// Find all challenges for an organization
15    async fn find_by_organization(&self, organization_id: Uuid) -> Result<Vec<Challenge>, String>;
16
17    /// Find challenges by organization and status
18    async fn find_by_organization_and_status(
19        &self,
20        organization_id: Uuid,
21        status: ChallengeStatus,
22    ) -> Result<Vec<Challenge>, String>;
23
24    /// Find challenges by building
25    async fn find_by_building(&self, building_id: Uuid) -> Result<Vec<Challenge>, String>;
26
27    /// Find active challenges (status = Active AND now >= start_date AND now < end_date)
28    async fn find_active(&self, organization_id: Uuid) -> Result<Vec<Challenge>, String>;
29
30    /// Find challenges that have ended but not yet marked Completed
31    async fn find_ended_not_completed(&self) -> Result<Vec<Challenge>, String>;
32
33    /// Update challenge
34    async fn update(&self, challenge: &Challenge) -> Result<Challenge, String>;
35
36    /// Delete challenge
37    async fn delete(&self, id: Uuid) -> Result<(), String>;
38
39    /// Count challenges by organization
40    async fn count_by_organization(&self, organization_id: Uuid) -> Result<i64, String>;
41}
42
43/// Repository trait for ChallengeProgress persistence operations
44#[async_trait]
45pub trait ChallengeProgressRepository: Send + Sync {
46    /// Create new challenge progress tracking
47    async fn create(&self, progress: &ChallengeProgress) -> Result<ChallengeProgress, String>;
48
49    /// Find progress by ID
50    async fn find_by_id(&self, id: Uuid) -> Result<Option<ChallengeProgress>, String>;
51
52    /// Find progress by user and challenge
53    async fn find_by_user_and_challenge(
54        &self,
55        user_id: Uuid,
56        challenge_id: Uuid,
57    ) -> Result<Option<ChallengeProgress>, String>;
58
59    /// Find all progress for a user
60    async fn find_by_user(&self, user_id: Uuid) -> Result<Vec<ChallengeProgress>, String>;
61
62    /// Find all progress for a challenge
63    async fn find_by_challenge(&self, challenge_id: Uuid)
64        -> Result<Vec<ChallengeProgress>, String>;
65
66    /// Find active progress for user (challenge is Active and not completed)
67    async fn find_active_by_user(&self, user_id: Uuid) -> Result<Vec<ChallengeProgress>, String>;
68
69    /// Update progress
70    async fn update(&self, progress: &ChallengeProgress) -> Result<ChallengeProgress, String>;
71
72    /// Count completed challenges for user
73    async fn count_completed_by_user(&self, user_id: Uuid) -> Result<i64, String>;
74
75    /// Get leaderboard data (top users by points)
76    async fn get_leaderboard(
77        &self,
78        organization_id: Uuid,
79        building_id: Option<Uuid>,
80        limit: i64,
81    ) -> Result<Vec<(Uuid, i32)>, String>; // Returns (user_id, total_points)
82}