feat(surgical-sync): add per-IID surgical sync pipeline
Implement lore sync --issue <IID> --mr <IID> -p <project> for on-demand
sync of specific entities without running the full project-wide pipeline.
Completes in seconds by fetching only targeted entities, their discussions,
resource events, and dependent data, then scoping doc regeneration and
embedding to only affected documents.
Pipeline stages: PREFLIGHT -> TOCTOU -> INGEST -> DEPENDENTS -> DOCS -> EMBED
New files:
- src/ingestion/surgical.rs: TOCTOU guard, preflight fetch, per-entity ingest
- src/ingestion/surgical_tests.rs: 17 unit/wiremock tests
- src/cli/commands/sync_surgical.rs: 719-line orchestrator
- src/embedding/pipeline_tests.rs: scoped embedding tests
- src/gitlab/client_tests.rs: get_by_iid wiremock tests
- migrations/027_surgical_sync_runs.sql: 12 surgical columns + indexes
Key changes:
- SyncOptions: issue_iids, mr_iids, project, preflight_only fields
- SyncResult: surgical_mode, surgical_iids, entity_results fields
- SyncRunRecorder: surgical lifecycle methods (set_surgical_metadata, etc)
- GitLabClient: get_issue_by_iid, get_mr_by_iid
- Scoped docs: regenerate_dirty_documents_for_sources
- Scoped embed: embed_documents_by_ids
- run_sync dispatches to run_sync_surgical when is_surgical()
- robot-docs updated with surgical sync schema + workflows
- All 1019 tests pass, clippy clean
Closes: bd-1sc6, bd-tiux, bd-159p, bd-1lja, bd-hs6j, bd-1elx, bd-arka,
bd-3sez, bd-wcja, bd-kanh, bd-1i4i, bd-3bec
This commit is contained in:
@@ -112,6 +112,18 @@ impl GitLabClient {
|
||||
self.request("/api/v4/version").await
|
||||
}
|
||||
|
||||
pub async fn get_issue_by_iid(&self, project_id: i64, iid: i64) -> Result<GitLabIssue> {
|
||||
self.request(&format!("/api/v4/projects/{project_id}/issues/{iid}"))
|
||||
.await
|
||||
}
|
||||
|
||||
pub async fn get_mr_by_iid(&self, project_id: i64, iid: i64) -> Result<GitLabMergeRequest> {
|
||||
self.request(&format!(
|
||||
"/api/v4/projects/{project_id}/merge_requests/{iid}"
|
||||
))
|
||||
.await
|
||||
}
|
||||
|
||||
const MAX_RETRIES: u32 = 3;
|
||||
|
||||
async fn request<T: serde::de::DeserializeOwned>(&self, path: &str) -> Result<T> {
|
||||
@@ -763,6 +775,10 @@ fn ms_to_iso8601(ms: i64) -> Option<String> {
|
||||
.map(|dt| dt.format("%Y-%m-%dT%H:%M:%S%.3fZ").to_string())
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
#[path = "client_tests.rs"]
|
||||
mod client_tests;
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
Reference in New Issue
Block a user