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