Back to SyncoraSystem Design

Syncora System Design

Complete architecture, deployment guide, and setup instructions for the Syncora watch-together platform.

System Architecture

Syncora is a full-stack monorepo with two applications shipping together: a NestJS backend and a Next.js 14 frontend. The system is designed for real-time watch-together experiences with sub-second video sync, encrypted chat, and HD video calls.

Tech Stack

BackendNestJS 10 + TypeScript
DatabasePostgreSQL 15 (Prisma ORM)
Cache/PubSubRedis 7
Real-time ChatSocket.IO (WebSocket)
Video CallsLiveKit (WebRTC)
Video SyncRedis state + Socket.IO events
File StorageLocal filesystem (uploads/)
YouTube Downloadsyt-dlp CLI
EmailGmail SMTP (Nodemailer)
FrontendNext.js 14 (App Router)
UITailwind CSS + Framer Motion
StateZustand
DeploymentDocker Compose + Nginx + PM2

Backend Modules

AuthModule

JWT auth (access + refresh tokens), email/password signup, Google OAuth, OTP email verification, password reset with expiring links

RoomsModule

CRUD for couple/friend rooms, invite codes (6-char), member management, kick/regenerate

ChatModule

Socket.IO gateway, encrypted messages (AES), image/GIF/sticker support, typing indicators, reactions, message deletion

UploadModule

Chunked multipart uploads (4MB chunks), server reassembly, 25MB room limit, 5MB per image, 6hr auto-cleanup

WatchModule

YouTube download via yt-dlp (max 3hr), video sync via Redis state, watch history/resume, adaptive quality

CallModule

LiveKit token generation, call state in Redis, couple/friend validation, incoming call notifications, call records in chat

AdminModule

Dashboard stats, user/room management, storage monitoring

MailModule

OTP, welcome, password reset emails with monochrome templates

Frontend Pages

/Marketing landing page (hero, features, how-it-works, pricing)
/auth/*Login, signup, verify email, forgot/reset password, Google OAuth
/dashboardRoom list, create/join rooms
/room/[id]Chat room with WhatsApp-style messaging
/room/[id]/callVideo call with 70/30 layout, airhorn sound
/room/[id]/watchWatch together with sync player, YouTube download, library
/adminAdmin dashboard with user/room stats

Data Flow

1. User signs up → OTP email → verify → login → JWT access (15min) + refresh (30d) cookies 2. Creates room → invite code generated → share with partner/friends 3. Chat: Socket.IO → encrypt message → store in Postgres → broadcast to room 4. Watch: Upload/YouTube link → server stores file → Redis sync state → all players sync 5. Call: Request LiveKit token → WebRTC peer connection → Redis call state → chat records

Security Features

AES encryption for chat messages (CHAT_ENCRYPTION_KEY)
JWT with httpOnly cookies (refresh) + bearer token (access)
Automatic token refresh interceptor (401 → refresh → retry)
Rate limiting on all endpoints (throttler)
Input sanitization (XSS prevention)
Room membership guards on all endpoints
Password hashing with bcrypt (12 rounds)
OTP brute-force protection (5 attempts max)
Password reset links expire after use + 30min TTL
CORS restricted to allowed origins
No premium/credit system — everything free

Google OAuth Setup

Step 1: Create Google Cloud Project

  1. Go to console.cloud.google.com
  2. Click Select a projectNew Project
  3. Name it Syncora
  4. Click Create

Step 2: Configure OAuth Consent Screen

  1. Go to APIs & ServicesOAuth consent screen
  2. Select External user type → Create
  3. Fill in: App name = Syncora, User support email = your email
  4. Add Authorized domains: bhupeshchauhan.in
  5. Add Developer contact email → Save and Continue
  6. On Scopes page → Add scope: openid, email, profile
  7. Save and Continue → Back to Dashboard

Step 3: Create OAuth Credentials

  1. Go to APIs & ServicesCredentials
  2. Click Create CredentialsOAuth client ID
  3. Application type: Web application
  4. Name: Syncora Web
  5. Authorized JavaScript origins:
    • https://syncora.bhupeshchauhan.in
    • http://localhost:3000 (for dev)
  6. Authorized redirect URIs:
    • http://localhost:3001/api/auth/google/callback
  7. Click Create
  8. Copy the Client ID and Client Secret

Step 4: Add to Environment Variables

# Backend .env

GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com

GOOGLE_CLIENT_SECRET=your-client-secret

# Frontend .env.local

NEXT_PUBLIC_GOOGLE_CLIENT_ID=your-client-id.apps.googleusercontent.com

Domain & VPS Deployment

Step 1: Domain DNS Setup (Hostinger)

  1. Login to Hostinger → DNS / Nameservers
  2. Add DNS records:

    Type: A | Name: @ | Value: YOUR_VPS_IP

    Type: A | Name: admin | Value: YOUR_VPS_IP

    Type: A | Name: www | Value: YOUR_VPS_IP

  3. Wait 5-30 minutes for DNS propagation
  4. Verify: dig syncora.bhupeshchauhan.in

Step 2: VPS Setup (Ubuntu 22.04)

# SSH into your VPS

ssh root@YOUR_VPS_IP

# Install Docker

curl -fsSL https://get.docker.com | sh

sudo usermod -aG docker $USER

# Clone the repo

git clone https://github.com/yourusername/Syncora.git

cd Syncora

# Install Certbot for SSL

sudo apt install certbot -y

sudo certbot certonly --standalone -d syncora.bhupeshchauhan.in -d admin.syncora.bhupeshchauhan.in

# Copy SSL certs

sudo cp /etc/letsencrypt/live/syncora.bhupeshchauhan.in/fullchain.pem nginx/certs/

sudo cp /etc/letsencrypt/live/syncora.bhupeshchauhan.in/privkey.pem nginx/certs/

Step 3: Configure & Deploy

  1. Edit .env with your credentials
  2. Run: bash deploy.sh
  3. Verify: docker compose -f docker-compose.prod.yml ps

Step 4: SSL Auto-Renewal

# Add cron job for auto-renewal

sudo crontab -e

Add this line:

0 3 * * 1 certbot renew --post-hook "cp /etc/letsencrypt/live/syncora.bhupeshchauhan.in/*.pem /home/user/Syncora/nginx/certs/ && docker compose -f /home/user/Syncora/docker-compose.prod.yml restart nginx"

Environment Variables

VariableDescriptionExample
DATABASE_URLPostgreSQL connection stringpostgresql://user:pass@host:5432/db
REDIS_URLRedis connection stringredis://redis:6379
JWT_SECRETSecret for JWT signingrandom-64-char-string
WEB_URLFrontend URLhttps://syncora.bhupeshchauhan.in
GMAIL_USERSMTP emailyour@gmail.com
GMAIL_APP_PASSWORDGmail app passwordxxxx-xxxx-xxxx-xxxx
GOOGLE_CLIENT_IDGoogle OAuth client IDxxx.apps.googleusercontent.com
GOOGLE_CLIENT_SECRETGoogle OAuth secretGOCSPX-xxx
LIVEKIT_API_KEYLiveKit API keydevkey
LIVEKIT_API_SECRETLiveKit API secretdevkeysecret
LIVEKIT_URLLiveKit WebSocket URLwss://syncora.bhupeshchauhan.in/livekit
UPLOAD_DIRFile upload directory/app/uploads
CHAT_ENCRYPTION_KEYAES key for chatsame-as-jwt-secret
NEXT_PUBLIC_API_URLFrontend API URLhttps://syncora.bhupeshchauhan.in/api
NEXT_PUBLIC_GOOGLE_CLIENT_IDFrontend Google client IDxxx.apps.googleusercontent.com

Built with care by Bhupesh Chauhan

Syncora — Watch Together. Feel Together.