Backend (Phase A):
- A1: Adaptive silence buffer — natural_gap_ms persisted per cue; renderer computes
per-cue silence_before/silence_after instead of fixed 500ms; per-cue silence files
- A2: Forward-preferred snap — snap_pause_point prefers boundaries up to 4s ahead
over boundaries within 1.5s behind, reducing mid-scene cuts
- A3: Min-gap validation — pause points with < 200ms gap trigger forward search
to the next acceptable gap
- natural_gap_ms added to PausePointData model and api.ts type
- New config fields: whisper_snap_forward_window, whisper_snap_backward_window,
ad_silence_buffer_default, ad_silence_buffer_min_after, ad_min_acceptable_gap
- Tests: test_whisper_snap.py (13 tests), test_video_renderer_buffers.py
Frontend (Phase B):
- B1: Drag pause-point markers — pointer state machine with 3px move threshold,
clamp to min/max bounds, click-without-move still opens PausePointEditor
- B2: Drag freeze blocks — orange blocks translate with linked pause point
- B3: Time tooltip visible during drag, hidden on release
- Tests: TimelinePreview.drag.test.tsx (10 tests)
Fixes:
- Share link pointed to ai-sandbox.oliver.solutions — added app_url to Settings
with correct optical-dev.oliver.solutions default; share_url now configurable
via APP_URL env var
- Removed all ai-sandbox.oliver.solutions references from docker-compose,
apache config, docs, and scripts
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
On optical-dev the Apache vhost is a standalone file in sites-enabled (not
a symlink to sites-available), so injecting the Include into sites-available
had no effect and the ProxyPassMatch rules were never loaded by Apache.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
deploy.sh and full-deploy.sh predate the optical-dev setup and reference
old URLs/compose files. deploy-dev.sh is the single source of truth.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
deploy-dev.sh:
- BUILD_SERVICES now includes tts-worker, ffmpeg-worker, whisper-worker (enabled
in docker-compose.optical-dev.yml via USE_CELERY_FALLBACK=true)
- ensure_apache_modules(): enables proxy, proxy_http, proxy_wstunnel, rewrite
- Apache fragment: WS proxy (ws://) placed BEFORE HTTP /api/ proxy (required
for correct longest-match precedence in Apache)
- Added ProxyTimeout 600 (10 min) and LimitRequestBody 2147483648 (2 GB) for
large video uploads; disablereuse=on for WS pool correctness
- Fragment always regenerated on deploy (picks up PORT/WEBROOT changes)
- Logs command uses full $COMPOSE variable instead of hardcoded partial flags
deploy/apache-video-accessibility.conf:
- Static reference copy of the Apache fragment with inline comments explaining
each directive
.env.production:
- Updated remaining ai-sandbox.oliver.solutions URLs to optical-dev.oliver.solutions
(API_BASE_URL, COOKIE_DOMAIN, CLIENT_BASE_URL, AZURE_REDIRECT_URI, CORS_ORIGINS)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Port 8003 is occupied by infra-api-1 on optical-dev server.
Artifact Registry repo renamed from nexus to video-accessibility.
cloudbuild.yaml defaults _TAG to 'latest' for manual runs.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Heavy pipeline tasks (ingest, translate, render, rerender) now dispatch
to a Cloud Run Job (va-worker) instead of local Celery workers. optical-dev
runs only api + lightweight worker (notify/embed) within its 2-CPU budget.
- backend/app/tasks/runner.py — Cloud Run Job entrypoint
- backend/app/services/cloud_run_dispatch.py — replaces .delay() for heavy tasks
- backend/Dockerfile.cloudrun — Cloud Run worker image (ffmpeg included)
- docker-compose.optical-dev.yml — 2-CPU safe overrides, disables heavy workers
- cloudbuild.yaml — builds va-worker image and updates Cloud Run Job
- deploy-dev.sh — uses 3-file compose, builds only api+worker locally
- routes_jobs, routes_admin_production, ingest_and_ai, translate_and_synthesize
— all dispatch sites updated to use cloud_run_dispatch.dispatch()
USE_CELERY_FALLBACK=true in .env.local to use Celery locally during dev.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sequential image builds (one at a time to avoid OOM), auto Apache
fragment, migrations, frontend rsync, smoke test. Flags:
--skip-build / --skip-frontend / --skip-migrations
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New migration updates MongoDB users collection validator to accept
project_manager role and pm_client_ids field
- full-deploy.sh was missing the run_migrations step entirely; added it
after rebuild_containers so new role/field validators apply on every deploy
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Was checking backend/.git and frontend/.git (submodule pattern) which
never exists — git pull silently skipped, deploying stale code.
Now pulls root repo first, falls back to submodule pattern.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
For replacing a single cue's voice (e.g., French Canadian → France French female)
without re-running the full pipeline.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The rendering_video status was defined in job.py and frontend types but
was missing from the MongoDB schema validator, causing document update
failures when jobs transitioned to the rendering_video state.
Changes:
- Add migration script to update existing databases
- Update mongodb-init.js for new database setups
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
For databases set up before migration tracking existed, this script
marks old migrations as "applied" in migration_history collection
so only new migrations will run.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add migration to update jobs collection validator with new statuses
- Update mongodb-init.js for fresh deployments
- Fix deploy.sh to properly run migrations with 'python migrate.py up'
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The npm ci --only=production flag was skipping dev dependencies,
but TypeScript is needed to compile the frontend build.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>