feat: auto-match metadata when 100% confidence and matching book count
When multiple provider results exist but the best has 100% confidence, compare local book count with external total_volumes. If they match, treat it as an auto-match and link+sync series and book metadata automatically instead of requiring manual review. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -632,7 +632,7 @@ enum SearchOutcome {
|
|||||||
|
|
||||||
async fn search_and_evaluate(
|
async fn search_and_evaluate(
|
||||||
pool: &PgPool,
|
pool: &PgPool,
|
||||||
_library_id: Uuid,
|
library_id: Uuid,
|
||||||
series_name: &str,
|
series_name: &str,
|
||||||
provider_name: &str,
|
provider_name: &str,
|
||||||
) -> SearchOutcome {
|
) -> SearchOutcome {
|
||||||
@@ -660,7 +660,31 @@ async fn search_and_evaluate(
|
|||||||
// Check if best candidate has perfect confidence
|
// Check if best candidate has perfect confidence
|
||||||
let best = candidates.into_iter().next().unwrap();
|
let best = candidates.into_iter().next().unwrap();
|
||||||
if (best.confidence - 1.0).abs() < f32::EPSILON {
|
if (best.confidence - 1.0).abs() < f32::EPSILON {
|
||||||
// Multiple results but best is 100% — still too many results
|
// Multiple results but best is 100% — check if book count matches to auto-match
|
||||||
|
if let Some(ext_total) = best.total_volumes {
|
||||||
|
let local_count: Option<i64> = sqlx::query_scalar(
|
||||||
|
r#"
|
||||||
|
SELECT COUNT(*) FROM books
|
||||||
|
WHERE library_id = $1
|
||||||
|
AND COALESCE(NULLIF(series, ''), 'unclassified') = $2
|
||||||
|
"#,
|
||||||
|
)
|
||||||
|
.bind(library_id)
|
||||||
|
.bind(series_name)
|
||||||
|
.fetch_one(pool)
|
||||||
|
.await
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
if let Some(count) = local_count {
|
||||||
|
if count == ext_total as i64 {
|
||||||
|
info!(
|
||||||
|
"[METADATA_BATCH] Auto-match by book count: series='{}' confidence=100% local_books={} external_volumes={}",
|
||||||
|
series_name, count, ext_total
|
||||||
|
);
|
||||||
|
return SearchOutcome::AutoMatch(best);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return SearchOutcome::TooManyResults(1, Some(best)); // count the 100% one
|
return SearchOutcome::TooManyResults(1, Some(best)); // count the 100% one
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user