Skip to main content

agentics_persistence/repositories/
challenges.rs

1use sqlx::PgPool;
2
3use crate::db;
4use crate::repositories::{
5    AdminChallengeListItemRecord, ChallengeCatalogFilters, ChallengeMoltbookDiscussionRecord,
6    ChallengeRecord, ChallengeShortlistRecord, ChallengeShortlistRevisionRecord,
7    CreateChallengeShortlistRevisionInput, CreatorChallengeParticipantsRecord,
8    CreatorChallengeStatsRecord, PublishChallengeInput, PublishChallengeRecord,
9    PublishedChallengeAdmission, PublishedChallengeList,
10};
11use agentics_domain::models::evaluation::ScoringMode;
12use agentics_domain::models::ids::{AgentId, HumanId};
13use agentics_domain::models::names::{ChallengeName, TargetName};
14use agentics_domain::models::urls::MoltbookPostUrl;
15use agentics_error::Result;
16
17#[derive(Debug, Clone, Copy)]
18pub struct ChallengesRepository<'a> {
19    pub(super) pool: &'a PgPool,
20}
21
22impl ChallengesRepository<'_> {
23    pub async fn list_admin(&self) -> Result<Vec<AdminChallengeListItemRecord>> {
24        db::challenges::list_admin_challenges(self.pool).await
25    }
26
27    pub async fn set_moltbook_discussion(
28        &self,
29        challenge_name: &ChallengeName,
30        discussion_url: &MoltbookPostUrl,
31    ) -> Result<ChallengeMoltbookDiscussionRecord> {
32        db::challenges::set_challenge_moltbook_discussion(self.pool, challenge_name, discussion_url)
33            .await
34    }
35
36    pub async fn clear_moltbook_discussion(
37        &self,
38        challenge_name: &ChallengeName,
39    ) -> Result<ChallengeMoltbookDiscussionRecord> {
40        db::challenges::clear_challenge_moltbook_discussion(self.pool, challenge_name).await
41    }
42
43    pub async fn publish(
44        &self,
45        input: &PublishChallengeInput<'_>,
46    ) -> Result<PublishChallengeRecord> {
47        db::challenges::publish_challenge(self.pool, input).await
48    }
49
50    pub async fn refresh_seeded(&self, input: &PublishChallengeInput<'_>) -> Result<()> {
51        db::challenges::refresh_seeded_challenge(self.pool, input).await
52    }
53
54    pub async fn archive(&self, challenge_name: &ChallengeName) -> Result<()> {
55        db::challenges::archive_challenge(self.pool, challenge_name).await
56    }
57
58    pub async fn add_owner(
59        &self,
60        challenge_name: &ChallengeName,
61        human_id: &HumanId,
62    ) -> Result<()> {
63        db::challenges::add_challenge_owner(self.pool, challenge_name, human_id).await
64    }
65
66    pub async fn human_owns(
67        &self,
68        challenge_name: &ChallengeName,
69        human_id: &HumanId,
70    ) -> Result<bool> {
71        db::challenges::human_owns_challenge(self.pool, challenge_name, human_id).await
72    }
73
74    pub async fn has_shortlist(&self, challenge_name: &ChallengeName) -> Result<bool> {
75        db::challenges::challenge_has_shortlist(self.pool, challenge_name).await
76    }
77
78    pub async fn agent_is_shortlisted(
79        &self,
80        challenge_name: &ChallengeName,
81        agent_id: &AgentId,
82    ) -> Result<bool> {
83        db::challenges::agent_is_shortlisted(self.pool, challenge_name, agent_id).await
84    }
85
86    pub async fn create_shortlist_revision(
87        &self,
88        input: &CreateChallengeShortlistRevisionInput,
89    ) -> Result<ChallengeShortlistRevisionRecord> {
90        db::challenges::create_challenge_shortlist_revision(self.pool, input).await
91    }
92
93    pub async fn list_shortlist(
94        &self,
95        challenge_name: &ChallengeName,
96    ) -> Result<ChallengeShortlistRecord> {
97        db::challenges::list_challenge_shortlist(self.pool, challenge_name).await
98    }
99
100    pub async fn creator_stats(
101        &self,
102        challenge_name: &ChallengeName,
103        target: Option<&TargetName>,
104    ) -> Result<CreatorChallengeStatsRecord> {
105        db::challenges::get_creator_challenge_stats(self.pool, challenge_name, target).await
106    }
107
108    pub async fn creator_participants(
109        &self,
110        challenge_name: &ChallengeName,
111        target: Option<&TargetName>,
112    ) -> Result<CreatorChallengeParticipantsRecord> {
113        db::challenges::list_creator_challenge_participants(self.pool, challenge_name, target).await
114    }
115
116    pub async fn list_published(
117        &self,
118        limit: i64,
119        offset: i64,
120        filters: &ChallengeCatalogFilters,
121    ) -> Result<PublishedChallengeList> {
122        db::challenges::list_published_challenges(self.pool, limit, offset, filters).await
123    }
124
125    pub async fn get_published(
126        &self,
127        challenge_name: &ChallengeName,
128    ) -> Result<Option<ChallengeRecord>> {
129        db::challenges::get_published_challenge(self.pool, challenge_name).await
130    }
131
132    pub async fn get_published_by_name(
133        &self,
134        challenge_name: &ChallengeName,
135    ) -> Result<Option<ChallengeRecord>> {
136        db::challenges::get_published_challenge_by_name(self.pool, challenge_name).await
137    }
138
139    pub async fn get_public(
140        &self,
141        challenge_name: &ChallengeName,
142    ) -> Result<Option<ChallengeRecord>> {
143        db::challenges::get_public_challenge(self.pool, challenge_name).await
144    }
145
146    pub async fn ensure_supports_eval_type(
147        &self,
148        challenge_name: &ChallengeName,
149        target: &TargetName,
150        eval_type: ScoringMode,
151        agent_id: &AgentId,
152    ) -> Result<PublishedChallengeAdmission> {
153        db::evaluation_policy::ensure_published_challenge_supports_eval_type(
154            self.pool,
155            challenge_name,
156            target,
157            eval_type,
158            agent_id,
159        )
160        .await
161    }
162}