Core Entities
Course: course_id, title, description, instructor_id, category, level (BEGINNER, INTERMEDIATE, ADVANCED), language, price, published_at, status (DRAFT, PUBLISHED, ARCHIVED), total_enrolled. Lesson: lesson_id, course_id, title, content_type (VIDEO, ARTICLE, QUIZ), content_url, duration_seconds, order_index, is_free_preview. Enrollment: enrollment_id, student_id, course_id, enrolled_at, completed_at (nullable), completion_percentage, last_accessed_at, status (ACTIVE, COMPLETED, REFUNDED). LessonProgress: progress_id, enrollment_id, lesson_id, status (NOT_STARTED, IN_PROGRESS, COMPLETED), completed_at, watch_position_seconds (for videos). Certificate: cert_id, enrollment_id, student_id, course_id, issued_at, verification_code (UUID), credential_url.
Course Enrollment and Access Control
class EnrollmentService:
def enroll(self, student_id: int, course_id: int, payment_intent_id: str) -> Enrollment:
# Idempotency: check existing enrollment
existing = self.db.get_enrollment(student_id, course_id)
if existing and existing.status == EnrollmentStatus.ACTIVE:
return existing
course = self.db.get_course(course_id)
if course.status != CourseStatus.PUBLISHED:
raise CourseNotAvailableError()
# Verify payment
if course.price > 0:
payment = self.payment.verify(payment_intent_id, course.price)
if not payment.succeeded:
raise PaymentError()
enrollment = Enrollment(
student_id=student_id,
course_id=course_id,
enrolled_at=datetime.now(),
status=EnrollmentStatus.ACTIVE
)
self.db.save(enrollment)
self.db.increment_course_enrollment_count(course_id)
self.email.send_welcome(student_id, course_id)
return enrollment
def can_access_lesson(self, student_id: int, lesson_id: int) -> bool:
lesson = self.db.get_lesson(lesson_id)
if lesson.is_free_preview:
return True
enrollment = self.db.get_enrollment(student_id, lesson.course_id)
return enrollment is not None and enrollment.status == EnrollmentStatus.ACTIVE
Progress Tracking
Track lesson-level progress: when a student watches a video, the client sends periodic progress pings every 30 seconds: {enrollment_id, lesson_id, watch_position_seconds}. Update LessonProgress.watch_position_seconds (allows resuming from where they left off). Mark lesson as COMPLETED when: video watched > 90% of duration, article scrolled to the bottom, quiz score >= passing threshold. Course completion calculation: completion_percentage = completed_lessons / total_lessons * 100. Recalculate and update Enrollment.completion_percentage on each lesson completion. Mark Enrollment.status = COMPLETED and issue a certificate when completion_percentage = 100.
Certificate Issuance and Verification
On course completion: generate a Certificate record with a unique verification_code (UUID v4). Generate a PDF certificate using a template (student name, course title, completion date, instructor name). Upload to S3, store the URL in Certificate.credential_url. Send the certificate URL to the student via email. Verification page: GET /verify/{verification_code} — look up the certificate by verification_code, display the student name, course, and completion date. This allows employers to verify authenticity. LinkedIn integration: provide a “Add to LinkedIn” URL that pre-populates the certification in the student’s LinkedIn profile (LinkedIn supports a URL scheme for this). Signed certificates: embed a digital signature in the PDF using the platform’s private key, verifiable with the public key — prevents forgery.
Course Search and Recommendations
Search: Elasticsearch index with course title, description, instructor name, and tags. Full-text search with relevance scoring. Filters: category, level, language, price (free vs paid), rating. Sort by: relevance, enrollment count, rating, date. Recommendations: collaborative filtering (students who enrolled in course A also enrolled in course B) — store co-enrollment matrix, updated nightly. Content-based filtering: if a student completed 3 Python courses, recommend more Python courses. Implement with a user-item matrix: rows are students, columns are courses, values are engagement score (completed=1, in_progress=0.5). Matrix factorization (SVD) gives latent factors for recommendation. For cold start (new student, no history): recommend top-rated courses in their declared interest areas (onboarding survey).
Video Delivery
Store course videos in S3. Transcode to multiple resolutions on upload (720p, 1080p) — trigger a Lambda on S3 upload. Generate HLS manifests for adaptive streaming. Serve through a CDN (CloudFront) — students worldwide get low-latency playback. Access control: pre-signed CDN URLs or signed cookies scoped to the student’s enrollment. The URL expires after 24 hours; the client refreshes via an API call. Never serve video through the application server — always directly from the CDN. For large video files: multipart upload to S3 so instructors can upload 2GB+ files without timeout. Progress tracking pings go to the application server, not the CDN.
Asked at: LinkedIn Interview Guide
Asked at: Atlassian Interview Guide
Asked at: Shopify Interview Guide
Asked at: Snap Interview Guide