agentics_persistence/repositories/
challenges.rs1use 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}