iSpeaker Live iSpeaker Live / Docs
Engineering

🏗️ System Architecture

From request to response — how the multi-client iSpeaker Live platform is wired together.

High-Level Overview

iSpeaker Live is a headless API + multi-client architecture. A single Laravel API serves a Next.js web app, a Flutter mobile app, and a Filament admin panel. Real-time communication is delivered via Laravel Reverb (WebSockets), and live video uses Jitsi Meet.

Technology Stack

🎨 Frontend Web

  • Next.js 15 (App Router)
  • React 19
  • TypeScript
  • Tailwind CSS + shadcn/ui
  • SWR / fetch for data
  • Laravel Echo + Pusher-JS for WebSocket

📱 Mobile

  • Flutter (latest stable)
  • Clean Architecture (data / domain / presentation)
  • Provider / Riverpod for state
  • Dio for HTTP, FlutterSecureStorage
  • jitsi_meet_flutter_sdk
  • firebase_messaging

⚙️ Backend API

  • Laravel 11 on PHP 8.3
  • Laravel Sanctum (auth)
  • Spatie laravel-permission (roles)
  • Filament v3 (admin panel)
  • Laravel Reverb (WebSocket server)
  • Laravel Queues + Scheduler

🗄️ Data & Infra

  • MySQL 8.0
  • Redis (cache + queues)
  • Object storage for media
  • DigitalOcean droplets
  • Nginx + PHP-FPM
  • Self-hosted Jitsi for streaming

System Diagram

flowchart TB subgraph Clients W[Next.js Web App] M[Flutter Mobile App] AD[Filament Admin] end subgraph EdgeLayer ["Edge / Web Tier"] NGINX[Nginx
Reverse Proxy + TLS] end subgraph App ["Application Tier"] API[Laravel 11 API
PHP-FPM] REVERB[Reverb
WebSocket Server] QUEUE[Queue Workers] SCHED[Scheduler] end subgraph Data ["Data Tier"] MYSQL[(MySQL 8)] REDIS[(Redis
cache + queue)] STORAGE[Object Storage
media / PDFs / videos] end subgraph External ["External Services"] JITSI[Jitsi Meet
self-hosted] PAYPAL[PayPal] FCM[Firebase
Cloud Messaging] SMTP[Email SMTP] end W --> NGINX M --> NGINX AD --> NGINX NGINX --> API NGINX --> REVERB API --> MYSQL API --> REDIS API --> STORAGE API --> QUEUE API --> SCHED QUEUE --> MYSQL QUEUE --> FCM QUEUE --> SMTP API <--> REVERB REVERB --> REDIS M --> JITSI W --> JITSI API --> PAYPAL

Backend (Laravel)

Folder structure

  • app/Http/Controllers/Api/ — 26 REST controllers (Auth, Cart, Course, Book, LiveRoom, Wallet, …).
  • app/Models/ — 40+ Eloquent models with relationships.
  • app/Filament/ — Filament resources for the admin panel.
  • app/Events/ — broadcast events for real-time (new messages, room updates).
  • app/Services/ — business logic (PaypalService, NotificationService, etc.).
  • app/Traits/ — reusable model traits (e.g. HasMediaUrls).
  • app/Helpers/ — global helper functions.
  • routes/api.php — 180+ endpoints grouped by feature.

Middleware stack on API routes

  1. throttle:api — rate limiting.
  2. localization — sets app locale.
  3. auth:sanctum — token auth (where required).
  4. role:speaker / role:student — Spatie role gates.

Background jobs

  • Notification fan-out (FCM + in-app).
  • Email delivery (welcome, password reset, invoice).
  • Media processing (thumbnails, transcoding hooks).
  • Scheduled tasks: room reminders, abandoned cart hints, daily aggregates.

Web (Next.js)

App Router layout — student and speaker have separate dashboards.

  • app/dashboard/student/* — feed, learn, books, rooms, marketplace, profile, wallet, chat, notifications, collections, speakers, follow-requests, cart.
  • app/dashboard/speaker/* — same surfaces plus authoring tools (courses, books, rooms, consultations, statistics, my-creations).
  • app/(public)/* — landing, login, register, privacy, terms.
  • app/courses/[courseId] — public course preview pages.
  • app/profile/[username], app/users/[id], app/posts/[id].
  • components/ — organized by feature (feed, course, reader, chat, wallet, rooms, …) plus shared UI primitives.
  • app/sitemap.ts, app/robots.ts — search-engine metadata served by Next's native routes at /sitemap.xml and /robots.txt. The sitemap lists the pages a signed-out visitor can genuinely read, plus current posts and hashtags pulled hourly from the public API; dashboards and auth screens are excluded from it and disallowed in robots.

Mobile (Flutter)

Clean Architecture with feature-based folders.

  • lib/core/ — helpers, networking, providers, routing, error, theme, storage, localization.
  • lib/features/<feature>/data — repositories & remote data sources.
  • lib/features/<feature>/domain — entities & use cases.
  • lib/features/<feature>/presentation — screens, widgets, state.

18 feature modules:

auth · feed · profile · home · marketplace · speakers · book_consultation · speaker_consultations · rooms · speaker_rooms · my_creations · speaker_courses · speaker_books · collections · wallet · statistics · chat · notifications

Real-time (Laravel Reverb)

  • WebSocket server runs alongside the API.
  • Frontend authenticates against /api/broadcasting/auth using its Sanctum token.
  • Channels by feature: conversation.{id} for chat, room.{id} for live rooms, user.{id} for personal events.
  • Events: MessageSent, RoomMessageSent, NotificationCreated, RoomStatusChanged, etc.
sequenceDiagram participant C as Client participant A as Laravel API participant R as Reverb participant D as DB C->>A: POST /chat/messages A->>D: Insert message A->>R: broadcast(MessageSent) R-->>C: message event (other party) C-->>C: Live update UI

Live Streaming (Jitsi Meet)

  • Self-hosted Jitsi server on a dedicated droplet (separate from web tier).
  • Room IDs are server-generated and stored in live_rooms.current_jitsi_room_id.
  • JWT-based authentication on Jitsi where required (paid rooms).
  • Web uses iframe embed; mobile uses jitsi_meet_flutter_sdk.
  • Served from meet.ispeakerlive.com with the iSpeaker logo as an in-room watermark (set in the Jitsi server's interface_config.js).
  • A wait-for-host gate keeps participants in the lobby until the room owner joins.
  • All room scheduling and countdown times are displayed in Asia/Riyadh (UTC+3) across web, mobile and the API.
  • Recordings (where enabled) saved to object storage and listed on the room.

Storage & Media

  • User-uploaded media (avatars, covers, post images / videos / audio) live in object storage.
  • Course videos, book PDFs, and lesson attachments use private buckets.
  • Access to protected media via signed short-lived URLs generated by the API.
  • HasMediaUrls trait normalizes media field URLs on model serialization.

Security

  • Auth: Sanctum bearer tokens with last-used / expires-at indexes.
  • Authorization: Spatie roles + per-route middleware. Speaker-only endpoints explicitly gated.
  • Transport: HTTPS everywhere; HSTS at the edge.
  • Passwords: bcrypt hashing via Laravel.
  • Encryption at rest: stored bank details — IBAN and account-holder name — are encrypted with AES-256-CBC through Laravel's encrypted cast, keyed by APP_KEY. Both storage sites are covered: the speaker's profile record, and the payout snapshot held inside each withdrawal transaction. Each row gets its own random IV, so two accounts holding the same IBAN do not produce matching ciphertext.
  • Rate limiting: per-IP and per-user on auth and high-cost endpoints.
  • CSRF: not applicable to stateless API; web forms use Laravel's built-in protection.
  • File uploads: validated MIME & size; stored outside web root.
  • SQL injection / XSS: Eloquent + Laravel escaping by default.
  • Reverb auth: presence and private channels go through Sanctum.

Scalability

  • Stateless API horizontally scalable behind load balancer.
  • Reverb can scale via Redis broadcaster across nodes.
  • Queue workers scale per workload (notifications high-throughput).
  • MySQL read-replica path planned for Phase 2 (heavy listing endpoints).
  • CDN in front of object storage for media delivery.
  • Jitsi instance scales by adding video bridges (JVBs).