feat: OCR independent chunks (方案 A) + stats API

Rule 1 now creates OCR chunks separately from ASRX segments:
- Phase 1: ASRX segments (pure speech, NO OCR merge)
- Phase 2: OCR-only chunks (all OCR frames grouped by proximity)

Added OCR statistics to ingestion status API:
- rule1_ocr: shows OCR pre_chunks count
- rule1_ocr_chunks: shows OCR-only chunks count

Example: FilmRiot_test now has 32 ASRX + 3 OCR-only = 35 chunks
Stats: rule1_sentence: 35, rule1_ocr: 30, rule1_ocr_chunks: 3
This commit is contained in:
Accusys
2026-07-05 23:28:09 +08:00
parent 5a3f791ecd
commit e91d51cc5e
2 changed files with 64 additions and 57 deletions
+21
View File
@@ -508,6 +508,17 @@ async fn get_ingestion_status(
"SELECT COUNT(*) FROM {chunk} WHERE file_uuid = '{file_uuid}' AND chunk_type = 'sentence'"
));
let sentence_embedded = count_sql!(&format!("SELECT COUNT(*) FROM {chunk} WHERE file_uuid = '{file_uuid}' AND chunk_type = 'sentence' AND embedding IS NOT NULL"));
// OCR statistics
let pre_chunks_table = schema::table_name("pre_chunks");
let ocr_pre_chunks: i64 = count_sql!(&format!(
"SELECT COUNT(*) FROM {pre_chunks_table} WHERE file_uuid = '{file_uuid}' AND processor_type = 'ocr'"
));
let ocr_only_chunks: i64 = count_sql!(&format!(
"SELECT COUNT(*) FROM {chunk} WHERE file_uuid = '{file_uuid}' AND chunk_type = 'sentence' \
AND (content->>'text' = '' OR content->>'text' IS NULL) \
AND content->>'ocr_text' IS NOT NULL AND content->>'ocr_text' != ''"
));
let scene_count = count_sql!(&format!(
"SELECT COUNT(*) FROM {chunk} WHERE file_uuid = '{file_uuid}' AND chunk_type = 'cut'"
));
@@ -595,6 +606,16 @@ async fn get_ingestion_status(
sentence_count > 0,
Some(format!("{sentence_count} sentence chunks"))
),
step!(
"rule1_ocr",
ocr_pre_chunks > 0,
Some(format!("{ocr_pre_chunks} OCR frames"))
),
step!(
"rule1_ocr_chunks",
ocr_only_chunks > 0,
Some(format!("{ocr_only_chunks} OCR-only chunks"))
),
step!(
"auto_vectorize",
sentence_embedded > 0,