|
| 1 | +# Glocal Ads AI Architecture |
| 2 | + |
| 3 | +## Overview |
| 4 | + |
| 5 | +The repository is a mono-repo containing a Next.js 14 frontend, a FastAPI backend, and a suite of Python worker services connected through RabbitMQ and Redis. Media assets are stored in MinIO (S3 compatible). Postgres stores relational data and Redis offers pub/sub for real-time status updates. |
| 6 | + |
| 7 | +``` |
| 8 | +frontend (Next.js) |
| 9 | + ↕ REST/SSE |
| 10 | +FastAPI BFF |
| 11 | + ↕ SQLAlchemy/Redis/RabbitMQ/S3 |
| 12 | +RabbitMQ (jobs exchange) <—> Orchestrator <—> Worker micro-services |
| 13 | +Redis (pub/sub) <—> Frontend SSE progress |
| 14 | +Postgres <—> FastAPI + workers |
| 15 | +MinIO (S3 bucket) ⇄ Media ingestion & artifacts |
| 16 | +``` |
| 17 | + |
| 18 | +## Applications |
| 19 | + |
| 20 | +### Frontend (`apps/frontend`) |
| 21 | +* Next.js 14 App Router with TypeScript. |
| 22 | +* Authentication via FastAPI (`/auth/sign-in`). Token stored in local storage. |
| 23 | +* Pages: |
| 24 | + * `/` — project list + creation. |
| 25 | + * `/projects/[id]` — asset upload to MinIO, localization job form. |
| 26 | + * `/jobs/[id]` — SSE-driven pipeline progress per language/stage. |
| 27 | + * `/results/[jobId]` — variant previews (HLS) with download & YouTube actions. |
| 28 | +* Uses `react-hook-form`, shadcn-inspired UI primitives, `hls.js` for preview. |
| 29 | + |
| 30 | +### API (`apps/api`) |
| 31 | +* FastAPI + SQLAlchemy 2.0 + async Postgres (psycopg3). |
| 32 | +* Provides auth, project & asset management, job orchestration endpoints, SSE progress stream, variant downloads, and YouTube stub. |
| 33 | +* Integrations: Redis pub/sub, RabbitMQ (via `aio-pika`), MinIO (boto3), JWT auth, Alembic-like SQL migrations (raw SQL in `migrations/sql`). |
| 34 | +* On startup ensures S3 bucket policy via MinIO client and seeds admin/demo data. |
| 35 | + |
| 36 | +## Services (`services/*`) |
| 37 | +* Shared utilities packaged in `packages/service-kit` (config, DB helpers, S3, RabbitMQ, Redis progress helper, path helpers). |
| 38 | +* Each worker listens to a dedicated routing key (`stage.<name>`) and publishes completion/error events back (`stage.<name>.completed|failed`). |
| 39 | +* Orchestrator sequences stages per language, updates DB, emits Redis progress, and optionally triggers YouTube uploads. |
| 40 | +* Workers emulate the media pipeline: |
| 41 | + * `asr-agent`: generates dummy segments & transcript. |
| 42 | + * `translate-agent`: applies pseudo translation with suffix `[lang]`. |
| 43 | + * `tts-agent`: synthesises sine-wave speech from segments. |
| 44 | + * `mix-agent`: runs FFmpeg to mux original video + TTS, produces MP4 + HLS. |
| 45 | + * `subs-agent`: builds SRT/VTT from translated segments. |
| 46 | + * `textinframe-agent`: overlays localized text via FFmpeg drawtext + new HLS. |
| 47 | + * `qc-agent`: probes final output and writes JSON QC report. |
| 48 | + * `yt-uploader`: logs pseudo YouTube URL and notifies Redis. |
| 49 | + |
| 50 | +## Messaging Flow |
| 51 | + |
| 52 | +1. API `/jobs` inserts job + variants and publishes `job.created` message. |
| 53 | +2. Orchestrator consumes `job.created`, sets variants to `processing`, queues first stage (`stage.asr`). |
| 54 | +3. Each worker retrieves job/variant context from Postgres via service kit, reads/writes artifacts in MinIO, updates DB fields, and publishes progress using Redis + `stage.<stage>.completed` message. |
| 55 | +4. Orchestrator hears completion events, queues next stage (skipping optional ones based on job options), and finally marks variant/job done. |
| 56 | +5. Frontend subscribes via `/jobs/{id}/stream` SSE channel and renders per-stage updates. |
| 57 | + |
| 58 | +## Storage Layout |
| 59 | + |
| 60 | +MinIO bucket `glocal-media` stores assets: |
| 61 | +* `raw/{projectId}/{assetId}/source.mp4` |
| 62 | +* `jobs/{jobId}/{lang}/asr/segments.json` |
| 63 | +* `jobs/{jobId}/{lang}/tts/track.wav` |
| 64 | +* `jobs/{jobId}/{lang}/mix/out.mp4` |
| 65 | +* `jobs/{jobId}/{lang}/mix/hls/...` |
| 66 | +* `jobs/{jobId}/{lang}/subs/subtitles.(srt|vtt)` |
| 67 | +* `jobs/{jobId}/{lang}/textinframe/out.mp4` |
| 68 | +* `jobs/{jobId}/{lang}/qc/report.json` |
| 69 | + |
| 70 | +Postgres tables follow schema defined in `migrations/sql/001_init.sql` (users, projects, assets, jobs, variants, voice profiles, glossaries). |
| 71 | + |
| 72 | +## Infrastructure |
| 73 | + |
| 74 | +* Dockerfiles live in `infrastructure/docker` for API, frontend, and generic Python services. |
| 75 | +* `docker-compose.yml` orchestrates Postgres, Redis, RabbitMQ, MinIO (+ mc bootstrap), API, frontend, orchestrator, all agents, and migration job. |
| 76 | +* Basic Kubernetes manifests provided under `infrastructure/k8s/` as a starting point. |
| 77 | + |
| 78 | +## Scripts & Automation |
| 79 | + |
| 80 | +* `scripts/dev/generate-test-video.sh` — produces an 8s synthetic demo video. |
| 81 | +* `scripts/dev/smoke.sh` — end-to-end happy-path using FastAPI endpoints. |
| 82 | +* GitHub Actions workflow (`ci.yml`) runs Ruff/Black/Mypy and Next.js lint. |
| 83 | + |
| 84 | +## Notes |
| 85 | + |
| 86 | +* SSE endpoints and variant preview/download accept either `Authorization` header or `?token=` query string for EventSource/video tags. |
| 87 | +* Bucket policy is configured for anonymous read to support direct HLS loads. |
| 88 | +* The architecture is modular to later swap emulators with real ML models (WhisperX, NLLB/LLM, XTTS, etc.) without changing orchestration plumbing. |
0 commit comments