Skip to main content

agentics_persistence/repositories/
challenge_review_records.rs

1use 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}