Commit graph

47 commits

Author SHA1 Message Date
michael
0eda72fd23 feat: add review action buttons to job detail page
Show contextual buttons when jobs are ready for review:
- QC Review button (blue) when status is pending_qc
- Final Review button (purple) when status is pending_final_review

Buttons appear dynamically via WebSocket updates without refresh.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 07:47:27 -06:00
michael
5376b89d8c feat: add column headers to Final Review Queue
Added header rows to clarify that "Original only" refers to
"Languages Requested" in both Pending and Completed sections.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 07:35:38 -06:00
michael
be660bbcff fix: parse dates as UTC for correct local time display
Backend returns UTC dates without timezone indicator. Added
parseUTCDate helper that appends 'Z' to ensure JavaScript
correctly interprets dates as UTC and converts to local time.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 07:32:25 -06:00
michael
0966ce717c refactor: remove Original Filename column from jobs table
Users can see the filename on the job detail page if needed.
Search still works on filename even though it's not displayed.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 07:29:36 -06:00
michael
46b0f2c092 feat: add filtering, sorting, and table view to All Jobs tab
- Add created_by_name field to JobResponse schema and API
- Batch-fetch user names in list_jobs endpoint for efficiency
- Convert JobsList from card layout to sortable data table
- Add search box (job name, filename, created by user)
- Add user filter dropdown (populated from current jobs)
- Add status filter dropdown (individual statuses from current jobs)
- Add date range filter (All Time, Last 7 Days, Last 30 Days)
- Add sortable columns: Job Name, Created By, Date Created, Status
- Fetch all jobs for full client-side filtering capability
- Add responsive horizontal scroll for mobile

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 07:16:21 -06:00
michael
41677d28e0 fix: prevent video reset when toast notifications appear
Stabilized video URLs in VideoReviewPlayer to prevent the video from
resetting when WebSocket updates trigger React Query refetches. The
fix stores the initial video URL for each tab and reuses it instead
of using the refreshed signed URL, preventing unnecessary remounts.

Changes:
- Added stableVideoUrls state to cache video URLs per tab
- Removed key prop from video element to prevent forced remounts
- Event listeners now attached once on mount, not on URL change

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 06:54:52 -06:00
michael
396e4e74e0 feat: add rendering_video status for accessible video processing
When jobs with accessible video option enabled enter video rendering
phase, the status now transitions to 'rendering_video' so users can
see why processing is taking longer. This provides better visibility
into the video rendering pipeline.

Changes:
- Added RENDERING_VIDEO status to JobStatus enum
- Updated render_accessible_video task to set new status
- Added status display to StatusBadge, jobStatusMessages
- Included new status in JobsList Translation filter group

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 06:49:46 -06:00
michael
ab063c6a28 fix: ensure jobs list fetches fresh data on mount
Added staleTime: 0 and refetchOnMount: 'always' to useJobs hook to
ensure the jobs list always fetches fresh data when navigating to
the All Jobs tab after creating a new job.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-27 06:39:30 -06:00
michael
eaabf9cef6 fix: show 'Original only' instead of 'N/A' for jobs without translations
Clarifies the UI when a job has no additional translation languages
requested, making it clearer that the job contains only the original
language assets.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 16:59:55 -06:00
michael
394cf478f5 fix: show 'Original' badge for primary language in Final Review
When a video's source language is non-English (e.g., German), the
language asset was incorrectly marked as 'Translated'. Now correctly
shows 'Original' with a green badge for the primary/source language.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 16:46:07 -06:00
michael
fd68d1ef54 feat: add accessible video validation, remove AI confidence check
- Add validation for accessible_video_gcs (file exists, size 0.1MB-5GB)
- Add validation for retimed_captions_vtt_gcs when accessible video exists
- Add AD Videos count to asset validation panel
- Include retimed captions in VTT file count
- Remove AI confidence from validation panel and backend checks

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 16:41:57 -06:00
michael
3cdea9dfec fix: video review caption sync and event listener issues
- Fix video event listeners not re-attaching when video element remounts
  (add activeTab?.videoUrl to useEffect dependency array)
- Add retimed_captions_vtt to VTT API response for accessible videos
- Use retimed captions for accessible video tab in VideoReviewPlayer

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 16:23:48 -06:00
michael
6effe58dc9 feat: add video review with timestamped notes to Final Review
Add a comprehensive video review feature to the Final Review page that allows
reviewers to watch videos with caption overlays and add timestamped notes.

Backend:
- New ReviewNote model for MongoDB with job_id, asset_key, timestamp, content
- CRUD API endpoints at /jobs/{job_id}/review-notes
- Owner-only edit/delete permissions (admins can bypass)
- Database indexes for efficient querying

Frontend:
- VideoReviewPlayer component with video player and caption overlay
- NotesSidebar for viewing/adding notes with auto-highlight when video reaches timestamp
- SyncedCaptionList with auto-scroll and click-to-seek
- AssetTabs for switching between languages and accessible videos
- React Query hooks with 30s polling for collaborative updates

Features:
- Notes persist to database and are shared across all reviewers
- Notes highlight for 5 seconds when video playback reaches their timestamp
- Click note to seek video to that position
- Pause video to add note at current timestamp
- Accessible videos use retimed captions when available

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 15:30:00 -06:00
michael
80d3866d32 feat: add accessible video (MP4 with embedded audio descriptions)
Add new deliverable type that renders video with audio descriptions embedded.
Supports two AI-determined methods:
- Direct Overlay: ducks original audio and overlays AD TTS (for minimal dialogue)
- Pause-Insert: freeze-frame video, insert AD, re-time subtitles (for significant dialogue)

Backend:
- Add Pydantic schemas for Gemini analysis response
- Add Gemini prompt and analyze_accessible_video_placement() method
- Add video_renderer.py service using FFmpeg for both rendering methods
- Add vtt_retimer.py service for pause-insert subtitle adjustment
- Add render_accessible_video.py Celery task
- Modify TTS service to return individual per-cue segments
- Update translate_and_synthesize.py to save segments and trigger rendering
- Update download endpoint to include accessible video outputs

Frontend:
- Add accessible_video_mp4 checkbox to NewJob form
- Update TypeScript types for new deliverable

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-26 11:06:41 -06:00
michael
d1e51ebade feat: add bulk approve/reject actions to Final Review screen
- Add checkbox selection for pending final review jobs
- Add bulk actions toolbar with Complete/Return to QC options
- Mirror QC Review bulk action pattern with parallel API calls
- Rejection notes required, completion notes optional

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 20:27:40 -06:00
michael
6537a0899a fix: make title optional in schema to allow multi-upload form submission
The zod schema required title to be non-empty, but in multi-upload mode
the title field is hidden (titles are auto-generated from filenames).
This caused form validation to fail silently when clicking upload.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 20:13:45 -06:00
michael
40acc3ff84 fix: correct TypeScript type for retry upload promise
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 20:05:35 -06:00
michael
465eca8bab feat: add multi-video upload support
- Add multi-file drag-and-drop to upload multiple videos at once
- Each video creates its own job using filename as title
- Single file upload preserves current UX with editable pre-filled title
- Multi-upload mode shows file list, individual progress bars, and summary
- Parallel uploads (max 3 concurrent) with error handling and retry
- Settings (language, outputs, TTS) apply to all jobs in batch

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 20:01:48 -06:00
michael
44ef3ff741 feat: add bulk download action for approved/completed jobs
Add "Download All Files" option to the bulk actions menu on the All Jobs page.
When selected, downloads all assets (source video, VTTs, MP3s for all languages)
from jobs in approved_english, approved_source, or completed status.

- Shows confirmation modal with eligible/ineligible job counts
- Downloads files sequentially with progress indicator
- Skips jobs not in approved/completed status with warning

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 19:36:25 -06:00
michael
804553e2a3 fix: TTS preview now uses job's detected source language
- QCDetail passes sourceLanguage to VoiceSelector instead of hardcoded 'en'
- VoiceSelector uses first language in selectedLanguages for default voice preview
- Removes hardcoded English assumption in displayLanguages logic

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 15:32:28 -06:00
michael
865fcdc246 feat: add TTS settings panel with model, speed, and style options
- Add model selection (flash vs pro) for quality control
- Add speed slider (0.5x - 2.0x) for pacing adjustment
- Add style presets (neutral, calm, energetic, professional, warm, documentary)
- Add custom style prompt option for advanced customization
- New /tts/options endpoint returns available TTS options
- Voice preview now tests all settings so users hear exact output
- Backward compatible: all new fields have sensible defaults

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 15:22:14 -06:00
michael
a999b23a17 fix: clear cached audio when voice selection changes
The preview button was caching audio but not invalidating the cache
when the user selected a different voice, causing the same audio to
play regardless of which voice was selected.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 14:58:31 -06:00
michael
29643f6683 upgrade TTS to Gemini TTS with voice selection and preview
- Add Gemini TTS service with 30 voices and 24 languages
- Add TTS API endpoints for voice listing and preview
- Add per-language voice selection in job creation form
- Add voice override at QC approval stage
- Add VoiceSelector and VoicePreviewButton components
- Update TTSPreferences model with provider and voice mapping

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 14:41:57 -06:00
michael
1ff3290081 fix hardcoded English labels to use detected source language
- Add sourceLanguage prop to VideoWithCaptions component
- Create shared getLanguageLabel utility for language code mapping
- Update QCDetail and JobDetail to pass source language
- Fix status messages to say "source content" instead of "English content"
- Update Downloads page to display proper language names

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 12:04:31 -06:00
michael
91a2894911 fix radio button state not updating in new job form
The setValueAs transformation wasn't working correctly with radio
buttons in react-hook-form, causing the form value to remain a string
instead of being converted to a boolean. This caused Zod validation
to fail silently since the schema expects a boolean.

Fixed by using controlled radio buttons with explicit onChange handlers
that call setValue() with the proper boolean value.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 11:09:50 -06:00
michael
58a4f1f627 add support for non-English original video uploads
- Upload form now has "English / Different language" radio with optional language hint
- Gemini auto-detects language and saves outputs to outputs.{detected_language}
- QC review dynamically loads/saves VTT for source language
- New APPROVED_SOURCE status for non-English videos (APPROVED_ENGLISH kept for backwards compat)
- Translation pipeline reads from source language and passes source_language to Google Translate
- All existing English jobs continue to work unchanged

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-22 10:33:58 -06:00
michael
282f95dbc3 removed timeout from upload request and improved error reporting 2025-10-17 11:24:04 -05:00
michael
df09f30d63 fixed auto update of filtered queries for jobs list 2025-10-16 11:59:17 -05:00
michael
762d7bcb38 fixed websockets live messaging for updates 2025-10-16 11:46:37 -05:00
michael
700f55a96d fixed production users ability to delete and reprocess jobs 2025-10-10 12:39:00 -05:00
michael
bc0a2ca43c fixed base URL for websockets connection 2025-10-10 12:22:26 -05:00
michael
eb402e0c68 adjusted login page to emphasize microsoft login, hide local login options behind small link 2025-10-10 11:50:52 -05:00
michael
f59f5cf93b fixed front end build errors 2025-10-10 10:26:57 -05:00
michael
aefd559e68 added production user role and made it default for new MSAL users - production can access everything EXCEPT user management - that's only for admin 2025-10-10 10:07:30 -05:00
michael
665b49c3f1 added MSAL microsoft authentication 2025-10-10 09:19:39 -05:00
michael
0910ade371 more fixes for refresh token - this time maintaining the username and role properly across refresh 2025-10-08 23:09:29 -05:00
michael
7e45a0c016 another fix for refresh token issue - this time front end only 2025-10-08 23:03:09 -05:00
michael
67ceca2777 fixed auth token refresh again and added --frontend-only mode to full deploy script 2025-10-08 22:43:23 -05:00
michael
990f6f6fa1 fixed session refresh and added full deploy script - and added documentation including videos 2025-10-08 22:29:08 -05:00
michael
5d949df531 fixed websocket URL 2025-10-08 17:28:15 -05:00
michael
1dae163cad base path for react router fix 2025-10-08 16:55:02 -05:00
michael
aafc4078ae bug fixes for frontend when trying to npm run build 2025-10-08 16:47:14 -05:00
michael
dac0fbea04 hid transcreation option and mentions in the UI as the feature is not fully implemented 2025-08-25 16:02:29 -05:00
michael
de61d0bd39 removed mongodb change stream monitoring, added global websockets monitoring for notifications, broke symmetry between toasts and persistent notifications (and refined which notifications get sent and how) 2025-08-25 15:48:18 -05:00
michael
86c8454625 added notification menu system with persistent and dismissable notifications from toats, updated Readme 2025-08-25 07:55:30 -05:00
michael
0c54dd4f29 added websockets for live job status updates with toast notifications on job list page 2025-08-24 19:41:23 -05:00
michael
af2562096a initial commit 2025-08-24 16:28:33 -05:00