use super::*;
pub(crate) async fn handle_record_import(
store: &Store,
ctx: &RequestContext,
request_id: Uuid,
input: &protocol::RecordImportInput,
) -> HandlerResult {
const CHUNK: usize = 200;
let mut imported: u64 = 0;
let mut skipped: u64 = 0;
let mut chunk_buf: Vec<&Record> = Vec::with_capacity(CHUNK);
let valid_prefixes = [
"gotcha:",
"decision:",
"dev_note:",
"file:",
"stage:",
"dep:",
"policy:",
];
let mut accepted_refs: Vec<&Record> = Vec::with_capacity(input.records.len());
for r in &input.records {
let key_str = r.key.as_str();
if !valid_prefixes.iter().any(|p| key_str.starts_with(p)) {
skipped += 1;
continue;
}
if crate::store::Durability::for_key(key_str) != crate::store::Durability::Immediate {
skipped += 1;
continue;
}
accepted_refs.push(r);
}
for chunk in accepted_refs.chunks(CHUNK) {
chunk_buf.clear();
chunk_buf.extend(chunk.iter().copied());
let chunk_target = format!("record_import:{}records", chunk_buf.len());
let audit = make_audit(ctx, request_id, "record_import", &chunk_target, true, None)
.ok_or_else(|| (ErrorCode::Internal, "audit serialization failed".into()))?;
let mut ops: Vec<KnowledgeWriteOp<'_>> = Vec::with_capacity(chunk_buf.len() + 1);
for r in &chunk_buf {
ops.push(KnowledgeWriteOp::PutRecord {
key: r.key.as_str(),
record: r,
});
}
ops.push(KnowledgeWriteOp::PutRaw {
key: &audit.0,
value: &audit.1,
});
store.transact_knowledge(&ops).await.map_err(|e| {
(
ErrorCode::StoreError,
format!("import transact failed: {e}"),
)
})?;
imported += chunk_buf.len() as u64;
}
Ok(serde_json::json!({
"ok": true,
"imported": imported,
"skipped": skipped,
}))
}