relay-knowledge 1.1.10

Graph-database-based knowledge graph project.
Documentation
use std::sync::Arc;

use crate::{
    api::{ApiError, ApiMetadata, CodeRepositoryIndexResponse, RequestContext},
    domain::{
        CodeIndexMode, CodeIndexProgressSummary, CodeIndexRequest, CodeIndexResourceBudget,
        CodeIndexSummary, CodeRepositoryStatus,
        code_snapshot_expected_scope_id as expected_scope_id,
    },
    storage::KnowledgeStore,
};

use super::support::{
    degraded_file_count_for_fresh_index, fresh_full_index_probe, storage_api_error,
};

pub(super) async fn fresh_full_index_response(
    store: &Arc<dyn KnowledgeStore>,
    status: &CodeRepositoryStatus,
    request: &CodeIndexRequest,
    context: &RequestContext,
) -> Result<Option<CodeRepositoryIndexResponse>, ApiError> {
    if request.mode != CodeIndexMode::Full {
        return Ok(None);
    }
    if request.workspace_detection.enabled {
        return Ok(None);
    }
    let probe = fresh_full_index_probe(status, &request.repository).await?;
    let scoped_status = store
        .code_repository_scope_status(
            request.repository.repository.clone(),
            probe.resolved_commit_sha.clone(),
            probe.path_filters.clone(),
            probe.language_filters.clone(),
        )
        .await
        .map_err(storage_api_error)?;
    let Some(scoped_status) = scoped_status else {
        return Ok(None);
    };
    let expected_source_scope = expected_scope_id(
        &status.repository_id,
        &probe.tree_hash,
        &scoped_status.path_filters,
        &scoped_status.language_filters,
    );
    if scoped_status.stale
        || scoped_status.tree_hash.as_deref() != Some(probe.tree_hash.as_str())
        || expected_source_scope.as_deref().is_some_and(|expected| {
            scoped_status.last_indexed_scope_id.as_deref() != Some(expected)
        })
    {
        return Ok(None);
    }
    let graph_version = store
        .current_graph_version()
        .await
        .map_err(storage_api_error)?;
    let source_scope = scoped_status
        .last_indexed_scope_id
        .clone()
        .unwrap_or_default();
    store
        .clear_code_workspace_state(scoped_status.repository_id.clone(), source_scope.clone())
        .await
        .map_err(storage_api_error)?;
    let software_projection = store
        .refresh_software_global_projection(source_scope.clone())
        .await
        .map_err(storage_api_error)?;
    let degraded_file_count = degraded_file_count_for_fresh_index(store, &scoped_status).await?;
    let generation_counts = store
        .code_repository_scope_symbol_generation_counts(source_scope.clone())
        .await
        .map_err(storage_api_error)?;
    let summary = CodeIndexSummary {
        repository_id: scoped_status.repository_id.clone(),
        source_scope,
        resolved_commit_sha: probe.resolved_commit_sha,
        tree_hash: probe.tree_hash,
        indexed_file_count: scoped_status.indexed_file_count,
        changed_path_count: 0,
        skipped_unchanged_count: scoped_status.indexed_file_count,
        deleted_path_count: 0,
        symbol_count: scoped_status.symbol_count,
        handwritten_symbol_count: generation_counts.handwritten_symbol_count,
        generated_symbol_count: generation_counts.generated_symbol_count,
        reference_count: scoped_status.reference_count,
        chunk_count: scoped_status.chunk_count,
        degraded_file_count,
        progress: CodeIndexProgressSummary {
            git_file_count: scoped_status.indexed_file_count,
            blob_read_count: 0,
            parsed_file_count: 0,
            sqlite_write_count: 0,
            skipped_file_count: scoped_status.indexed_file_count,
            degraded_file_count,
            batch_count: 0,
            checkpoint_file_count: scoped_status.indexed_file_count,
            resource_budget: CodeIndexResourceBudget::default(),
        },
    };

    Ok(Some(CodeRepositoryIndexResponse {
        metadata: ApiMetadata::graph_only(context, graph_version),
        scope: crate::api::CodeRepositoryScopeMetadata::from_status(
            &scoped_status,
            &request.repository,
            request.repository.ref_selector.clone(),
        ),
        summary,
        status: CodeRepositoryStatus {
            degraded_reason: scoped_status
                .degraded_reason
                .or(software_projection.status.last_error),
            ..scoped_status
        },
    }))
}