SpeakBridge is a full-stack online English tutoring platform that connects students with verified tutors for live 1-on-1 video lessons. The platform includes real-time video calling, an interactive whiteboard, AI-powered speech analysis, subscription-based pricing, Stripe payment processing, and a complete admin panel for platform management.
- Project Overview
- Key Features
- Tech Stack
- Architecture
- Project Structure
- Database Design
- Authentication and Authorization
- Cloud Functions (Backend API)
- Frontend Pages and Routing
- Third-Party Integrations
- Getting Started
- Environment Variables
- Available Scripts
- API Documentation
SpeakBridge serves three user roles:
- Students -- Browse tutors, book lessons, join video sessions, receive AI-generated feedback on their spoken English, manage subscriptions, and leave reviews.
- Tutors -- Set availability schedules, manage students and bookings, conduct live video lessons with whiteboard and note-taking tools, create structured courses, and request payouts via Stripe Connect.
- Admins -- Approve or reject tutor applications, moderate content and reports, manage users (ban/unban), oversee finances and payouts, and manage courses platform-wide.
New tutor accounts register with a "guest" role and must submit verification documents (CV, certificates). An admin reviews the application and either promotes the guest to a verified tutor or rejects the application with feedback.
- Tutor discovery with filtering by language, accent, level, and teaching style
- Tutor profile pages with ratings, reviews, education, experience, and intro videos
- Booking system with calendar-based scheduling against tutor availability slots
- Live 1-on-1 video sessions via Agora RTC
- Interactive whiteboard (Netless Fastboard) during sessions
- Session recordings with cloud recording support
- AI-powered post-session analysis (vocabulary, grammar, fluency, pronunciation scoring)
- Subscription plans with Stripe checkout
- Real-time chat messaging with tutors
- Notification system (booking updates, system alerts, payment confirmations)
- Feedback and rating system for completed sessions
- Report system for flagging inappropriate content or behavior
- Application and verification workflow (guest to tutor promotion)
- Availability schedule management with recurring slots
- Student management dashboard with private notes per student
- Course and lesson creation with structured curricula
- Session recording controls (acquire, start, stop cloud recording)
- Payout requests via Stripe Connect with admin approval
- Profile management (bio, qualifications, certifications, intro video)
- Dashboard with platform-wide statistics
- Tutor application review (approve/reject with reason)
- Student and tutor management (view, ban, unban with temporary/permanent options)
- Content moderation for reports (review reports, user reports)
- Financial overview and payout management (approve/reject payout requests)
- Course management (create, edit, delete courses platform-wide)
- Audit logging for admin actions
- Role-based access control with protected routes
- Firebase Authentication with email/password and Google Sign-In
- Real-time data synchronization via Firestore listeners
- Firebase emulator support for local development
- Swagger/OpenAPI documentation for all backend endpoints
- Lazy ban evaluation (auto-unban when temporary ban expires)
- Responsive design with Tailwind CSS
| Technology | Purpose |
|---|---|
| React 19 | UI framework |
| Vite 7 | Build tool and dev server |
| React Router 7 | Client-side routing |
| Redux Toolkit | Global state management |
| Tailwind CSS 3 | Utility-first styling |
| Firebase SDK 12 | Auth, Firestore, Storage, Functions client |
| Agora RTC SDK | Real-time video/audio communication |
| Netless Fastboard | Interactive whiteboard |
| Stripe React | Payment UI components |
| Lucide React | Icon library |
| DOMPurify | HTML sanitization |
| html2canvas | Screenshot/export functionality |
| Technology | Purpose |
|---|---|
| Node.js 20 | Runtime |
| Firebase Functions v2 | Serverless function hosting |
| Firebase Admin SDK | Server-side Firestore, Auth, Storage access |
| Express 5 | HTTP framework (for Swagger endpoint) |
| Stripe SDK | Payment processing and Stripe Connect payouts |
| Google Generative AI | AI-powered speech analysis (Gemini) |
| Agora Token/Access Token | RTC token generation for video sessions |
| Netless Token | Whiteboard room token generation |
| FFmpeg (fluent-ffmpeg) | Video/audio processing |
| Swagger (swagger-jsdoc + swagger-ui-express) | API documentation |
| Technology | Purpose |
|---|---|
| Firebase Hosting | Static frontend hosting (SPA) |
| Cloud Firestore | NoSQL document database |
| Firebase Authentication | User identity management |
| Firebase Storage | File storage (recordings, CVs, avatars) |
| Firebase Emulators | Local development environment |
+---------------------+
| Firebase Hosting |
| (React SPA) |
+----------+----------+
|
+-------------+-------------+
| |
+---------v---------+ +-----------v-----------+
| Firebase Auth | | Cloud Firestore |
| (JWT Tokens) | | (NoSQL Database) |
+-------------------+ +-----------------------+
| |
+---------v-----------------------------v---------+
| Firebase Cloud Functions |
| (Callable Functions - onCall / onRequest) |
+---------+----------+----------+---------+-------+
| | | |
+-------v--+ +----v-----+ +--v------+ +v---------+
| Stripe | | Agora | | Google | | Firebase |
| Payments | | RTC/ | | Gemini | | Storage |
| Connect | | Recording| | AI | | (Files) |
+----------+ +----------+ +---------+ +----------+
The Cloud Functions codebase follows a clean layered architecture:
Controller Layer --> HTTP handling, input extraction, error responses
|
Middleware Layer --> Authentication (JWT), authorization (role checks), validation
|
Service Layer --> Business logic, workflow orchestration, validation rules
|
Repository Layer --> Firestore data access, queries, transactions
|
Cloud Firestore --> Persistent data storage
Each layer has a single responsibility. Controllers never directly access the database, and repositories contain no business logic.
SpeakBridge/
|
|-- client/ # Frontend (React + Vite)
| |-- src/
| | |-- components/
| | | |-- common/ # Reusable UI (Button, Input, LoadingSpinner, Toast,
| | | | # ProtectedRoute, ErrorBoundary, Modals, Headers)
| | | |-- admin/ # Admin-specific (BanModal, UnbanModal, ResolveReportModal)
| | | |-- feedback/ # FeedbackCard, FeedbackForm, FeedbackList, ReportFeedbackModal
| | | |-- report/ # ReportTutorModal
| | | |-- room/ # NotesPanel, WhiteboardPanel (in-session tools)
| | | |-- tutor/ # RequestPayoutModal, StudentNoteModal
| | | |-- layouts/ # TutorLayout, AdminLayout
| | | |-- LandingPage.jsx # Landing page composition (Hero, Pricing, Sections)
| | | +-- ... # Hero, Footer, Header, SectionGoals, SectionTutors, etc.
| | |
| | |-- pages/
| | | |-- auth/ # LoginPage, SignUpFormPage, TutorSignUpPage, TutorLoginPage,
| | | | # AdminLoginPage, ForgotPasswordPage, ResetSuccessPage
| | | |-- admin/ # AdminCourses, AdminFinance, ContentModeration,
| | | | # StudentManagement, TutorManagement, CreateCoursePage, EditCoursePage
| | | |-- tutor/ # Dashboard, TutorSchedule, MyStudentsPage, StudentDetail,
| | | | # MyProfile, EditProfile, BecomeTutorPage, WaitForPermitPage
| | | |-- room/ # Room.jsx (video session page)
| | | |-- FindTutorPage.jsx # Tutor search and discovery
| | | |-- TutorDetailPage.jsx # Tutor profile with booking
| | | |-- CoursesPage.jsx # Course catalog
| | | |-- CourseDetailPage.jsx # Course detail with lessons
| | | |-- StudentCalendarPage # Student booking calendar
| | | |-- StudentProfilePage # Student profile management
| | | |-- StudentRecordingPage # Session recording playback + AI analysis
| | | |-- SubscriptionCheckout # Stripe payment page
| | | |-- SubscriptionSuccess # Post-payment confirmation
| | | +-- NotificationsPage # User notifications
| | |
| | |-- features/
| | | |-- student-dashboard/ # StudentDashboard (main student home)
| | | +-- admin-dashboard/ # AdminDashboard (main admin home)
| | |
| | |-- services/ # API service layer
| | | |-- api.js # Base API configuration and callable function wrappers
| | | |-- apiService.js # Extended API service
| | | |-- authService.js # Authentication logic (login, signup, logout, role routing)
| | | |-- chatService.js # Real-time chat operations
| | | |-- courseService.js # Course CRUD operations
| | | +-- feedbackService.js # Feedback submission
| | |
| | |-- redux/
| | | |-- store.js # Redux store configuration
| | | +-- slices/authSlice.js # Auth state slice
| | |
| | |-- context/
| | | +-- AuthContext.jsx # Authentication context provider
| | |
| | |-- hooks/ # Custom React hooks
| | | |-- useChat.js # Chat messaging hook
| | | |-- useChatList.js # Chat list with real-time updates
| | | |-- useAutoLogout.js # Auto-logout for students
| | | |-- useTutorAutoLogout.js# Auto-logout for tutors
| | | +-- useUnreadNotifications.js
| | |
| | |-- config/
| | | |-- firebase.js # Firebase initialization + emulator config
| | | +-- stripe.js # Stripe initialization
| | |
| | |-- utils/ # Validation, test utilities
| | |-- data/ # Test/seed data
| | |-- App.jsx # Root component with routing
| | +-- main.jsx # Entry point
| |
| |-- tailwind.config.js
| +-- vite.config.js
|
|-- functions/ # Backend (Firebase Cloud Functions)
| |-- index.js # Function exports (entry point)
| |-- src/
| | |-- controllers/ # HTTP handlers (14 controller files)
| | | |-- aiController.js # AI analysis endpoints
| | | |-- availability.controller.js
| | | |-- ban.controller.js # Ban/unban user
| | | |-- booking.controller.js
| | | |-- chat.controller.js
| | | |-- feedback.controller.js
| | | |-- note.controller.js # Tutor private notes
| | | |-- payment.controller.js# Stripe payments
| | | |-- payout.controller.js # Stripe Connect payouts
| | | |-- recording.controller.js # Agora cloud recording
| | | |-- report.controller.js
| | | |-- session.controller.js# Join/complete session + token generation
| | | |-- tutor.controller.js # Approve/reject tutor
| | | +-- user.controller.js # User profile, role assignment
| | |
| | |-- services/ # Business logic (14 service files)
| | |-- repositories/ # Data access layer (9 repository files)
| | |-- middleware/ # auth.middleware.js, reportValidation.js
| | |-- utils/ # constants.js, errors.js, firebase.js
| | |-- config/ # firebase.js, swagger.config.js
| | |-- swagger.js # Swagger UI Express endpoint
| | +-- videoOnUploadHandler.js # Firebase Storage trigger for video processing
| +-- tools/ # Dev tools (token generators for testing)
|
|-- docs/ # Documentation
| |-- firestore-schema.md # Complete database schema with TypeScript interfaces
| +-- tutor-approval-flow.md # Detailed approval workflow with sequence diagrams
|
|-- scripts/ # Database seeding
| |-- seed-firestore.js # Emulator seed script
| |-- seed-production.js # Production seed script
| +-- seed-data.json # Seed data (50KB+)
|
|-- tests/ # Test checklist
|-- firestore.rules # Firestore security rules (460+ lines)
|-- firestore.indexes.json # Composite index definitions
|-- storage.rules # Firebase Storage security rules
|-- firebase.json # Firebase project configuration
+-- .firebaserc # Firebase project alias
The application uses Cloud Firestore with the following collection hierarchy:
users/{userId}
|-- slots/{slotId} # Tutor availability time slots
|-- feedback/{feedbackId} # Student reviews for this tutor
|-- private_info/{docId} # Verification docs, wallet, payout details
|-- notifications/{notificationId} # Per-user notifications
+-- students_management/{studentId} # Tutor's student management data
bookings/{bookingId} # Lesson bookings (student <-> tutor)
courses/{courseId}
+-- lessons/{lessonId} # Structured lesson content
chats/{chatId}
+-- messages/{messageId} # Real-time chat messages
private_notes/{noteId} # Tutor's private notes about students
transcripts/{transcriptId} # Session transcription (system-generated)
AI_feedbacks/{feedbackId} # AI analysis results (system-generated)
reports/{reportId} # User/content violation reports
payouts/{payoutId} # Tutor payout requests
plan/{planId} # Subscription plan definitions
subscription_order/{orderId} # Subscription purchase records
admin_logs/{logId} # Audit trail (system-generated)
Detailed TypeScript interfaces for every collection are documented in docs/firestore-schema.md.
- Firebase Authentication handles user identity
- Supports email/password registration and Google OAuth
- JWT tokens carry custom claims for role verification
- Separate login flows for students, tutors, and admins
The system enforces a four-role model:
| Role | Description | Capabilities |
|---|---|---|
student |
Registered learner | Book lessons, join sessions, leave feedback, subscribe |
guest |
Unverified tutor applicant | View/edit own profile, submit verification documents, wait for approval |
tutor |
Verified teacher | All guest capabilities plus: create courses, set availability, manage students, request payouts |
admin |
Platform administrator | Full access: approve/reject tutors, ban users, moderate content, manage finances |
- 460+ lines of Firestore security rules enforce data access at the database level
- Non-admin users cannot modify their own role or ban status
- Guest tutors cannot create courses, slots, or request payouts
- Banned users cannot create bookings, send messages, or submit reports
- Transcripts and AI feedback are immutable (system-generated only)
- Admin audit logs are write-protected (Cloud Functions only)
The backend exposes 30+ Cloud Functions organized by domain:
| Domain | Functions | Description |
|---|---|---|
| User | assignRole, getProfile, setAdminClaim |
User profile and role management |
| Booking | createBooking, cancelBooking |
Lesson booking lifecycle |
| Availability | setupAvailability |
Tutor schedule management |
| Session | joinSession, completeSession |
Live session management with Agora token generation |
| Recording | acquireRecordingResource, startCloudRecording, stopCloudRecording, getRecordingInfo |
Agora cloud recording control |
| AI | analyzeRecording |
Post-session AI analysis via Google Gemini |
| Video | onVideoUpload |
Storage trigger for video processing (FFmpeg) |
| Chat | createOrGetChat, sendMessage, markMessagesAsRead |
Real-time messaging |
| Feedback | createFeedback |
Student reviews with validation |
| Tutor Mgmt | approveTutor, rejectTutor |
Admin tutor verification workflow |
| User Mgmt | banUser, unbanUser |
Admin user moderation |
| Reports | createReport, resolveReport |
Content/user report system |
| Payments | createPaymentIntent, handleWebhook |
Stripe subscription payments |
| Payouts | createConnectAccount, checkAccountStatus, requestPayout, approvePayout, rejectPayout |
Stripe Connect tutor payouts |
| Docs | swagger |
Swagger UI API documentation endpoint |
All functions are deployed to the asia-southeast1 region with a maximum instance limit of 10 for cost control.
| Path | Page |
|---|---|
/ |
Landing page (Hero, Features, Pricing, Tutor showcase) |
/login |
Student login |
/signup |
Student registration |
/forgot-password |
Password reset |
/tutor/login |
Tutor login |
/tutor/signup |
Tutor registration |
/admin/login |
Admin login |
| Path | Page |
|---|---|
/student-dashboard |
Student home with upcoming bookings and stats |
/tutors |
Tutor search and discovery with filters |
/tutors/:tutorId |
Tutor profile, reviews, availability, and booking |
/courses |
Course catalog |
/courses/:courseId |
Course detail with lesson list |
/calendar |
Student booking calendar view |
/profile |
Student profile management |
/recording/:bookingId |
Session recording playback and AI analysis results |
/notifications |
Notification center |
/subscription-checkout |
Stripe payment page |
/room |
Live video session room |
| Path | Page |
|---|---|
/tutor/dashboard |
Tutor home with earnings, schedule, and stats |
/tutor/apply |
Tutor application form (CV, certificates upload) |
/tutor/wait-for-permit |
Pending approval status page (guest only) |
/tutor/schedule |
Availability slot management |
/tutor/students |
Student list management |
/tutor/students/:id |
Individual student detail with private notes |
/tutor/profile |
Tutor profile view |
/tutor/profile/edit |
Profile editor |
| Path | Page |
|---|---|
/admin/dashboard |
Platform statistics overview |
/admin/students |
Student management (view, ban, unban) |
/admin/tutors |
Tutor management (approve, reject, ban) |
/admin/moderation |
Report review and resolution |
/admin/finance |
Payout management and financial overview |
/admin/courses |
Platform-wide course management |
/admin/courses/create |
Create new course |
/admin/courses/:courseId/edit |
Edit existing course |
- Video and audio calling for live tutoring sessions
- Cloud recording for session playback
- Token generation on the server side for secure channel access
- Stripe Checkout -- Subscription plan payments for students
- Stripe Connect -- Tutor payout management with onboarding, account verification, and fund transfers
- Webhooks -- Server-side payment event handling
- Post-session analysis of recorded audio/video
- Scoring across four dimensions: vocabulary, grammar, fluency, pronunciation
- Detailed feedback with specific corrections and suggestions
- Real-time interactive whiteboard during live sessions
- Shared drawing canvas between tutor and student
- Node.js 20+
- npm
- Firebase CLI (
npm install -g firebase-tools) - A Firebase project with Authentication, Firestore, Storage, and Functions enabled
- Clone the repository:
git clone <repository-url>
cd SpeakBridge- Install root dependencies:
npm install- Install client dependencies:
cd client && npm install && cd ..- Install functions dependencies:
cd functions && npm install && cd ..-
Set up environment variables (see Environment Variables).
-
Start the Firebase emulators and dev server:
# Terminal 1: Start emulators
npm run emulator
# Terminal 2: Start frontend dev server
npm run dev- Seed the emulator database (optional):
npm run seedVITE_FIREBASE_API_KEY=
VITE_FIREBASE_AUTH_DOMAIN=
VITE_FIREBASE_PROJECT_ID=
VITE_FIREBASE_STORAGE_BUCKET=
VITE_FIREBASE_MESSAGING_SENDER_ID=
VITE_FIREBASE_APP_ID=
VITE_USE_EMULATORS=true
VITE_STRIPE_PUBLISHABLE_KEY=
VITE_AGORA_APP_ID=
STRIPE_SECRET_KEY=
STRIPE_WEBHOOK_SECRET=
AGORA_APP_ID=
AGORA_APP_CERTIFICATE=
GEMINI_API_KEY=
NETLESS_ACCESS_KEY=
NETLESS_SECRET_KEY=
| Command | Description |
|---|---|
npm run dev |
Start Vite dev server (client) |
npm run build |
Build client for production |
npm run emulator |
Start Firebase emulators |
npm run emulator:import |
Start emulators with imported data |
npm run emulator:export |
Export emulator data |
npm run seed |
Seed Firestore emulator with test data |
npm run deploy |
Deploy everything to Firebase |
npm run deploy:functions |
Deploy Cloud Functions only |
npm run deploy:rules |
Deploy Firestore security rules only |
npm run deploy:indexes |
Deploy Firestore indexes only |
The backend API is documented using Swagger/OpenAPI 3.0. When running locally, access the documentation at:
http://127.0.0.1:5001/<project-id>/asia-southeast1/swagger/api-docs
The Swagger UI supports:
- Interactive "Try it out" for all endpoints
- Bearer token authentication input
- Request/response schema visualization
- Exportable OpenAPI JSON at
/swagger.json