
Sharaf ul Quran
Full-stack Islamic education platform connecting students with Quran teachers (Qaris): one-time and monthly booking, course enrollment with Stripe, Google Meet, Fireflies.ai recording, and admin oversight.
Executive Summary
Case Study Overview
Sharaf ul Quran is a full-stack Islamic education platform connecting students with Quran teachers (Qaris). This case study covers the architecture for one-time and monthly booking, course enrollment with Stripe, Google Meet integration, Fireflies.ai recording, and comprehensive admin oversight.
The Challenge
The platform needed to coordinate students, Qaris, and admins across registration, payment handling, session scheduling with meeting links, and access control to learning resources. Students needed to find Qaris, book sessions, and pay; Qaris needed onboarding, availability setup, and earnings tracking; admins needed approval workflows and enrollment management.
The Approach
Dual backends (main + admin) with shared PostgreSQL and role-separated auth. Webhook-driven Stripe payment confirmation, idempotent course payment handling, and an enrollment state machine (pending_approval → approved_unpaid → active → completed). Session notification cron, in-memory admin stats cache with TTL, and resource gating based on paid bookings.
Key Deliverables
Student/Qari registration with admin approval, one-time and monthly booking with Google Meet, course enrollment with slot assignment, Fireflies.ai meeting recordings, and a comprehensive admin panel for oversight and analytics.
Want to dive deeper? Explore the full technical case study with architecture diagrams, implementation details, and outcomes.
Problem
The Challenge
Context
Platform for Quran education requiring coordination between students, Qaris, and admins; payment handling; session scheduling with meeting links; and access control to learning resources.
User Pain Points
Students need to find Qaris, book sessions, pay, and access resources
Qaris need onboarding approval, availability setup, earnings tracking, resource uploads
Admins need to approve onboarding, manage enrollments, assign slots, view stats
Why Existing Solutions Failed
Existing solutions did not provide the combined workflow of onboarding, booking, course enrollment, and resource gating in one platform.
Goals & Metrics
What We Set Out to Achieve
Objectives
- 01Student/Qari registration and role-based onboarding with admin approval
- 02One-time and monthly session booking with Stripe and Google Meet
- 03Course enrollment with admin slot assignment and monthly payments
- 04Resource sharing gated by paid bookings; meeting recordings via Fireflies
- 05Admin panel for oversight, stats, and management
Success Metrics
- 01Dual backends (main + admin) with shared PostgreSQL and role-separated auth
- 02Webhook-driven payment confirmation and idempotent course payment handling
- 03Enrollment state machine (pending_approval → approved_unpaid → active → completed)
- 04Session notification cron; in-memory admin stats cache with TTL
User Flow
User Journey
Landing → Register (student/Qari) → Onboarding → Admin review → Booking (one-time/monthly) or Course enrollment → Portal access; Qari uploads resources; Student accesses resources for Qaris with paid bookings.
Architecture
System Design
Two frontends (main: Student + Qari; admin: dashboard) and two Express backends sharing one PostgreSQL (Neon). Main backend: auth, calendar, payment, resources, courses, monthly booking, Socket.io, cron. Admin backend: admin auth, Qari/student management, stats. External: Stripe, Google Calendar, Fireflies, SMTP, WhatsApp.
What This Diagram Represents
The full topology of Sharaf ul Quran: main and admin frontends, main and admin backends, PostgreSQL, and external systems (Stripe, Google Calendar, Fireflies, SMTP, WhatsApp, Socket.io). It shows which components exist and how they are grouped (frontend, backend, db, external).
How to Read the Flow
Key Engineering Decisions
Layer Breakdown
Frontend
Backend
Data
External
Security
Authentication & Authorization Flow
JWT in httpOnly cookie with role-based backend separation; main backend rejects admin tokens. Email/password and OAuth (Google, Facebook); profile endpoint for cookie clients.
What This Diagram Represents
The path from user action (register, login, OAuth callback) through backend verification and token issuance to role-based redirect and subsequent authenticated requests. Includes branches for email/password vs OAuth and for student/Qari vs admin.
How to Read the Flow
Key Engineering Decisions
Core Feature
One-Time Booking Lifecycle
From slot selection to PaymentIntent, webhook confirmation, Google Meet link creation, and email/WhatsApp notifications.
What This Diagram Represents
One-time booking flow: student → slot selection → payment → webhook → Meet + notifications. Nodes are steps or systems; edges are "next step" or "sends to".
How to Read the Flow
Key Engineering Decisions
Core Feature
Course Enrollment Lifecycle
Submit → admin approval → slot assignment → payment → idempotent webhook → state machine → course_sessions.
What This Diagram Represents
Course enrollment flow: enroll → admin approval → payment → webhook → state machine → sessions. Shows state transitions and idempotent webhook handling.
How to Read the Flow
Key Engineering Decisions
Data Flow
How Data Moves
Frontend → Backend (auth, booking, enrollment); Backend → Stripe (PaymentIntent); Stripe/Fireflies → Backend (webhooks); Backend → PostgreSQL, Google Calendar, SMTP, WhatsApp; Backend → Frontend via Socket.io.
Data Flow
Data Processing Flow
Frontend ↔ Backend ↔ PostgreSQL; Backend ↔ Stripe, Google, SMTP, WhatsApp; Fireflies → Backend; Backend → Frontend via Socket.io.
What This Diagram Represents
Movement of data between Frontend, Backend, PostgreSQL, Stripe, Google Calendar, SMTP, WhatsApp, and Fireflies. Emphasizes who sends what and on what trigger.
How to Read the Flow
Key Engineering Decisions
Core Features
Key Functionality
Authentication
What it does
Email/password and OAuth (Google, Facebook); JWT in httpOnly cookie; role-based access.
Why it matters
Single user store; main backend rejects admin tokens for API separation.
Implementation
authController, authMiddleware, useAuth; bcrypt, cookie + Bearer fallback, profile endpoint.
Qari & Student Onboarding
What it does
Qaris/students submit details; admin approves or rejects.
Why it matters
Gates platform use and ensures verified teachers and student info.
Implementation
qari_onboarding, student_onboarding; availability JSONB; CNIC validation; admin routes.
One-Time Booking
What it does
Students book single sessions; Stripe payment; Google Meet; email/WhatsApp.
Why it matters
Core revenue and session delivery path.
Implementation
calendar_bookings; Stripe webhook as source of truth; googleMeet, emailService, whatsappService.
Monthly & Course Enrollment
What it does
Monthly plans (5/6 days) and multi-month courses; admin approval and slot assignment; Stripe.
Why it matters
Recurring engagement and subscription revenue.
Implementation
monthly_sessions, course_sessions; enrollment state machine; idempotent course webhook (webhook_events).
Resource Management
What it does
Qaris upload lessons/PDFs/videos; students access only with paid booking for that Qari.
Why it matters
Content gating and fair access.
Implementation
qari_resources; resourceAccessMiddleware checks calendar_bookings before serve.
Meeting Recordings (Fireflies)
What it does
Fireflies.ai records/transcribes; webhook and polling update meeting_recordings.
Why it matters
Post-session review and accountability.
Implementation
firefliesRoutes, firefliesService, firefliesWebhookHandlers, firefliesPolling job.
Admin Panel & Session Notifications
What it does
Admin dashboard (stats, management); cron sends email ~1h before sessions, creates Meet if missing.
Why it matters
Oversight and reduced no-shows.
Implementation
Admin-frontend/backend; adminStatsService (30s cache); monthlySessionNotificationJob (node-cron).
Performance
Performance & Decision Flow
Admin stats cache (hit/miss, TTL), rate limiting, resource access middleware, file streaming, and cron-driven session notifications.
What This Diagram Represents
Where performance and caching decisions are made: admin stats (cache hit vs miss, TTL 30s/2min), rate limiting (request → allow/block), resource serve (middleware check → allow/deny), and cron schedule (every 5 min → session notification job).
How to Read the Flow
Key Engineering Decisions
Technical Challenges
Problems We Solved
Why This Was Hard
express.json() parses body and breaks signature verification
Our Solution
Stripe and Fireflies webhook routes registered before express.json(); use express.raw() for those routes.
Why This Was Hard
Stripe can retry; multiple workers could process same event
Our Solution
webhook_events table; claimForProcessing atomic lock; mark processed/failed with retry count.
Why This Was Hard
Students should only access resources for Qaris they have paid bookings with
Our Solution
resourceAccessMiddleware extracts qariId from path; queries calendar_bookings; denies if no paid booking.
Why This Was Hard
Admin and student/qari share auth tables but different backends
Our Solution
Main backend explicitly rejects admin tokens; returns 403 and clears cookie.
Why This Was Hard
Meet creation uses OAuth; access token expires
Our Solution
GOOGLE_REFRESH_TOKEN in env; setCredentials with refresh_token; token refresh on use.
Engineering Excellence
Performance, Security & Resilience
Performance
- Admin stats in-memory cache with 30s–2min TTL
- PostgreSQL indexes on bookings, enrollments, payments, sessions, availability
- Connection pooling (pg); file streaming for certificates and resources
- Rate limiting (express-rate-limit)
Error Handling
- PostgreSQL 23505 (unique), 23503 (FK) in errorHandler
- Stripe/Fireflies webhook signature verification
- 401/403 for auth; course webhook returns 200 on processing error to avoid Stripe retry storms
Security
- JWT in httpOnly cookie; bcrypt; express-validator
- Resource access middleware for file serving; CORS; parameterized SQL (pg)
- Helmet in admin backend
Design Decisions
Visual & UX Choices
Auth and navigation
Rationale
Consistent experience across student and Qari portals
Details
Modal-based login/register; sidebar navigation; skeleton loaders during auth check; role-based redirects (Qari → /qari/overview, Student → /portal).
OAuth and onboarding
Rationale
Clear state and redirects
Details
OAuth callback cleans URL and fetches profile; onboarding status determines redirect (submitted → under-review, approved → dashboard). Legacy routes /wari → /qari, /qari/quran-resources → /qari/resources.
Impact
The Result
What We Achieved
Modular full-stack platform: two Express backends and two React frontends sharing one PostgreSQL and shared file store. Cookie-based JWT with role-based backend separation; webhook-driven Stripe payments with idempotent course handling and enrollment state machine; one-time and monthly booking plus course enrollment; Google Meet, Fireflies, email, WhatsApp; resource access gated by paid booking.
Who It Helped
Single team; implementation-accurate documentation from PROJECT_ANALYSIS and caseStudyData.
Why It Matters
Production-oriented system with clear boundaries, documented limitations (no tests, in-memory cache, Helmet off on main backend), and a path for improvements.
Reflections
Key Learnings
Technical Learnings
- Webhook raw body and express.raw(); idempotency via claimForProcessing; state machines for enrollment.
Architectural Insights
- Dual backend split for role isolation; single DB and shared uploads simplify operations.
What I'd Improve
- Enable Helmet on main backend; add tests; replace in-memory cache with Redis; retries/circuit breakers for external APIs.
Roadmap
Future Enhancements
Enable Helmet on main backend once CORS stable
Introduce automated tests (unit + integration)
Replace in-memory admin stats cache with Redis
Move credentials to secrets manager
Use dedicated STRIPE_WEBHOOK_SECRET_COURSES
Add structured retries and circuit breakers for external APIs
Clarify or complete Calendly integration
