Description
Course Flow is a backend-first Learning Management System (LMS) built to support real-world educational platforms. The system handles user authentication, course management, payments, media uploads, and notifications with a strong focus on security, scalability, and maintainability.
The project is structured using clean architecture principles, separating routing, validation, business logic, and data access to ensure long-term extensibility and team scalability.
Tech Stack
- Runtime: Node.js
- Language: TypeScript
- Framework: Express.js
- Database: MongoDB with Mongoose ODM
- Authentication: JWT (access & refresh tokens)
- File Storage: Cloudinary
- Payments: Razorpay, Stripe
- Email: Resend
- Validation: Zod
- Logging: Winston
- Security: Helmet, Rate Limiting, HPP, XSS protection
Key Features
- Role-Based Authentication — Secure JWT-based auth for students, instructors, and admins.
- Course Management APIs — Create, update, publish, and manage courses with structured data models.
- Payment Integration — Secure course purchases using Razorpay and Stripe with server-side verification.
- Media Uploads — Cloudinary-based handling for course thumbnails and assets.
- Email Notifications — Transactional emails for onboarding, payments, and system events.
- Robust Validation Layer — Strong request validation using Zod schemas.
- Centralized Logging — Structured logging with Winston for easier debugging and monitoring.
Architecture & API Flow
The backend follows a layered architecture to keep responsibilities clear:
- Routes — Define API endpoints
- Validations — Validate request payloads with Zod
- Controllers — Handle HTTP-level logic
- Services — Contain core business logic
- Models — Interact with MongoDB via Mongoose
This separation ensures cleaner code, easier testing, and safer refactors.
Challenges & Solutions
1. Designing a Scalable Backend Structure
Challenge: Preventing tight coupling as the feature set grows.
Solution: Adopted a controller–service–model pattern with strict boundaries, enabling independent feature development and easier maintenance.
2. Securing APIs Against Common Attacks
Challenge: Protecting the system from brute force, injection, and malformed requests.
Solution: Implemented layered security using Helmet, rate limiting, input sanitization, HPP protection, and strict schema validation with Zod.
3. Reliable Payment Verification
Challenge: Ensuring payment authenticity and preventing fraud.
Solution: Used server-side payment verification for Razorpay and Stripe webhooks before granting course access.
4. Handling File Uploads at Scale
Challenge: Efficiently storing and serving media without overloading the backend.
Solution: Offloaded uploads to Cloudinary, keeping the backend stateless and performant.
What I Learned
- Designing production-grade backend architectures with TypeScript and Express.
- Implementing secure authentication and payment flows.
- Writing defensive APIs with strong validation and security layers.
- Structuring large Node.js codebases for scalability and long-term maintainability.