# Subtitle Jobs Async Design ## Goal Replace the synchronous `/api/generate-subtitles` request with an async job flow so long-running subtitle generation can survive gateway timeouts and provide user-visible progress. ## Chosen Approach Use a single-process in-memory job store on the backend and 5-second polling on the frontend. The backend will: - accept subtitle generation requests - create a job with `queued` status - return `202 Accepted` immediately with `jobId` - continue subtitle generation in the background - expose `GET /api/generate-subtitles/:jobId` for status and result lookup The frontend will: - submit the job - poll every 5 seconds - map backend `stage` values to a staged progress bar - stop polling on `succeeded`, `failed`, or timeout ## Job Model Each subtitle job stores: - `id` - `requestId` - `status` - `stage` - `progress` - `message` - `createdAt` - `updatedAt` - `provider` - `targetLanguage` - `fileId` - `filePath` - `error` - `result` Statuses: - `queued` - `running` - `succeeded` - `failed` Stages: - `queued` - `upload_received` - `preparing` - `calling_provider` - `processing_result` - `succeeded` - `failed` Jobs expire from memory after 1 hour. ## Progress Strategy Progress is stage-based, not byte-accurate. This avoids fake precision while still keeping the user informed. Suggested mapping: - `queued`: 5 - `upload_received`: 15 - `preparing`: 30 - `calling_provider`: 70 - `processing_result`: 90 - `succeeded`: 100 - `failed`: keep last reported progress ## Backend Flow 1. Parse request and validate source input. 2. Create a job. 3. Return `202` with the new job state. 4. Run subtitle generation in a detached async task. 5. Update the job on each pipeline stage. 6. Store final result or error. 7. Clean up uploaded temp files after background completion. ## Frontend Flow 1. Doubao still uploads to Ark Files first and waits for file readiness. 2. Frontend posts to `/api/generate-subtitles`. 3. Frontend polls `/api/generate-subtitles/:jobId` every 5 seconds. 4. Progress UI updates from backend job status and stage. 5. Final result is normalized into `SubtitlePipelineResult`. ## Risks - In-memory jobs are lost on restart. - Single-instance memory state will not scale across multiple backend replicas. - Upload time can still be slow, but the long model invocation is no longer tied to one HTTP response.