Engineering
🏗️ System Architecture
From request to response — how the multi-client iSpeaker Live platform is wired together.
On this page
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
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
throttle:api— rate limiting.localization— sets app locale.auth:sanctum— token auth (where required).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.
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/authusing 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
iframeembed; mobile usesjitsi_meet_flutter_sdk. - 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.
HasMediaUrlstrait 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.
- 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).