feat(events): Wire resource event fetching into sync pipeline (bd-1ep)
Enqueue resource_events jobs for all issues/MRs after discussion sync, then drain the queue by fetching state/label/milestone events from GitLab API and storing them via transaction-based wrappers. Adds progress events, count tracking through orchestrator->ingest->sync result chain, and respects fetch_resource_events config flag. Includes clippy fixes across codebase from parallel agent work. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -102,7 +102,10 @@ fn knn_search_returns_nearest_neighbors() {
|
||||
let results = lore::search::search_vector(&conn, &query, 10).unwrap();
|
||||
|
||||
assert!(!results.is_empty(), "Should return at least one result");
|
||||
assert_eq!(results[0].document_id, 1, "Nearest neighbor should be doc 1");
|
||||
assert_eq!(
|
||||
results[0].document_id, 1,
|
||||
"Nearest neighbor should be doc 1"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -122,7 +125,12 @@ fn knn_search_respects_limit() {
|
||||
fn knn_search_deduplicates_chunks() {
|
||||
let (_tmp, conn) = create_test_db();
|
||||
|
||||
insert_document(&conn, 1, "Multi-chunk doc", "Very long content that was chunked.");
|
||||
insert_document(
|
||||
&conn,
|
||||
1,
|
||||
"Multi-chunk doc",
|
||||
"Very long content that was chunked.",
|
||||
);
|
||||
|
||||
// Same document, two chunks, both similar to query
|
||||
let mut v1 = vec![0.0f32; 768];
|
||||
@@ -137,7 +145,8 @@ fn knn_search_deduplicates_chunks() {
|
||||
let results = lore::search::search_vector(&conn, &axis_vector(0), 10).unwrap();
|
||||
|
||||
// Should deduplicate: same document_id appears at most once
|
||||
let unique_docs: std::collections::HashSet<i64> = results.iter().map(|r| r.document_id).collect();
|
||||
let unique_docs: std::collections::HashSet<i64> =
|
||||
results.iter().map(|r| r.document_id).collect();
|
||||
assert_eq!(
|
||||
unique_docs.len(),
|
||||
results.len(),
|
||||
@@ -154,22 +163,38 @@ fn orphan_trigger_deletes_embeddings_on_document_delete() {
|
||||
|
||||
// Verify embedding exists
|
||||
let count: i64 = conn
|
||||
.query_row("SELECT COUNT(*) FROM embeddings WHERE rowid = 1000", [], |r| r.get(0))
|
||||
.query_row(
|
||||
"SELECT COUNT(*) FROM embeddings WHERE rowid = 1000",
|
||||
[],
|
||||
|r| r.get(0),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(count, 1, "Embedding should exist before delete");
|
||||
|
||||
// Delete the document
|
||||
conn.execute("DELETE FROM documents WHERE id = 1", []).unwrap();
|
||||
conn.execute("DELETE FROM documents WHERE id = 1", [])
|
||||
.unwrap();
|
||||
|
||||
// Verify embedding was cascade-deleted via trigger
|
||||
let count: i64 = conn
|
||||
.query_row("SELECT COUNT(*) FROM embeddings WHERE rowid = 1000", [], |r| r.get(0))
|
||||
.query_row(
|
||||
"SELECT COUNT(*) FROM embeddings WHERE rowid = 1000",
|
||||
[],
|
||||
|r| r.get(0),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(count, 0, "Trigger should delete embeddings when document is deleted");
|
||||
assert_eq!(
|
||||
count, 0,
|
||||
"Trigger should delete embeddings when document is deleted"
|
||||
);
|
||||
|
||||
// Verify metadata was cascade-deleted via FK
|
||||
let meta_count: i64 = conn
|
||||
.query_row("SELECT COUNT(*) FROM embedding_metadata WHERE document_id = 1", [], |r| r.get(0))
|
||||
.query_row(
|
||||
"SELECT COUNT(*) FROM embedding_metadata WHERE document_id = 1",
|
||||
[],
|
||||
|r| r.get(0),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(meta_count, 0, "Metadata should be cascade-deleted");
|
||||
}
|
||||
@@ -206,7 +231,8 @@ fn overflow_doc_with_error_sentinel_not_re_detected_as_pending() {
|
||||
.unwrap();
|
||||
|
||||
// Now find_pending_documents should NOT return this document
|
||||
let pending = lore::embedding::find_pending_documents(&conn, 100, 0, "nomic-embed-text").unwrap();
|
||||
let pending =
|
||||
lore::embedding::find_pending_documents(&conn, 100, 0, "nomic-embed-text").unwrap();
|
||||
assert!(
|
||||
pending.is_empty(),
|
||||
"Document with overflow error sentinel should not be re-detected as pending, got {} pending",
|
||||
@@ -215,7 +241,10 @@ fn overflow_doc_with_error_sentinel_not_re_detected_as_pending() {
|
||||
|
||||
// count_pending_documents should also return 0
|
||||
let count = lore::embedding::count_pending_documents(&conn, "nomic-embed-text").unwrap();
|
||||
assert_eq!(count, 0, "Count should be 0 for document with overflow sentinel");
|
||||
assert_eq!(
|
||||
count, 0,
|
||||
"Count should be 0 for document with overflow sentinel"
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -226,14 +255,24 @@ fn count_and_find_pending_agree() {
|
||||
|
||||
// Case 1: No documents at all
|
||||
let count = lore::embedding::count_pending_documents(&conn, "nomic-embed-text").unwrap();
|
||||
let found = lore::embedding::find_pending_documents(&conn, 1000, 0, "nomic-embed-text").unwrap();
|
||||
assert_eq!(count as usize, found.len(), "Empty DB: count and find should agree");
|
||||
let found =
|
||||
lore::embedding::find_pending_documents(&conn, 1000, 0, "nomic-embed-text").unwrap();
|
||||
assert_eq!(
|
||||
count as usize,
|
||||
found.len(),
|
||||
"Empty DB: count and find should agree"
|
||||
);
|
||||
|
||||
// Case 2: New document (no metadata)
|
||||
insert_document(&conn, 1, "New doc", "Content");
|
||||
let count = lore::embedding::count_pending_documents(&conn, "nomic-embed-text").unwrap();
|
||||
let found = lore::embedding::find_pending_documents(&conn, 1000, 0, "nomic-embed-text").unwrap();
|
||||
assert_eq!(count as usize, found.len(), "New doc: count and find should agree");
|
||||
let found =
|
||||
lore::embedding::find_pending_documents(&conn, 1000, 0, "nomic-embed-text").unwrap();
|
||||
assert_eq!(
|
||||
count as usize,
|
||||
found.len(),
|
||||
"New doc: count and find should agree"
|
||||
);
|
||||
assert_eq!(count, 1);
|
||||
|
||||
// Case 3: Document with matching metadata (not pending)
|
||||
@@ -247,8 +286,13 @@ fn count_and_find_pending_agree() {
|
||||
)
|
||||
.unwrap();
|
||||
let count = lore::embedding::count_pending_documents(&conn, "nomic-embed-text").unwrap();
|
||||
let found = lore::embedding::find_pending_documents(&conn, 1000, 0, "nomic-embed-text").unwrap();
|
||||
assert_eq!(count as usize, found.len(), "Complete doc: count and find should agree");
|
||||
let found =
|
||||
lore::embedding::find_pending_documents(&conn, 1000, 0, "nomic-embed-text").unwrap();
|
||||
assert_eq!(
|
||||
count as usize,
|
||||
found.len(),
|
||||
"Complete doc: count and find should agree"
|
||||
);
|
||||
assert_eq!(count, 0);
|
||||
|
||||
// Case 4: Config drift (chunk_max_bytes mismatch)
|
||||
@@ -258,8 +302,13 @@ fn count_and_find_pending_agree() {
|
||||
)
|
||||
.unwrap();
|
||||
let count = lore::embedding::count_pending_documents(&conn, "nomic-embed-text").unwrap();
|
||||
let found = lore::embedding::find_pending_documents(&conn, 1000, 0, "nomic-embed-text").unwrap();
|
||||
assert_eq!(count as usize, found.len(), "Config drift: count and find should agree");
|
||||
let found =
|
||||
lore::embedding::find_pending_documents(&conn, 1000, 0, "nomic-embed-text").unwrap();
|
||||
assert_eq!(
|
||||
count as usize,
|
||||
found.len(),
|
||||
"Config drift: count and find should agree"
|
||||
);
|
||||
assert_eq!(count, 1);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user