feat: streamline QC approval to skip translation pipeline

QC approval now transitions jobs directly to pending_final_review
since translation, TTS, and accessible video rendering happen before
QC review. Removes unnecessary translate_and_synthesize_task trigger
on approval.

- Update approve_source() to use PENDING_FINAL_REVIEW status
- Update bulk_approve_jobs() to use PENDING_FINAL_REVIEW status
- Remove translate_and_synthesize_task.delay() calls from both endpoints
- Update JobDetail progress indicator to reflect new flow
- Update CLAUDE.md state machine documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
michael 2026-01-12 10:37:37 -06:00
parent 48bcea349e
commit dab294f18a
3 changed files with 24 additions and 28 deletions

View file

@ -73,7 +73,9 @@ The development plan is the authoritative source for all implementation details.
## Job Status State Machine
```
created → ingesting → ai_processing → pending_qc → approved_english | rejected → translating → tts_generating → pending_final_review → completed
created → ingesting → ai_processing → translating → tts_generating → rendering_video → pending_qc → pending_final_review → completed
rejected
```
## Key Architecture Decisions
@ -88,10 +90,11 @@ created → ingesting → ai_processing → pending_qc → approved_english | re
### Data Flow
1. Client uploads MP4 → GCS + MongoDB record
2. Celery worker processes video with Gemini 2.5 Pro
3. Generates English captions.vtt and audio_description.vtt
4. Reviewer QC approval triggers translation pipeline
5. Multi-language assets generated (translate/transcreate + TTS)
6. Final review and client notification with download links
3. Generates captions.vtt and audio_description.vtt for source language
4. Translation, TTS synthesis, and accessible video rendering run automatically
5. Job enters QC Review for reviewer approval (edits can trigger re-rendering)
6. QC approval moves job directly to Final Review
7. Final review and client notification with download links
### File Structure
```

View file

@ -267,9 +267,9 @@ async def bulk_approve_jobs(
errors.append(f"Job {job_id}: not in pending QC status")
continue
# Determine the appropriate status based on source language
source_language = job_doc["source"].get("language", "en")
new_status = JobStatus.APPROVED_ENGLISH if source_language == "en" else JobStatus.APPROVED_SOURCE
# Transition directly to PENDING_FINAL_REVIEW
# Translation, TTS, and accessible video rendering now happen BEFORE QC
new_status = JobStatus.PENDING_FINAL_REVIEW
# Build update operations
update_set = {
@ -305,12 +305,8 @@ async def bulk_approve_jobs(
if result:
approved_count += 1
# Trigger translation pipeline
try:
translate_and_synthesize_task.delay(job_id)
logger.info(f"Triggered translation task for bulk-approved job {job_id}")
except Exception as e:
logger.error(f"Failed to trigger translation task for job {job_id}: {e}")
# No need to trigger translate_and_synthesize_task - all processing done before QC
logger.info(f"Job {job_id} approved, transitioning directly to final review")
else:
errors.append(f"Job {job_id}: update failed (may have been modified concurrently)")
@ -591,9 +587,9 @@ async def approve_source(
detail="Job not in pending QC status"
)
# Determine the appropriate status based on source language
source_language = job_doc["source"].get("language", "en")
new_status = JobStatus.APPROVED_ENGLISH if source_language == "en" else JobStatus.APPROVED_SOURCE
# Transition directly to PENDING_FINAL_REVIEW
# Translation, TTS, and accessible video rendering now happen BEFORE QC
new_status = JobStatus.PENDING_FINAL_REVIEW
# Build update operations
update_set = {
@ -635,13 +631,8 @@ async def approve_source(
detail="Job not found or not in pending QC status"
)
# Trigger translation and synthesis pipeline immediately
try:
translate_and_synthesize_task.delay(job_id)
logger.info(f"Triggered translation task for approved job {job_id} (source: {source_language})")
except Exception as e:
logger.error(f"Failed to trigger translation task for job {job_id}: {e}")
# Don't fail the approval, just log the error
# No need to trigger translate_and_synthesize_task - all processing done before QC
logger.info(f"Job {job_id} approved, transitioning directly to final review")
return JobResponse(
id=str(result["_id"]),

View file

@ -9,21 +9,23 @@ import { useToastContext } from '../../contexts/ToastContext';
const ProgressIndicator = ({ status }: { status: string }) => {
// New flow: processing happens before QC, approval goes directly to final review
const steps = [
'created',
'ingesting',
'ai_processing',
'pending_qc',
'approved', // Generic - matches both approved_english and approved_source
'translating',
'tts_generating',
'rendering_video',
'pending_qc',
'pending_final_review',
'completed'
];
// Map approved statuses to generic 'approved' for progress display
const normalizedStatus = (status === 'approved_english' || status === 'approved_source') ? 'approved' : status;
// Handle legacy approved_english/approved_source statuses (map to pending_final_review)
const normalizedStatus = (status === 'approved_english' || status === 'approved_source')
? 'pending_final_review'
: status;
const currentIndex = steps.indexOf(normalizedStatus);
const isRejected = status === 'rejected';
const isFailed = status === 'tts_failed' || status === 'render_failed';