fix(translate): prevent empty translations in _persist_pre + add diag logging

Bug 1 (secondary): _persist_pre() created TranslationLanguage with
empty final_value for non-source target languages when same_language
flag was set but no cache/approved value existed. This produced
is_original=0 rows with empty text in target table.

Fix: skip TranslationLanguage creation when fv is empty (continue
in the loop instead of falling through to else with empty string).

Bug 2 (diagnostic): No visibility into _classify() routing decisions.
Add logger.reason with pre/llm/total counts per batch.

Scenario trace: ru source + targets [ru,en] + no cache → llm_rows ✓
If same-language partial match hits cache for all targets → pre_rows ✓
If same-language partial match misses cache → llm_rows ✓
If same-language all-match (targets=[ru]) → short-circuit pre_rows ✓

Tests: 69/69 translate tests pass.
This commit is contained in:
2026-06-02 11:44:41 +03:00
parent 0b74946bd2
commit 1dec48079c

View File

@@ -160,6 +160,9 @@ class BatchProcessingService:
pre_rows.append(row)
continue
llm_rows.append(row)
logger.reason("Batch classified",
{"tls": tls, "pre": len(pre_rows), "llm": len(llm_rows),
"total": len(pre_rows) + len(llm_rows)})
return llm_rows, pre_rows
def _persist_pre(self, pre_rows, bid, run_id, tls):
@@ -190,7 +193,8 @@ class BatchProcessingService:
elif cl and lc in cl:
fv = cl[lc]
else:
fv = row.get("approved_translation", "")
# No translation available — skip this language
continue
self.db.add(TranslationLanguage(
id=str(uuid.uuid4()), record_id=rec.id, language_code=lc,
source_language_detected=detected_lang, translated_value=fv,