Blueprint Backend & AI API
Backend API-first, cloud-native, event-driven, dan queue-based: 16 service modular, 20 tabel inti dengan soft delete, 21 endpoint REST v1, dan adapter AI yang dapat ditukar tanpa menyentuh logika aplikasi.
- Service
- 16
- Tabel inti
- 20
- Endpoint v1
- 21
- Antrean
- 7
Peta service
Stateless, horizontal scaling, REST untuk publik & gRPC antar-service
Authentication Service
RESTJWT, refresh token, OAuth Google, email login, RBAC.
Project Service
RESTCRUD proyek, metadata, lifecycle, soft delete.
AI Workflow Service
gRPCOrkestrasi antrean, dependensi tahap, retry, resume.
Story Service
gRPCAnalisis naskah, optimasi, storyboard.
Character Service
gRPCCharacter Bible & Environment Library.
Image Service
gRPCPrompt gambar, render, konsistensi karakter.
Video Service
gRPCMotion prompt, image-to-video, klip per scene.
Voice Service
gRPCTTS multi-bahasa, emosi, pitch, speed.
Music Service
gRPCPemilihan/generasi musik dan ducking.
Subtitle Service
gRPCSubtitle sinkron, SRT/VTT, terjemahan.
Thumbnail Service
RESTVariasi thumbnail dan skor CTR.
SEO Service
RESTJudul, deskripsi, tag, keyword, hook.
Rendering Service
gRPCKomposisi timeline, transcode, multi-resolusi.
Notification Service
WS/SSEEvent realtime ke klien.
Analytics Service
RESTMetrik proyek, biaya, performa provider.
Admin Service
RESTKuota, moderasi, feature flag, rotasi kunci.
Struktur database
PostgreSQL + Prisma · setiap tabel memakai kolom dasar berikut
id uuid pk default gen_random_uuid() created_at timestamptz default now() updated_at timestamptz default now() status text not null deleted_at timestamptz null
- identity
users
Identitas pengguna, role, kuota, dan preferensi.
kolom: email citext unique · display_name text · avatar_url text · plan text · locale text
relasi: 1-N projects · 1-N api_keys · 1-N notifications · 1-N audit_logs
index: unique(email) · idx(plan, status)
- identity
user_roles
RBAC terpisah dari profil untuk mencegah privilege escalation.
kolom: user_id uuid fk→users · role app_role
relasi: N-1 users
index: unique(user_id, role)
- project
projects
Proyek video: narasi, metadata, bahasa, gaya visual, progress.
kolom: owner_id uuid fk→users · title text · narration text · language text · style text · progress int
relasi: 1-1 storyboards · 1-N render_jobs · 1-1 seo_packages
index: idx(owner_id, status) · idx(updated_at desc)
- creative
storyboards
Hasil Storyboard AI dan naskah teroptimasi.
kolom: project_id uuid fk→projects · optimized_script text · hook text · cta text · analysis jsonb
relasi: 1-N scenes
index: unique(project_id)
- creative
scenes
10 scene × 2 detik beserta kamera, emosi, transisi, prompt.
kolom: storyboard_id uuid fk→storyboards · index int · narration text · camera text · image_prompt text · video_prompt text
relasi: 1-1 image_assets · 1-1 video_assets · 1-N subtitle_assets
index: unique(storyboard_id, index)
- creative
characters
Character Bible terkunci untuk konsistensi visual.
kolom: project_id uuid fk→projects · name text · locked_prompt text · attributes jsonb
relasi: N-1 projects
index: idx(project_id)
- creative
environments
Environment Library: lokasi, cuaca, waktu, pencahayaan.
kolom: project_id uuid fk→projects · name text · attributes jsonb
relasi: N-1 projects
index: idx(project_id)
- asset
image_assets
Render gambar 9:16 per scene beserta versi regenerasi.
kolom: scene_id uuid fk→scenes · storage_path text · provider_id text · version int · checksum text
relasi: N-1 scenes
index: idx(scene_id, version desc) · idx(checksum)
- asset
video_assets
Klip video 2 detik hasil Video Director AI.
kolom: scene_id uuid fk→scenes · storage_path text · duration_ms int · provider_id text · version int
relasi: N-1 scenes
index: idx(scene_id, version desc)
- asset
voice_assets
Voice over: gender, emosi, pitch, speed.
kolom: project_id uuid fk→projects · storage_path text · voice_config jsonb · duration_ms int
relasi: N-1 projects
index: idx(project_id)
- asset
music_assets
Trek musik latar dan level ducking terhadap narasi.
kolom: project_id uuid fk→projects · storage_path text · mood text · gain_db numeric
relasi: N-1 projects
index: idx(project_id)
- asset
subtitle_assets
Subtitle sinkron (SRT/VTT) termasuk terjemahan.
kolom: project_id uuid fk→projects · locale text · format text · storage_path text · cues jsonb
relasi: N-1 projects
index: unique(project_id, locale, format)
- delivery
thumbnail_assets
Variasi thumbnail high-CTR beserta skor prediksi.
kolom: project_id uuid fk→projects · storage_path text · concept text · ctr_score numeric
relasi: N-1 projects
index: idx(project_id, ctr_score desc)
- delivery
seo_packages
Judul, deskripsi, tag, hashtag, keyword, hook komentar.
kolom: project_id uuid fk→projects · title text · description text · tags text[] · hashtags text[]
relasi: 1-1 projects
index: unique(project_id)
- delivery
render_jobs
Job antrean render/export beserta progres dan hasil.
kolom: project_id uuid fk→projects · queue text · stage text · attempts int · format text · resolution text · output_path text
relasi: N-1 projects · 1-N logs
index: idx(status, queue) · idx(project_id, created_at desc)
- ops
notifications
Notifikasi realtime (render, aset siap, error, export).
kolom: user_id uuid fk→users · project_id uuid null · type text · payload jsonb · read_at timestamptz
relasi: N-1 users
index: idx(user_id, read_at)
- ops
api_keys
Kunci API pengguna dengan rotasi dan scope terbatas.
kolom: user_id uuid fk→users · hashed_key text · scopes text[] · last_used_at timestamptz · expires_at timestamptz
relasi: N-1 users
index: unique(hashed_key) · idx(user_id, expires_at)
- ops
logs
Log workflow, request/response AI, retry, dan performa.
kolom: project_id uuid null · job_id uuid null · level text · agent text · message text · duration_ms int · meta jsonb
relasi: N-1 render_jobs
index: idx(project_id, created_at desc) · idx(level, created_at desc)
- ops
audit_logs
Jejak audit tak terhapus untuk aksi sensitif & keamanan.
kolom: actor_id uuid fk→users · action text · entity text · entity_id uuid · ip inet · diff jsonb
relasi: N-1 users
index: idx(actor_id, created_at desc) · idx(entity, entity_id)
- ops
settings
Preferensi pengguna/workspace: provider default, kualitas, budget.
kolom: scope text · owner_id uuid · key text · value jsonb
relasi: N-1 users
index: unique(scope, owner_id, key)
REST API /api/v1
Validasi request/response konsisten, job async mengembalikan 202 + jobId
/api/v1/projectsbearer · 30/menitMembuat proyek dan Project Memory baru.
req { title, narration, language, style } → 201 { project } · err: 422 VALIDATION_ERROR, 429 RATE_LIMITED
/api/v1/projectsbearer · 120/menitDaftar proyek milik pengguna (paginated, filter status).
req ?page&limit&status → 200 { items, page, total } · err: 401 UNAUTHORIZED
/api/v1/projects/{id}bearer · 120/menitDetail proyek + snapshot Project Memory.
200 { project, memory } · err: 403 FORBIDDEN, 404 NOT_FOUND
/api/v1/projects/{id}bearer · 60/menitMemperbarui metadata/narasi proyek.
req { title?, narration?, style? } → 200 { project } · err: 409 CONFLICT_VERSION, 422 VALIDATION_ERROR
/api/v1/projects/{id}bearer · 30/menitSoft delete proyek (deleted_at).
204 · err: 403 FORBIDDEN
/api/v1/script/analyzebearer · 20/menitMenjalankan Script Analyst + Story Optimizer.
req { projectId } → 202 { jobId } · err: 409 STAGE_ALREADY_RUNNING
/api/v1/storyboard/generatebearer · 20/menitMembuat 10 scene × 2 detik.
req { projectId } → 202 { jobId } · err: 424 MISSING_DEPENDENCY
/api/v1/images/generatebearer · 10/menitRender gambar per scene (batch atau tunggal).
req { projectId, sceneIds?, strategy? } → 202 { jobId } · err: 402 QUOTA_EXCEEDED, 451 CONTENT_BLOCKED
/api/v1/video/generatebearer · 6/menitImage-to-video per scene dengan motion prompt.
req { projectId, sceneIds? } → 202 { jobId } · err: 402 QUOTA_EXCEEDED, 504 PROVIDER_TIMEOUT
/api/v1/voice/generatebearer · 20/menitVoice over dengan konfigurasi emosi & bahasa.
req { projectId, voice } → 202 { jobId } · err: 422 VALIDATION_ERROR
/api/v1/music/generatebearer · 20/menitMemilih atau menghasilkan musik latar.
req { projectId, mood? } → 202 { jobId } · err: 424 MISSING_DEPENDENCY
/api/v1/subtitle/generatebearer · 20/menitSubtitle sinkron + terjemahan opsional.
req { projectId, locales? } → 202 { jobId } · err: 424 MISSING_DEPENDENCY
/api/v1/thumbnail/generatebearer · 10/menitVariasi thumbnail beserta skor CTR.
req { projectId, variants? } → 202 { jobId } · err: 402 QUOTA_EXCEEDED
/api/v1/seo/generatebearer · 20/menitPaket SEO YouTube lengkap.
req { projectId } → 200 { seo } · err: 424 MISSING_DEPENDENCY
/api/v1/render/startbearer · 6/menitKomposisi master timeline dan mulai render.
req { projectId, resolution, format } → 202 { jobId } · err: 409 RENDER_IN_PROGRESS
/api/v1/render/statusbearer · 600/menitStatus job render, progres, dan ETA.
req ?jobId → 200 { status, progress, etaSec } · err: 404 JOB_NOT_FOUND
/api/v1/exportbearer · 6/menitExport MP4/MOV/WebM pada 720p–4K.
req { projectId, targets[] } → 202 { jobId } · err: 402 QUOTA_EXCEEDED
/api/v1/uploads/initbearer · 60/menitInisiasi chunk upload (resumable) + signed URL.
req { filename, size, mime, checksum } → 201 { uploadId, chunkUrls } · err: 413 FILE_TOO_LARGE, 415 UNSUPPORTED_MEDIA
/api/v1/uploads/{id}/completebearer · 60/menitFinalisasi upload: virus scan, kompresi, versioning.
200 { asset } · err: 422 CHECKSUM_MISMATCH, 451 INFECTED_FILE
/api/v1/events/streambearer · 5 koneksi/penggunaSSE realtime: render, aset siap, error, retry, selesai.
200 text/event-stream · err: 401 UNAUTHORIZED
/api/v1/analytics/summarybearer+apikey · 60/menitMetrik proyek, biaya, dan performa provider.
req ?from&to → 200 { projects, successRate, avgRenderSec, costUsd } · err: 403 FORBIDDEN
AI Provider Adapter
Satu antarmuka per kapabilitas: adapter, retry, timeout, validasi, error mapping
| Adapter | Kapabilitas | Biaya | Kualitas | p95 | Timeout/Retry |
|---|---|---|---|---|---|
| llm.gateway.flash | llm | $0.002 | 92 | 3.2s | 45s / 3× |
| llm.gateway.pro | llm | $0.011 | 97 | 7.4s | 60s / 3× |
| image.gateway.nano | image | $0.012 | 90 | 9.0s | 90s / 4× |
| image.gateway.pro | image | $0.038 | 96 | 16.0s | 120s / 3× |
| video.img2vid.fast | video | $0.090 | 88 | 42.0s | 180s / 4× |
| video.img2vid.cine | video | $0.240 | 95 | 78.0s | 240s / 3× |
| tts.gateway.multi | tts | $0.004 | 91 | 5.2s | 60s / 3× |
| stt.gateway.whisper | stt | $0.003 | 93 | 4.1s | 60s / 2× |
| translate.llm | translation | $0.001 | 90 | 2.1s | 30s / 2× |
| music.library | music | $0.000 | 84 | 0.8s | 15s / 2× |
| music.generative | music | $0.060 | 93 | 28.0s | 120s / 2× |
| thumbnail.gateway | thumbnail | $0.014 | 92 | 11.0s | 90s / 3× |
PROVIDER_RATE_LIMITED · HTTP 429
retryable — Backoff eksponensial + failover provider.
PROVIDER_QUOTA_EXCEEDED · HTTP 402
non-retryable — Eskalasi billing, hentikan job.
PROVIDER_TIMEOUT · HTTP 504
retryable — Retry pada adapter fallback.
PROVIDER_INVALID_INPUT · HTTP 422
non-retryable — Validasi Zod gagal sebelum kirim.
PROVIDER_CONTENT_BLOCKED · HTTP 451
non-retryable — Regenerasi prompt oleh Prompt Engineer AI.
PROVIDER_UNAVAILABLE · HTTP 503
retryable — Circuit breaker terbuka 60 detik.
INTERNAL_ADAPTER_ERROR · HTTP 500
retryable — Log + alert on-call.
Workflow engine berbasis antrean
BullMQ + Redis · idempoten, resumable, dead-letter queue
q.story
concurrency 32Script Analysis, Story Optimization, Storyboard
q.design
concurrency 24Character, Environment, Prompt Generation
q.image
concurrency 64Image Generation (10 scene paralel)
q.video
concurrency 32Video Prompt, Video Generation
q.audio
concurrency 32Voice, Music, SFX, Subtitle
q.render
concurrency 16Composition, Thumbnail, SEO, Render, Export
q.dlq
concurrency 4Dead-letter: job gagal permanen, tunggu tindakan manual
Setiap job menyimpan projectId, stage, dan attempts di database — restart server tidak menghilangkan status, dan hanya tahap yang gagal yang dijalankan ulang (bukan seluruh pipeline).
Upload & storage
Supabase Storage / S3-compatible / Cloudinary via satu storage adapter
- Chunk upload 5 MB + resume via uploadId dan signed URL.
- Progress event dikirim lewat SSE ke klien.
- Kompresi otomatis: gambar → WebP/AVIF, audio → AAC, video → H.264/H.265.
- Virus scan sebelum aset dipublikasikan; file terinfeksi ditolak 451.
- Auto rename ke `{projectId}/{kind}/{uuid}.{ext}` untuk mencegah tabrakan.
- Versioning per aset (version + checksum) agar regenerasi tidak menimpa.
- Lifecycle rule: aset sementara dihapus otomatis setelah 24 jam.
- Signed URL berumur pendek untuk unduhan; bucket tidak publik.
Caching & notifikasi realtime
Redis namespace + SSE/WebSocket event
Redis
session:{userId}— Sesi & refresh token metadata · TTL 7 hariworkflow:{projectId}— State workflow & posisi resume · TTL 24 jamqueue:{queueName}:stats— Kedalaman antrean & throughput · TTL 30 detikprompt:{hash}— Prompt sementara & hasil dedup · TTL 6 jamthumb:{assetId}— Cache thumbnail terkompresi · TTL 30 hariapi:{route}:{hash}— Response cache endpoint GET · TTL 60 detikproject:{projectId}— Snapshot Project Memory · TTL 10 menit
Event realtime
Strategi keamanan
Defense in depth dari edge sampai database
- JWT akses pendek (15 menit) + refresh token rotasi dengan reuse detection.
- RBAC pada tabel user_roles terpisah + security definer has_role().
- Rate limiting per IP, per pengguna, dan per API key (token bucket di Redis).
- CORS allowlist ketat, CSRF token untuk cookie flow, SameSite=Lax.
- Validasi Zod di setiap boundary request/response.
- Query berparameter/ORM — tidak ada SQL string concatenation.
- Sanitasi output & Content Security Policy tanpa inline script.
- Secret terenkripsi at-rest, rotasi API key terjadwal, tanpa secret di klien.
- Audit trail immutable untuk aksi sensitif (append-only, retensi 1 tahun).
- Virus scan dan validasi MIME/checksum pada seluruh upload.
Monitoring, logging & analytics
Prometheus + Grafana · Winston → Loki · trace terkorelasi requestId
| Metrik | Target | Alert |
|---|---|---|
| api_request_duration_seconds | p95 < 300 ms | p95 > 800 ms selama 5 menit |
| queue_depth | < 500 job | > 2000 job selama 10 menit |
| ai_provider_latency_seconds | p95 sesuai SLA adapter | 3× baseline |
| render_duration_seconds | p95 < 180 s | p95 > 420 s |
| job_success_rate | > 98% | < 95% dalam 15 menit |
| storage_usage_bytes | < 80% kuota | > 90% kuota |
| db_connections_active | < 70% pool | > 90% pool |
| cost_per_project_usd | sesuai budget paket | > 150% baseline |
Analytics menghitung jumlah proyek, video sukses, rata-rata waktu render, provider tercepat & terakurat, penggunaan API, serta biaya per proyek dan per pengguna dari tabel logs + render_jobs.
Deployment & CI/CD
Docker → Kubernetes · canary + rollback otomatis
- 1.Push ke GitHub memicu GitHub Actions.
- 2.Lint, typecheck, unit & integration test, contract test OpenAPI.
- 3.Security scan: dependency audit, SAST, secret scanning, image scan.
- 4.Build image Docker multi-stage, tag imutabel per commit.
- 5.Deploy bertahap (canary 10% → 50% → 100%) ke Kubernetes.
- 6.Health check + smoke test; gagal → rollback otomatis ke revisi sebelumnya.
- 7.Migrasi database forward-only dengan expand/contract agar zero-downtime.
- 8.Backup harian (PITR 7 hari) dan mingguan (retensi 90 hari) untuk DB, aset, konfigurasi.
Catatan implementasi pada stack ini
Jalur tercepat dari blueprint ke produksi di Lovable
- Aplikasi ini berjalan di TanStack Start: endpoint publik dipetakan ke server route
src/routes/api/*, dan logika internal ke server function bertipe aman. - Aktifkan Lovable Cloud untuk mendapatkan PostgreSQL, Auth (email + Google), Storage, dan RLS tanpa setup — menggantikan kebutuhan Supabase/Prisma/Docker terpisah pada tahap awal.
- Provider AI cukup diakses lewat satu AI Gateway; adapter di
src/lib/backend/providers.tssudah menyiapkan retry, timeout, error mapping, cache key, dan cost optimizer. - Untuk skala jutaan video, pindahkan worker antrean (BullMQ/Redis) dan rendering FFmpeg ke layanan container terpisah; kontrak REST di halaman ini tetap sama.