1use crate::domain::{
4 CodeFeatureFlagGraph, CodeFeatureFlagRequest, CodeFileFingerprint, CodeImpactRequest,
5 CodeIndexBatch, CodeIndexCheckpoint, CodeIndexSession, CodeIndexSnapshot, CodeIndexSummary,
6 CodeIndexTaskRecord, CodeRepositoryCrossEdge, CodeRepositoryRegistration, CodeRepositoryReport,
7 CodeRepositorySet, CodeRepositorySetMember, CodeRepositorySetRefreshSummary,
8 CodeRepositorySetRefreshTaskRecord, CodeRepositorySetStatus, CodeRepositoryStatus,
9 CodeRepositoryTotals, CodeRetrievalHit, CodeRetrievalRequest, CodeScopeRetentionSummary,
10};
11
12use super::{StorageError, StorageFuture};
13
14pub const CODE_INDEX_TASK_LEASE_RECOVERY_UNAVAILABLE: &str =
16 "code index task lease recovery is unavailable";
17
18pub const CODE_INDEX_TASK_LEASE_RENEWAL_UNAVAILABLE: &str =
20 "code index task lease renewal is unavailable";
21
22#[derive(Debug, Clone, Default, PartialEq, Eq)]
24pub struct CodeImpactChanges {
25 pub paths: Vec<String>,
26 pub deleted_symbol_names: Vec<String>,
27}
28
29#[derive(Debug, Clone, PartialEq, Eq)]
31pub struct CodeIndexTaskSeed {
32 pub repository_id: String,
33 pub alias: String,
34 pub ref_selector: String,
35 pub resolved_commit_sha: String,
36 pub tree_hash: String,
37 pub source_scope: String,
38 pub path_filters: Vec<String>,
39 pub language_filters: Vec<String>,
40 pub mode: crate::domain::CodeIndexMode,
41 pub input_fingerprint: String,
42 pub resource_budget: crate::domain::CodeIndexResourceBudget,
43 pub payload_json: String,
44 pub now_ms: u64,
45}
46
47#[derive(Debug, Clone, PartialEq, Eq)]
49pub struct CodeIndexTaskClaimRequest {
50 pub task_id: Option<String>,
51 pub lease_owner: String,
52 pub lease_duration_ms: u64,
53 pub max_attempts: u32,
54 pub now_ms: u64,
55}
56
57#[derive(Debug, Clone, PartialEq, Eq)]
59pub struct CodeIndexTaskLeaseRenewal {
60 pub task_id: String,
61 pub lease_owner: String,
62 pub attempt_count: u32,
63 pub lease_duration_ms: u64,
64 pub now_ms: u64,
65}
66
67#[derive(Debug, Clone, PartialEq, Eq)]
69pub struct CodeIndexTaskCompletion {
70 pub task_id: String,
71 pub lease_owner: String,
72 pub attempt_count: u32,
73 pub now_ms: u64,
74}
75
76#[derive(Debug, Clone, PartialEq, Eq)]
78pub struct CodeIndexTaskFailure {
79 pub task_id: String,
80 pub lease_owner: String,
81 pub attempt_count: u32,
82 pub error_kind: String,
83 pub error_message: String,
84 pub retry_backoff_ms: u64,
85 pub max_attempts: u32,
86 pub now_ms: u64,
87}
88
89#[derive(Debug, Clone, PartialEq, Eq)]
91pub struct CodeScopeRetentionRequest {
92 pub repository_id: String,
93 pub active_scope: String,
94 pub retain_recent_successful_scopes: usize,
95}
96
97#[derive(Debug, Clone, PartialEq, Eq)]
99pub struct CodeRepositorySetSeed {
100 pub alias: String,
101 pub description: Option<String>,
102 pub default_ref_policy_json: String,
103 pub now_ms: u64,
104}
105
106#[derive(Debug, Clone, PartialEq, Eq)]
108pub struct CodeRepositorySetMemberSeed {
109 pub set_alias: String,
110 pub repository_id: String,
111 pub repository_alias: String,
112 pub ref_selector: String,
113 pub resolved_commit_sha: String,
114 pub source_scope: String,
115 pub path_filters: Vec<String>,
116 pub language_filters: Vec<String>,
117 pub priority: i32,
118}
119
120#[derive(Debug, Clone, PartialEq, Eq)]
122pub struct CodeRepositorySetRefreshTaskSeed {
123 pub set_id: String,
124 pub set_alias: String,
125 pub input_fingerprint: String,
126 pub now_ms: u64,
127}
128
129#[derive(Debug, Clone, PartialEq, Eq)]
131pub struct CodeRepositorySetRefreshTaskClaimRequest {
132 pub task_id: Option<String>,
133 pub lease_owner: String,
134 pub lease_duration_ms: u64,
135 pub max_attempts: u32,
136 pub now_ms: u64,
137}
138
139#[derive(Debug, Clone, PartialEq, Eq)]
141pub struct CodeRepositorySetRefreshTaskCompletion {
142 pub task_id: String,
143 pub lease_owner: String,
144 pub attempt_count: u32,
145 pub now_ms: u64,
146}
147
148#[derive(Debug, Clone, PartialEq, Eq)]
150pub struct CodeRepositorySetRefreshTaskFailure {
151 pub task_id: String,
152 pub lease_owner: String,
153 pub attempt_count: u32,
154 pub error_kind: String,
155 pub error_message: String,
156 pub retry_backoff_ms: u64,
157 pub max_attempts: u32,
158 pub now_ms: u64,
159}
160
161pub trait CodeRepositoryStore: Send + Sync {
163 fn upsert_code_repository(
164 &self,
165 registration: CodeRepositoryRegistration,
166 ) -> StorageFuture<'_, CodeRepositoryStatus>;
167
168 fn code_repository_status(
169 &self,
170 repository: String,
171 ) -> StorageFuture<'_, Option<CodeRepositoryStatus>>;
172
173 fn code_repository_scope_status(
174 &self,
175 repository: String,
176 resolved_commit_sha: String,
177 path_filters: Vec<String>,
178 language_filters: Vec<String>,
179 ) -> StorageFuture<'_, Option<CodeRepositoryStatus>>;
180
181 fn latest_code_repository_scope_status(
182 &self,
183 _repository: String,
184 _path_filters: Vec<String>,
185 _language_filters: Vec<String>,
186 ) -> StorageFuture<'_, Option<CodeRepositoryStatus>> {
187 Box::pin(async { Ok(None) })
188 }
189
190 fn queue_code_index_task(
191 &self,
192 task: CodeIndexTaskSeed,
193 ) -> StorageFuture<'_, CodeIndexTaskRecord>;
194
195 fn claim_code_index_task(
196 &self,
197 request: CodeIndexTaskClaimRequest,
198 ) -> StorageFuture<'_, Option<CodeIndexTaskRecord>>;
199
200 fn recover_code_index_task_leases(
201 &self,
202 _now_ms: u64,
203 _max_attempts: u32,
204 ) -> StorageFuture<'_, ()> {
205 Box::pin(async {
206 Err(StorageError::InvalidInput(
207 CODE_INDEX_TASK_LEASE_RECOVERY_UNAVAILABLE.to_owned(),
208 ))
209 })
210 }
211
212 fn renew_code_index_task_lease(
213 &self,
214 _request: CodeIndexTaskLeaseRenewal,
215 ) -> StorageFuture<'_, CodeIndexTaskRecord> {
216 Box::pin(async {
217 Err(StorageError::InvalidInput(
218 CODE_INDEX_TASK_LEASE_RENEWAL_UNAVAILABLE.to_owned(),
219 ))
220 })
221 }
222
223 fn complete_code_index_task(
224 &self,
225 request: CodeIndexTaskCompletion,
226 ) -> StorageFuture<'_, CodeIndexTaskRecord>;
227
228 fn fail_code_index_task(
229 &self,
230 request: CodeIndexTaskFailure,
231 ) -> StorageFuture<'_, CodeIndexTaskRecord>;
232
233 fn code_index_task(&self, task_id: String) -> StorageFuture<'_, Option<CodeIndexTaskRecord>>;
234
235 fn active_code_index_task(
236 &self,
237 repository_id: String,
238 ) -> StorageFuture<'_, Option<CodeIndexTaskRecord>>;
239
240 fn code_index_checkpoint(
241 &self,
242 source_scope: String,
243 ) -> StorageFuture<'_, Option<CodeIndexCheckpoint>>;
244
245 fn code_scope_retention(
246 &self,
247 repository_id: String,
248 ) -> StorageFuture<'_, CodeScopeRetentionSummary>;
249
250 fn prune_code_repository_scopes(
251 &self,
252 request: CodeScopeRetentionRequest,
253 ) -> StorageFuture<'_, CodeScopeRetentionSummary>;
254
255 fn code_file_fingerprints(
256 &self,
257 repository_id: String,
258 ) -> StorageFuture<'_, Vec<CodeFileFingerprint>>;
259
260 fn code_file_fingerprints_for_scope(
261 &self,
262 source_scope: String,
263 ) -> StorageFuture<'_, Vec<CodeFileFingerprint>> {
264 Box::pin(async move {
265 Err(StorageError::InvalidInput(format!(
266 "code file fingerprints for scope '{source_scope}' are unavailable"
267 )))
268 })
269 }
270
271 fn code_file_candidate_paths_for_scope(
272 &self,
273 source_scope: String,
274 _path_filters: Vec<String>,
275 _language_filters: Vec<String>,
276 _limit: usize,
277 ) -> StorageFuture<'_, Vec<String>> {
278 Box::pin(async move {
279 Err(StorageError::InvalidInput(format!(
280 "bounded code file candidate paths for scope '{source_scope}' are unavailable"
281 )))
282 })
283 }
284
285 fn code_file_candidate_paths_for_query_scope(
286 &self,
287 source_scope: String,
288 _query: String,
289 path_filters: Vec<String>,
290 language_filters: Vec<String>,
291 limit: usize,
292 ) -> StorageFuture<'_, Vec<String>> {
293 self.code_file_candidate_paths_for_scope(
294 source_scope,
295 path_filters,
296 language_filters,
297 limit,
298 )
299 }
300
301 fn apply_code_index_snapshot(
302 &self,
303 snapshot: CodeIndexSnapshot,
304 ) -> StorageFuture<'_, CodeIndexSummary>;
305
306 fn begin_code_index_session(
307 &self,
308 session: CodeIndexSession,
309 ) -> StorageFuture<'_, CodeIndexCheckpoint> {
310 Box::pin(async move {
311 Err(StorageError::InvalidInput(format!(
312 "checkpointed code index sessions for scope '{}' are unavailable",
313 session.source_scope
314 )))
315 })
316 }
317
318 fn apply_code_index_batch(
319 &self,
320 batch: CodeIndexBatch,
321 ) -> StorageFuture<'_, CodeIndexCheckpoint> {
322 Box::pin(async move {
323 Err(StorageError::InvalidInput(format!(
324 "checkpointed code index batches for scope '{}' are unavailable",
325 batch.source_scope
326 )))
327 })
328 }
329
330 fn finalize_code_index_session(
331 &self,
332 session: CodeIndexSession,
333 ) -> StorageFuture<'_, CodeIndexSummary> {
334 Box::pin(async move {
335 Err(StorageError::InvalidInput(format!(
336 "checkpointed code index finalization for scope '{}' is unavailable",
337 session.source_scope
338 )))
339 })
340 }
341
342 fn search_code(
343 &self,
344 request: CodeRetrievalRequest,
345 ) -> StorageFuture<'_, Vec<CodeRetrievalHit>>;
346
347 fn search_code_feature_flags(
348 &self,
349 request: CodeFeatureFlagRequest,
350 ) -> StorageFuture<'_, Vec<CodeFeatureFlagGraph>> {
351 Box::pin(async move {
352 Err(StorageError::InvalidInput(format!(
353 "code feature flag search for repository '{}' is unavailable",
354 request.repository.repository
355 )))
356 })
357 }
358
359 fn search_code_feature_flags_scope(
360 &self,
361 source_scope: String,
362 _request: CodeFeatureFlagRequest,
363 ) -> StorageFuture<'_, Vec<CodeFeatureFlagGraph>> {
364 Box::pin(async move {
365 Err(StorageError::InvalidInput(format!(
366 "code feature flag search for source scope '{source_scope}' is unavailable"
367 )))
368 })
369 }
370
371 fn search_code_scope(
372 &self,
373 source_scope: String,
374 _request: CodeRetrievalRequest,
375 ) -> StorageFuture<'_, Vec<CodeRetrievalHit>> {
376 Box::pin(async move {
377 Err(StorageError::InvalidInput(format!(
378 "code search for source scope '{source_scope}' is unavailable"
379 )))
380 })
381 }
382
383 fn analyze_code_impact(
384 &self,
385 request: CodeImpactRequest,
386 changes: CodeImpactChanges,
387 ) -> StorageFuture<'_, Vec<CodeRetrievalHit>>;
388
389 fn code_repository_totals(&self) -> StorageFuture<'_, CodeRepositoryTotals> {
390 Box::pin(async { Ok(CodeRepositoryTotals::default()) })
391 }
392
393 fn code_repository_report(
394 &self,
395 repository: String,
396 ) -> StorageFuture<'_, CodeRepositoryReport> {
397 Box::pin(async move {
398 Err(StorageError::InvalidInput(format!(
399 "code repository report for '{repository}' is unavailable"
400 )))
401 })
402 }
403
404 fn create_code_repository_set(
405 &self,
406 _seed: CodeRepositorySetSeed,
407 ) -> StorageFuture<'_, CodeRepositorySet> {
408 Box::pin(async {
409 Err(StorageError::InvalidInput(
410 "repository set storage is unavailable".to_owned(),
411 ))
412 })
413 }
414
415 fn add_code_repository_set_member(
416 &self,
417 _seed: CodeRepositorySetMemberSeed,
418 ) -> StorageFuture<'_, CodeRepositorySetMember> {
419 Box::pin(async {
420 Err(StorageError::InvalidInput(
421 "repository set member storage is unavailable".to_owned(),
422 ))
423 })
424 }
425
426 fn remove_code_repository_set_member(
427 &self,
428 _set_alias: String,
429 _repository_alias: String,
430 ) -> StorageFuture<'_, CodeRepositorySetMember> {
431 Box::pin(async {
432 Err(StorageError::InvalidInput(
433 "repository set member storage is unavailable".to_owned(),
434 ))
435 })
436 }
437
438 fn code_repository_set(
439 &self,
440 _set_alias: String,
441 ) -> StorageFuture<'_, Option<CodeRepositorySet>> {
442 Box::pin(async { Ok(None) })
443 }
444
445 fn code_repository_set_status(
446 &self,
447 _set_alias: String,
448 ) -> StorageFuture<'_, Option<CodeRepositorySetStatus>> {
449 Box::pin(async { Ok(None) })
450 }
451
452 fn refresh_code_repository_set_overlay(
453 &self,
454 _set_alias: String,
455 _now_ms: u64,
456 ) -> StorageFuture<'_, CodeRepositorySetRefreshSummary> {
457 Box::pin(async {
458 Err(StorageError::InvalidInput(
459 "repository set overlay refresh is unavailable".to_owned(),
460 ))
461 })
462 }
463
464 fn code_repository_set_cross_edges(
465 &self,
466 _set_id: String,
467 ) -> StorageFuture<'_, Vec<CodeRepositoryCrossEdge>> {
468 Box::pin(async { Ok(Vec::new()) })
469 }
470
471 fn queue_code_repository_set_refresh_task(
472 &self,
473 _task: CodeRepositorySetRefreshTaskSeed,
474 ) -> StorageFuture<'_, CodeRepositorySetRefreshTaskRecord> {
475 Box::pin(async {
476 Err(StorageError::InvalidInput(
477 "repository set refresh task storage is unavailable".to_owned(),
478 ))
479 })
480 }
481
482 fn claim_code_repository_set_refresh_task(
483 &self,
484 _request: CodeRepositorySetRefreshTaskClaimRequest,
485 ) -> StorageFuture<'_, Option<CodeRepositorySetRefreshTaskRecord>> {
486 Box::pin(async { Ok(None) })
487 }
488
489 fn complete_code_repository_set_refresh_task(
490 &self,
491 _request: CodeRepositorySetRefreshTaskCompletion,
492 ) -> StorageFuture<'_, CodeRepositorySetRefreshTaskRecord> {
493 Box::pin(async {
494 Err(StorageError::InvalidInput(
495 "repository set refresh task storage is unavailable".to_owned(),
496 ))
497 })
498 }
499
500 fn fail_code_repository_set_refresh_task(
501 &self,
502 _request: CodeRepositorySetRefreshTaskFailure,
503 ) -> StorageFuture<'_, CodeRepositorySetRefreshTaskRecord> {
504 Box::pin(async {
505 Err(StorageError::InvalidInput(
506 "repository set refresh task storage is unavailable".to_owned(),
507 ))
508 })
509 }
510}