vault backup: 2026-04-30 17:05:55

This commit is contained in:
Vadym Samoilenko 2026-04-30 17:05:55 +01:00
parent e6571a42a5
commit 8b8a92bd41

View file

@ -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 | ~34h |
| Phase 2 — Frontend | ~23h |
| Phase 3 — Conflict resolution | ~46h (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?