Back to projects

Learning Management System (LMS)

ThriveCart·Product Engineer·
TypeScriptPrismaMySQLAWS S3CloudFrontRedis

Overview

A full-featured Learning Management System built as part of ThriveCart's product suite, enabling creators to host courses, manage enrollments, track learner progress, and deliver content securely at scale.

Role: Product Engineer — owning backend architecture, access control, file delivery, and analytics pipeline.

Problem

ThriveCart needed a first-party LMS that could handle thousands of concurrent learners, enforce granular access control per course/lesson, deliver large media files securely, and provide creators with real-time analytics — all without introducing operational complexity.

Constraints

  • Multi-tenant architecture: strict data isolation between creators
  • Large file delivery (video, PDF) with access-controlled URLs
  • Real-time progress tracking without overloading the primary database
  • RBAC that supports course-level, lesson-level, and time-gated access

Solution

Architecture Decisions

Domain Modeling: Designed a normalized schema for courses, modules, lessons, and enrollments using Prisma/MySQL. Each entity supports soft deletes, audit timestamps, and polymorphic content types.

RBAC: Implemented role-based access control with JWT + scoped permissions. Roles cascade from organization → course → lesson level, supporting time-gated and drip-scheduled access patterns.

File Delivery: AWS S3 for storage with CloudFront CDN. Presigned URLs with short TTLs ensure files are only accessible to authenticated, authorized learners. No direct S3 access is exposed.

Analytics Pipeline: Learner events (video play, lesson complete, quiz submit) are written to a Redis stream, consumed by a background processor, and aggregated into a reporting table. This avoids write amplification on the primary DB.

Deep Dives

Auth & Permissions Design

The RBAC system uses a hierarchical permission model:

  • Organization roles (admin, instructor, learner)
  • Course-level overrides (enrolled, auditing, blocked)
  • Lesson-level gates (drip schedule, prerequisite completion)

Permissions are resolved at request time via middleware, checking JWT claims against the course/lesson context. This keeps authorization logic centralized and testable.

Secure File Delivery

Media files are stored in S3 with bucket policies that deny all public access. Content is served exclusively through CloudFront with signed URLs:

  1. Client requests a lesson's media → API validates enrollment + permissions
  2. API generates a CloudFront signed URL (5-minute TTL)
  3. Client streams directly from CDN — no proxy through the application server

This pattern handles thousands of concurrent streams without backend bottleneck.

Analytics Event Pipeline

Instead of writing analytics directly to MySQL on every learner action:

  1. Events are published to a Redis stream (low-latency writes)
  2. A consumer process batches events and writes aggregates to a reporting table
  3. Creator dashboards query the aggregated data

This decouples the hot path (learner experience) from the analytical workload.

Results

  • Secure content delivery serving thousands of concurrent learners via CDN
  • Sub-100ms authorization checks via JWT + cached permission resolution
  • Analytics pipeline processing events without impacting primary database performance
  • Zero unauthorized file access incidents since launch

What I Learned

Building a multi-tenant LMS reinforced the importance of designing access control as a first-class concern rather than an afterthought. The presigned URL pattern for file delivery is broadly applicable to any system that needs secure, scalable content distribution.