fix(translate): CR1-CR2 migration + H1-H4 code review bugs
CR1: Add needs_review, language_overridden to translation_languages migration CR2: Add per_language_metrics to translation_metric_snapshots migration H1: BulkFindReplaceService.preview() now uses replacement_text (not find pattern) H2: get_run_records now includes per-language data via selectinload H3: Preview per-language approve/reject uses correct (jobId, rowId, lang) args H4: _compute_config_hash now includes target_languages
This commit is contained in:
@@ -507,6 +507,7 @@ async def bulk_find_replace(
|
||||
run_id=run_id,
|
||||
pattern=payload.find_pattern,
|
||||
is_regex=payload.is_regex,
|
||||
replacement_text=payload.replacement_text,
|
||||
target_language=payload.target_language,
|
||||
)
|
||||
return {
|
||||
|
||||
@@ -548,9 +548,10 @@ class TestTranslationOrchestrator:
|
||||
record.status = "SUCCESS"
|
||||
record.error_message = None
|
||||
record.created_at = datetime.now(UTC)
|
||||
record.languages = []
|
||||
|
||||
db.query.return_value.filter.return_value.count.return_value = 1
|
||||
db.query.return_value.filter.return_value.order_by.return_value.offset.return_value.limit.return_value.all.return_value = [record]
|
||||
db.query.return_value.options.return_value.filter.return_value.count.return_value = 1
|
||||
db.query.return_value.options.return_value.filter.return_value.order_by.return_value.offset.return_value.limit.return_value.all.return_value = [record]
|
||||
|
||||
orch = TranslationOrchestrator(db, config_manager, "test-user")
|
||||
result = orch.get_run_records("run-1")
|
||||
|
||||
@@ -23,7 +23,7 @@ from collections.abc import Callable
|
||||
from datetime import UTC, datetime
|
||||
from typing import Any
|
||||
|
||||
from sqlalchemy.orm import Session
|
||||
from sqlalchemy.orm import Session, selectinload
|
||||
|
||||
from ...core.config_manager import ConfigManager
|
||||
from ...core.logger import belief_scope, logger
|
||||
@@ -827,8 +827,10 @@ class TranslationOrchestrator:
|
||||
status_filter: str | None = None,
|
||||
) -> dict[str, Any]:
|
||||
with belief_scope("TranslationOrchestrator.get_run_records"):
|
||||
query = self.db.query(TranslationRecord).filter(
|
||||
TranslationRecord.run_id == run_id
|
||||
query = (
|
||||
self.db.query(TranslationRecord)
|
||||
.options(selectinload(TranslationRecord.languages))
|
||||
.filter(TranslationRecord.run_id == run_id)
|
||||
)
|
||||
|
||||
if status_filter:
|
||||
@@ -856,6 +858,17 @@ class TranslationOrchestrator:
|
||||
"status": r.status,
|
||||
"error_message": r.error_message,
|
||||
"created_at": r.created_at.isoformat() if r.created_at else None,
|
||||
"languages": [
|
||||
{
|
||||
"language_code": tl.language_code,
|
||||
"translated_value": tl.translated_value,
|
||||
"final_value": tl.final_value or tl.translated_value,
|
||||
"source_language_detected": tl.source_language_detected,
|
||||
"status": tl.status,
|
||||
"needs_review": tl.needs_review or False,
|
||||
}
|
||||
for tl in (r.languages or [])
|
||||
],
|
||||
}
|
||||
for r in records
|
||||
],
|
||||
@@ -995,6 +1008,7 @@ class TranslationOrchestrator:
|
||||
"translation_column": job.translation_column,
|
||||
"context_columns": job.context_columns,
|
||||
"target_language": job.target_language,
|
||||
"target_languages": sorted(job.target_languages) if job.target_languages else [],
|
||||
"provider_id": job.provider_id,
|
||||
"batch_size": job.batch_size,
|
||||
"upsert_strategy": job.upsert_strategy,
|
||||
|
||||
@@ -865,6 +865,7 @@ class BulkFindReplaceService:
|
||||
run_id: str,
|
||||
pattern: str,
|
||||
is_regex: bool,
|
||||
replacement_text: str,
|
||||
target_language: str,
|
||||
) -> list[dict]:
|
||||
"""Scan TranslationLanguage entries and return matching items without applying changes."""
|
||||
@@ -888,7 +889,7 @@ class BulkFindReplaceService:
|
||||
source_term = record.source_sql if record else ""
|
||||
|
||||
new_value = compiled.sub(
|
||||
BulkFindReplaceService._get_replacement(pattern, is_regex),
|
||||
replacement_text,
|
||||
current_value,
|
||||
)
|
||||
if new_value != current_value:
|
||||
@@ -904,10 +905,9 @@ class BulkFindReplaceService:
|
||||
return preview_items
|
||||
|
||||
@staticmethod
|
||||
def _get_replacement(pattern: str, is_regex: bool) -> str:
|
||||
def _get_replacement(replacement_text: str, is_regex: bool) -> str:
|
||||
"""Return replacement pattern (for regex, use backrefs; for plain, use literal)."""
|
||||
# The replacement_text is passed through at apply time
|
||||
return pattern # Placeholder — actual replacement is done in apply()
|
||||
return replacement_text
|
||||
|
||||
@staticmethod
|
||||
def apply(
|
||||
|
||||
Reference in New Issue
Block a user