From 8b8a92bd41fe1779f255363dbe71b149bfc0246e Mon Sep 17 00:00:00 2001 From: Vadym Samoilenko Date: Thu, 30 Apr 2026 17:05:55 +0100 Subject: [PATCH] vault backup: 2026-04-30 17:05:55 --- .../apply-en-changes-to-all-languages.md | 181 ++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 01 Projects/video-accessibility/features/apply-en-changes-to-all-languages.md diff --git a/01 Projects/video-accessibility/features/apply-en-changes-to-all-languages.md b/01 Projects/video-accessibility/features/apply-en-changes-to-all-languages.md new file mode 100644 index 0000000..2a36cd6 --- /dev/null +++ b/01 Projects/video-accessibility/features/apply-en-changes-to-all-languages.md @@ -0,0 +1,181 @@ +--- +title: Apply EN Changes to All Languages +type: feature-plan +project: video-accessibility +status: planned +created: 2026-04-30 +priority: high +--- + +# Feature: Apply EN Changes to All Languages + +## Problem + +When a reviewer edits the English (source) VTT during QC, translated language versions are **not updated**. The translations remain stale — based on the original AI output, not the corrected source. + +## Expected Behaviour + +When source VTT is saved with `retranslate: true`: +1. All target languages are re-translated from the updated source +2. TTS is re-synthesised for changed AD cues +3. Job temporarily returns to `translating` status, then back to `pending_qc` +4. Reviewer sees a progress indicator per language + +--- + +## Implementation Plan + +### Phase 1 — Backend: Retranslation Trigger + +#### 1.1 Extend `VttUpdateRequest` schema +**File:** `backend/app/schemas/job.py` + +Add optional flag: +```python +retranslate_languages: bool = False +``` + +#### 1.2 Detect source VTT change in update endpoint +**File:** `backend/app/api/v1/routes_jobs.py` → `update_job_vtt_content` (~line 1550) + +After saving the VTT, if `request.retranslate_languages is True` and the updated language is the source language: +```python +if request.retranslate_languages and updated_lang == job_doc.get("source_language", "en"): + await _trigger_retranslation(job_id, job_doc, db) +``` + +#### 1.3 Create `_trigger_retranslation` helper +**File:** `backend/app/api/v1/routes_jobs.py` + +```python +async def _trigger_retranslation(job_id: str, job_doc: dict, db) -> None: + target_languages = [ + lang for lang in job_doc.get("target_languages", []) + if lang != job_doc.get("source_language", "en") + ] + if not target_languages: + return + + await db.jobs.update_one( + {"_id": job_id}, + {"$set": { + "status": JobStatus.TRANSLATING.value, + "retranslation_triggered_at": datetime.utcnow(), + "updated_at": datetime.utcnow(), + }} + ) + + from ...tasks.translate_and_synthesize import translate_and_synthesize_task + translate_and_synthesize_task.delay(job_id, languages=target_languages, retranslate=True) +``` + +#### 1.4 Update `translate_and_synthesize_task` +**File:** `backend/app/tasks/translate_and_synthesize.py` + +- Accept optional `languages: list[str] | None` and `retranslate: bool = False` +- When `retranslate=True`: overwrite existing translated VTTs, re-queue TTS for all cues +- On completion: set job status back to `pending_qc` (not `tts_generating`) +- Emit audit log: `AuditAction.RETRANSLATION_TRIGGERED` + +#### 1.5 Add `RETRANSLATION_TRIGGERED` to AuditAction +**File:** `backend/app/models/audit_log.py` + +--- + +### Phase 2 — Frontend: UI + +#### 2.1 Add confirmation dialog in QC VTT editor +**File:** `frontend/src/routes/admin/QCDetail.tsx` + +When reviewer clicks "Save" on source language VTT: +- Check if job has target languages (`job.target_languages.length > 0`) +- Show modal: **"Apply changes to all languages?"** + - "Yes, retranslate all" → save with `retranslate_languages: true` + - "No, source only" → save normally + +#### 2.2 Pass flag through API client +**File:** `frontend/src/lib/api.ts` → `updateJobVtt()` + +```typescript +async updateJobVtt(jobId: string, payload: VttUpdateRequest & { retranslate_languages?: boolean }) +``` + +#### 2.3 Show retranslation progress +**File:** `frontend/src/routes/admin/QCDetail.tsx` + +- When job status flips to `translating`, show per-language progress +- Use existing `useJob` polling (10s interval for `translating` status — already in `useJob.ts`) +- When status returns to `pending_qc`, invalidate VTT cache for all languages: + ```typescript + queryClient.invalidateQueries(['jobs', jobId, 'vtt']) + ``` + +--- + +### Phase 3 — Conflict Resolution (v2, optional) + +When target language has **reviewer edits** (VTT version > 1), retranslation will overwrite them. + +Options: +- **Option A (simple):** Always overwrite — show warning "existing edits will be lost" +- **Option B (safe):** Keep reviewer-edited cues, only retranslate AI-generated ones + - Requires per-cue "is_reviewer_edited" flag in VTT version snapshots + +**Recommendation for v1:** Option A with clear warning in confirmation dialog. + +--- + +## State Machine Changes + +``` +pending_qc + ↓ (source VTT saved with retranslate=true) +translating ← NEW transition + ↓ (all languages done) +pending_qc ← return to same state +``` + +No new statuses needed — reuse existing `translating`. + +--- + +## Data Model Changes + +None required. `translate_and_synthesize_task` already operates on `job_id` and target language list. + +Optional addition to job document: +```python +retranslation_triggered_at: datetime | None = None +retranslation_source_version: int | None = None # VTT version that triggered it +``` + +--- + +## Affected Files Summary + +| File | Change | +|------|--------| +| `backend/app/schemas/job.py` | Add `retranslate_languages: bool = False` to `VttUpdateRequest` | +| `backend/app/api/v1/routes_jobs.py` | Add `_trigger_retranslation` helper, call from `update_job_vtt_content` | +| `backend/app/tasks/translate_and_synthesize.py` | Accept `languages` + `retranslate` params, return to `pending_qc` | +| `backend/app/models/audit_log.py` | Add `RETRANSLATION_TRIGGERED` action | +| `frontend/src/lib/api.ts` | Add `retranslate_languages` to VTT update payload | +| `frontend/src/routes/admin/QCDetail.tsx` | Confirmation dialog + progress handling | + +--- + +## Estimated Effort + +| Phase | Effort | +|-------|--------| +| Phase 1 — Backend | ~3–4h | +| Phase 2 — Frontend | ~2–3h | +| Phase 3 — Conflict resolution | ~4–6h (defer to v2) | + +--- + +## Open Questions + +1. Should AD VTT also retranslate? (currently plan covers captions only) +2. What if retranslation fails for one language — partial failure handling? +3. Should client-facing download links be invalidated immediately on retranslation start?