Skip to content

System Architecture

Vidivo is built as a set of independent microservices, each responsible for a distinct domain. Services communicate over HTTP/JSON internally. The system is deployed on Docker Swarm with Traefik as the reverse proxy.

+-------------------------+
| Clients |
| Web . iOS . Android . |
| Admin Panel |
+-----------+--------------+
| HTTPS
+-----------v--------------+
| Traefik 3 |
| Reverse Proxy / TLS |
+---+------------------+---+
| |
+---------------v---+ +---------v-----------+
| api.vidivo.app | | signal.vidivo.app |
| API Gateway | | Signaling Service |
| (Echo v5) | | (WebSocket) |
+---+----------+----+ +---------------------+
| |
+------------+ +-----+
| |
v v
+------+--+ +----------+--+ +----------+ +----------+
| Auth | | User | | Call | | Billing |
| Service | | Service | | Service | | Service |
+---------+ +-------------+ +----------+ +----------+
+----------+ +----------+ +----------+ +------------+
| Chat | | Follow | | Notif | | Support |
| Service | | Service | | Service | | Service |
+----------+ +----------+ +----------+ +------------+
+----------+ +----------+
| Verif. | | Admin |
| Service | | Service |
+----------+ +----------+
| | | |
v v v v
+----------------------------------------------+
| PostgreSQL 17 (Neon) |
+----------------------------------------------+
+----------------------------------------------+
| Redis 8 |
| Sessions . Call State . Signaling . Limits |
+----------------------------------------------+
External: Stripe . FCM . Resend . Xident . Cloudflare R2
+------------------------+
| turn.vidivo.app |
| TURN Server |
| (pion/turn v4, VPS) |
| UDP 3478 / TCP 5349 |
+------------------------+
ServicePathResponsibility
API Gatewayapi.vidivo.appRoute aggregation, auth middleware, rate limiting, CORS
Auth/v1/auth/*Registration, login, JWT issuance, token refresh, OAuth, guest sessions
User/v1/users/*Profile CRUD, avatar upload, host onboarding, availability scheduling
Call/v1/calls/*, /v1/schedule/*Call links, sessions, history, scheduling, calendar invites
Billing/v1/payments/*Stripe hold/capture, earnings, payouts, invoices, data export
Chat/v1/chat/*Real-time messaging, WebSocket hub, file sending, broadcast
Follow/v1/users/:id/follow*User follows host system
Signalingsignal.vidivo.appWebSocket relay for WebRTC SDP/ICE exchange
Notification/v1/notifications/*In-app notifications, FCM push delivery, email
Support/v1/support/*Support ticket system with threaded messages
Verification/v1/verification/*Age verification via Xident integration
Admin/v1/admin/*User/call management, stats, notification broadcast, refunds
TechnologyVersionRole
Go1.26All microservice runtimes
Echov5HTTP framework (router, middleware, binding)
GORMlatestORM for PostgreSQL
golang-migratelatestDatabase schema migrations
pion/webrtcv4WebRTC (signaling)
pion/turnv4TURN server binary
slogstdlibStructured JSON logging
PrometheuslatestMetrics collection
StoreVersionRole
PostgreSQL17Primary relational database (Neon in production)
Redis8Sessions, call state, signaling, rate limits, presence
Cloudflare R2-Object storage (avatars, invoices)
TechnologyVersionRole
React19Web app and admin panel UI
Vite7Build tool and dev server
React Routerv7Client-side routing
ZustandlatestGlobal state management
TanStack Queryv5Server state, caching, mutations
Radix UIlatestAccessible component primitives
Tailwind CSS4Utility-first styling
Stripe ElementslatestSecure card input (PCI compliance)
PlatformTechnologyArchitecture
iOSSwift + SwiftUIMVVM + Clean Architecture, min iOS 16
AndroidKotlin + Jetpack ComposeMVVM + Clean Architecture, min SDK 26
ComponentTechnologyNotes
Container orchestrationDocker SwarmNot Kubernetes (simpler for single-region V1)
Reverse proxyTraefik 3Auto-discovery, Let’s Encrypt TLS
CDNCloudflareWeb app, DDoS protection
Object storageCloudflare R2Profile images, invoices
EmailResendTransactional emails
Push notificationsFirebase Cloud MessagingiOS, Android, Web push
ObservabilityPrometheus + Grafana + Loki + JaegerMetrics, logs, traces

Each service follows a consistent Clean Architecture pattern:

internal/<service>/
+-- router.go -- RegisterRoutes(), dependency wiring
+-- handler/handler.go -- HTTP handlers (parse request -> call service -> respond)
+-- service/service.go -- Business logic (orchestrates repos + external clients)
+-- repository/ -- Database access via GORM
+-- dto/ -- Request/response types

Key conventions:

  • Handlers only parse HTTP requests and format responses
  • Business logic lives exclusively in the service layer
  • Repository methods accept and return GORM models
  • DTOs are the contract between handlers and services
  • Functional options pattern for optional dependencies (e.g., WithBilling(), WithNotifier())
Guest Browser
|
| 1. GET /c/{short_code} (Cloudflare CDN -> Web App)
v
Web App (React)
|
| 2. GET /v1/calls/links/{shortCode}/info -- fetch link metadata
| POST /v1/auth/guest-session -- obtain guest token
| POST /v1/payments/guest/setup-intent -- get Stripe client secret
| POST /v1/calls/join/{short_code} -- place hold, create session
v
API Gateway -> Billing Service -> Stripe API
|
| 3. Signaling token + TURN credentials issued
v
WebSocket -> signal.vidivo.app
|
| 4. SDP offer/answer exchanged
v
P2P WebRTC (direct or via TURN relay)
Call starts
|
| PaymentIntent (hold) created via Stripe API
| -> payment_transactions record (status: hold)
v
Window timer runs (Redis: billing:{id}:state)
|
| At window_size - 60s: next hold placed
| At window_size: current window captured
| -> Stripe captures PaymentIntent
| -> payment_transactions updated (status: captured)
| -> Invoice PDF generated (fire-and-forget)
| -> Notification created + email receipt sent
v
Call ends (POST /v1/calls/{id}/end)
|
| Partial window captured
| Remaining holds released
| call_sessions record finalized
v
Host requests payout -> Stripe Payout to bank

The platform uses 16+ tables across 18 migrations. Key tables:

TableDescription
usersAll user accounts (multi-role, soft deletes)
call_linksShareable URLs with configuration
call_sessionsActive and completed call records
scheduled_callsBooked future calls
payment_transactionsPer-window Stripe PaymentIntent records
host_payoutsPayout requests and status tracking
invoicesInvoice records with R2 storage keys
guest_sessionsAnonymous caller sessions
user_followsFollower relationships
conversationsChat conversation metadata
conversation_participantsChat participants with read tracking
messagesChat messages
notificationsIn-app notification records
push_tokensFCM device tokens
support_ticketsSupport ticket records
ticket_messagesThreaded ticket replies
verification_recordsAge verification results
stripe_accountsHost Stripe Connected Account references

All primary keys use UUID format. All timestamps use TIMESTAMPTZ (UTC). Soft deletes are implemented on user-facing tables for GDPR compliance.

HostnameBackendNotes
vidivo.appCloudflare CDNWeb app (React PWA)
api.vidivo.appTraefik -> API GatewayREST API
signal.vidivo.appTraefik -> SignalingWebSocket (sticky sessions required)
turn.vidivo.appDirect to TURN VPSUDP 3478 / TCP 5349 --- no proxy
admin.vidivo.appTraefik -> Admin PanelAdmin panel
docs.vidivo.appCloudflare CDNThis documentation site
Client -> API Gateway
|
| Validate JWT (RS256, public key from JWKS)
| Check token expiry, role claims
v
Upstream Service

Access tokens are signed with a private RSA key held only by the auth service. All other services validate tokens using the public key available at /.well-known/jwks.json.

  • Passwords: bcrypt with cost factor 12
  • Media: DTLS-SRTP (mandatory, browser-enforced)
  • Transport: TLS 1.2+ enforced by Traefik
  • Card data: Never touches Vidivo servers (Stripe Elements)
  • TURN credentials: HMAC-SHA1 time-limited (24h expiry, RFC 5389)

All services emit:

  • Structured JSON logs via slog, collected by Loki
  • Prometheus metrics scraped every 15s, visualized in Grafana
  • Distributed traces via OpenTelemetry -> Jaeger

Key dashboards:

  • Active calls and concurrent sessions
  • Billing success/failure rate
  • TURN usage percentage
  • API latency percentiles (p50, p95, p99)
  • WebRTC connection failure rate