agentics_persistence/repositories/
challenge_review_records.rs1use sqlx::PgPool;
2
3use crate::db;
4use crate::repositories::{
5 AdminChallengePrivateAssetRecord, BeginChallengeReviewRecordValidationInput,
6 ChallengePrivateAssetPurgeRecord, ChallengePrivateAssetRecord, ChallengeReviewRecordRecord,
7 ChallengeReviewValidationRecord, ClaimedChallengeReviewRecordForPublish,
8 CreateChallengePrivateAssetInput, CreateChallengeReviewRecordAuditEventInput,
9 CreateChallengeReviewRecordInput, FinishChallengeReviewRecordValidationInput,
10 PublishArchiveChallengeReviewRecordInput, PublishNewChallengeReviewRecordInput,
11};
12use agentics_domain::models::ids::{
13 ChallengePrivateAssetId, ChallengeReviewPublishClaimId, ChallengeReviewRecordId, HumanId,
14};
15use agentics_domain::storage::StorageKey;
16use agentics_error::Result;
17
18#[derive(Debug, Clone, Copy)]
19pub struct ChallengeReviewRecordsRepository<'a> {
20 pub(super) pool: &'a PgPool,
21}
22
23impl ChallengeReviewRecordsRepository<'_> {
24 pub async fn create(
25 &self,
26 input: &CreateChallengeReviewRecordInput,
27 audit_event: &CreateChallengeReviewRecordAuditEventInput,
28 ) -> Result<ChallengeReviewRecordRecord> {
29 db::challenge_creation::create_challenge_review_record(self.pool, input, audit_event).await
30 }
31
32 pub async fn get(
33 &self,
34 review_record_id: &ChallengeReviewRecordId,
35 ) -> Result<Option<ChallengeReviewRecordRecord>> {
36 db::challenge_creation::get_challenge_review_record(self.pool, review_record_id).await
37 }
38
39 pub async fn list(&self, limit: i64) -> Result<Vec<ChallengeReviewRecordRecord>> {
40 db::challenge_creation::list_challenge_review_records(self.pool, limit).await
41 }
42
43 pub async fn list_private_asset_states(
44 &self,
45 review_record_id: &ChallengeReviewRecordId,
46 ) -> Result<Vec<AdminChallengePrivateAssetRecord>> {
47 db::challenge_creation::list_challenge_private_asset_states(self.pool, review_record_id)
48 .await
49 }
50
51 pub async fn reserve_private_asset(
52 &self,
53 input: &CreateChallengePrivateAssetInput,
54 max_bytes_per_review_record: u64,
55 validation_timeout_minutes: i32,
56 pending_timeout_minutes: i32,
57 ) -> Result<ChallengePrivateAssetRecord> {
58 db::challenge_creation::reserve_challenge_private_asset(
59 self.pool,
60 input,
61 max_bytes_per_review_record,
62 validation_timeout_minutes,
63 pending_timeout_minutes,
64 )
65 .await
66 }
67
68 pub async fn activate_private_asset_with_audit(
69 &self,
70 asset_row_id: &agentics_domain::models::ids::ChallengePrivateAssetId,
71 audit_event_id: agentics_domain::models::ids::ChallengeReviewAuditEventId,
72 uploader_human_id: &HumanId,
73 ) -> Result<ChallengePrivateAssetRecord> {
74 db::challenge_creation::activate_challenge_private_asset_with_audit(
75 self.pool,
76 asset_row_id,
77 audit_event_id,
78 uploader_human_id,
79 )
80 .await
81 }
82
83 pub async fn activate_private_asset(
84 &self,
85 asset_row_id: &agentics_domain::models::ids::ChallengePrivateAssetId,
86 ) -> Result<ChallengePrivateAssetRecord> {
87 db::challenge_creation::activate_challenge_private_asset(self.pool, asset_row_id).await
88 }
89
90 pub async fn fail_private_asset(
91 &self,
92 asset_row_id: &agentics_domain::models::ids::ChallengePrivateAssetId,
93 message: &str,
94 ) -> Result<()> {
95 db::challenge_creation::fail_challenge_private_asset(self.pool, asset_row_id, message).await
96 }
97
98 pub async fn private_asset_storage_key_has_active_reference(
99 &self,
100 storage_key: &StorageKey,
101 ) -> Result<bool> {
102 db::challenge_creation::private_asset_storage_key_has_active_reference(
103 self.pool,
104 storage_key,
105 )
106 .await
107 }
108
109 pub async fn begin_validation(
110 &self,
111 input: &BeginChallengeReviewRecordValidationInput,
112 window_seconds: i64,
113 validation_limit: i64,
114 validation_timeout_minutes: i32,
115 ) -> Result<ChallengeReviewValidationRecord> {
116 db::challenge_creation::begin_challenge_review_record_validation(
117 self.pool,
118 input,
119 window_seconds,
120 validation_limit,
121 validation_timeout_minutes,
122 )
123 .await
124 }
125
126 pub async fn finish_validation(
127 &self,
128 input: &FinishChallengeReviewRecordValidationInput,
129 audit_event: &CreateChallengeReviewRecordAuditEventInput,
130 ) -> Result<ChallengeReviewValidationRecord> {
131 db::challenge_creation::finish_challenge_review_record_validation(
132 self.pool,
133 input,
134 audit_event,
135 )
136 .await
137 }
138
139 pub async fn abandon_with_audit(
140 &self,
141 review_record_id: &ChallengeReviewRecordId,
142 message: Option<&str>,
143 audit_event: &CreateChallengeReviewRecordAuditEventInput,
144 ) -> Result<()> {
145 db::challenge_creation::abandon_challenge_review_record_with_audit(
146 self.pool,
147 review_record_id,
148 message,
149 audit_event,
150 )
151 .await
152 }
153
154 pub async fn abandon_stale(&self, ttl_days: i64) -> Result<i64> {
155 db::challenge_creation::abandon_stale_challenge_review_records(self.pool, ttl_days).await
156 }
157
158 pub async fn list_unpublished_private_assets_for_purge(
159 &self,
160 grace_days: i64,
161 ) -> Result<Vec<ChallengePrivateAssetPurgeRecord>> {
162 db::challenge_creation::list_unpublished_private_assets_for_purge(self.pool, grace_days)
163 .await
164 }
165
166 pub async fn delete_private_asset(&self, asset_row_id: &ChallengePrivateAssetId) -> Result<()> {
167 db::challenge_creation::delete_challenge_private_asset(self.pool, asset_row_id).await
168 }
169
170 pub async fn mark_private_asset_purging(
171 &self,
172 asset_row_id: &agentics_domain::models::ids::ChallengePrivateAssetId,
173 ) -> Result<Option<ChallengePrivateAssetPurgeRecord>> {
174 db::challenge_creation::mark_challenge_private_asset_purging(self.pool, asset_row_id).await
175 }
176
177 pub async fn approve_validated_with_audit(
178 &self,
179 review_record_id: &ChallengeReviewRecordId,
180 expected_validation_bundle_sha256: &agentics_domain::models::hashes::Sha256Digest,
181 message: Option<&str>,
182 audit_event: &CreateChallengeReviewRecordAuditEventInput,
183 ) -> Result<()> {
184 db::challenge_creation::approve_validated_challenge_review_record_with_audit(
185 self.pool,
186 review_record_id,
187 expected_validation_bundle_sha256,
188 message,
189 audit_event,
190 )
191 .await
192 }
193
194 pub async fn update_status_with_audit(
195 &self,
196 review_record_id: &ChallengeReviewRecordId,
197 status: agentics_domain::models::challenge_creation::ChallengeReviewRecordStatus,
198 message: Option<&str>,
199 audit_event: &CreateChallengeReviewRecordAuditEventInput,
200 ) -> Result<()> {
201 db::challenge_creation::update_challenge_review_record_status_with_audit(
202 self.pool,
203 review_record_id,
204 status,
205 message,
206 audit_event,
207 )
208 .await
209 }
210
211 pub async fn claim_for_publish(
212 &self,
213 review_record_id: &ChallengeReviewRecordId,
214 publish_timeout_minutes: i32,
215 ) -> Result<ClaimedChallengeReviewRecordForPublish> {
216 db::challenge_creation::claim_challenge_review_record_for_publish(
217 self.pool,
218 review_record_id,
219 publish_timeout_minutes,
220 )
221 .await
222 }
223
224 pub async fn fail_publish(
225 &self,
226 review_record_id: &ChallengeReviewRecordId,
227 publish_claim_id: &ChallengeReviewPublishClaimId,
228 message: &str,
229 ) -> Result<()> {
230 db::challenge_creation::fail_challenge_review_record_publish(
231 self.pool,
232 review_record_id,
233 publish_claim_id,
234 message,
235 )
236 .await
237 }
238
239 pub async fn publish_archive(
240 &self,
241 input: &PublishArchiveChallengeReviewRecordInput,
242 ) -> Result<()> {
243 db::challenge_creation::publish_archive_challenge_review_record(self.pool, input).await
244 }
245
246 pub async fn publish_new(&self, input: &PublishNewChallengeReviewRecordInput) -> Result<()> {
247 db::challenge_creation::publish_new_challenge_review_record(self.pool, input).await
248 }
249
250 pub async fn mark_published(
251 &self,
252 review_record_id: &ChallengeReviewRecordId,
253 publish_claim_id: &ChallengeReviewPublishClaimId,
254 published_challenge_name: Option<&agentics_domain::models::names::ChallengeName>,
255 ) -> Result<()> {
256 db::challenge_creation::mark_challenge_review_record_published(
257 self.pool,
258 review_record_id,
259 publish_claim_id,
260 published_challenge_name,
261 )
262 .await
263 }
264}