Skip to content

Enterprise-Grade Learning Management System with Terminal Aesthetic

Notifications You must be signed in to change notification settings

codezelat/cca-lms

Β 
Β 

Repository files navigation

πŸŽ“ Codezela Career Accelerator - LMS

Next.js TypeScript Prisma PostgreSQL React

Production-Ready Learning Management System by Codezela Technologies

Developed with ❀️ by Codezela Technologies

Features β€’ Tech Stack β€’ Getting Started β€’ Documentation β€’ Architecture


πŸ“‹ Table of Contents


🎯 Overview

Codezela Career Accelerator LMS is a comprehensive, enterprise-grade Learning Management System designed for modern educational institutions, corporate training programs, and online academies. Built with cutting-edge technologies and featuring a sleek terminal-inspired aesthetic, it delivers a complete end-to-end learning experience.

Why Choose CCA LMS?

βœ… Production-Ready - Battle-tested with real users, zero downtime deployments
βœ… Type-Safe - 100% TypeScript with Prisma-generated types
βœ… Secure by Design - Row-Level Security, audit logging, NextAuth v5
βœ… Performance Optimized - Turbopack bundling, React Server Components, edge runtime
βœ… Fully Featured - Quiz system, multi-format resources, bulk enrollment, analytics
βœ… Responsive Design - Mobile-first UI that works on all devices
βœ… SEO Protected - robots.txt and meta tags configured for privacy
βœ… Google Analytics - Built-in tracking and insights

What Makes It Unique?

  • Terminal Aesthetic - Dark green on black theme inspired by classic terminals
  • Intelligent Content Rendering - Automatically detects and embeds YouTube, Vimeo videos
  • Admin-Controlled Enrollment - No self-service enrollment, full admin control
  • Bulk CSV Enrollment - Upload hundreds of students instantly
  • Real-time Progress Tracking - Live lesson completion and quiz scores
  • Multi-Format Resources - Videos, PDFs, links, embedded content, rich text notes

✨ Features

πŸ“š Content Management

Programme Structure

  • Three-Tier Hierarchy: Programmes β†’ Modules β†’ Lessons
  • Drag-and-Drop Reordering: Intuitive content organization
  • Status Management: Draft, Published, Archived states
  • Visibility Controls: Schedule content release dates
  • Enrollment Tracking: Real-time capacity monitoring
  • Bulk Operations: Mass student enrollment via CSV

Lesson Types

The system supports diverse lesson formats:

  1. Video Lessons

    • Direct video file uploads to Cloudflare R2
    • YouTube Integration - Automatic embed detection
    • Vimeo Integration - Native player embedding
    • HTML5 video player with progress tracking
    • Auto-mark complete on video end
  2. Rich Text Content

    • Full HTML support with custom styling
    • Code syntax highlighting
    • Tables, lists, blockquotes
    • Image embedding
    • Terminal-themed typography
  3. Interactive Quizzes

    • Multiple choice questions
    • True/False questions
    • Short answer (manual grading)
    • Essay questions (manual grading)
  4. Resource-Based Lessons

    • Multiple attachments per lesson
    • Mix and match content types
    • Scheduled availability

πŸ‘₯ User Roles

πŸ”‘ Administrator

Full System Control:

  • User Management
    • Create, edit, delete users (students, lecturers, admins)
    • Bulk CSV enrollment with validation
    • Download enrollment templates
    • Account status management (Active, Suspended, Deleted)
    • Password reset capabilities
  • Programme Management
    • Create/edit/delete programmes
    • Module and lesson organization
    • Content visibility controls
    • Enrollment capacity settings
  • Analytics Dashboard
    • Total users, programmes, enrollments
    • Recent activity logs
    • System-wide statistics
    • 20+ action types tracked
  • Audit Logging
    • Every user action logged with metadata
    • IP address and user agent tracking
    • Timestamps and entity references
    • Filterable audit trail

πŸ‘¨β€πŸ« Lecturer

Content Creation & Student Management:

  • Programme Development
    • Create and publish programmes
    • Build multi-module courses
    • Upload video content
    • Add lesson resources
  • Quiz Management
    • Visual quiz builder (673 lines of code)
    • 4 question types supported
    • Automatic and manual grading
    • Result analytics
  • Student Oversight
    • View enrolled students
    • Track individual progress
    • Grade text-based submissions
    • Generate progress reports
  • Resource Library
    • Upload files (20MB limit)
    • Create rich text notes
    • Add external links
    • Embed videos/iframes

πŸŽ“ Student

Learning Experience:

  • Programme Access
    • View assigned programmes only (admin-controlled)
    • No self-enrollment capability
    • Progress tracking dashboard
    • Recently accessed lessons
  • Lesson Interaction
    • Watch videos (YouTube/Vimeo/direct)
    • Read text content
    • Download resources
    • Mark lessons complete
  • Quiz Taking
    • Timed quiz attempts
    • Question navigation
    • Save and resume support
    • Instant score feedback
  • Progress Monitoring
    • Completion percentages
    • Quiz scores and attempts
    • Learning activity history
    • Achievement tracking

🎯 Assessment System

Quiz Builder (Lecturer/Admin)

Comprehensive quiz creation tool with:

Question Types:

  1. Multiple Choice

    • Single correct answer
    • Radio button interface
    • Up to 10 answer options
    • Point value configuration
    • Explanation field for feedback
  2. True/False

    • Binary questions
    • Toggle-based selection
    • Quick grading
    • Explanation support
  3. Short Answer

    • Text input field
    • Manual grading required
    • 20 character limit
    • Rubric support
  4. Essay Questions

    • Long-form responses
    • Rich text area
    • Manual grading workflow
    • Detailed feedback options

Quiz Settings:

  • Time Limit: Set duration in minutes (0 = unlimited)
  • Passing Score: Define threshold percentage
  • Attempts: Limit number of tries
  • Question Shuffling: Randomize question order
  • Answer Shuffling: Randomize answer order (MC only)
  • Show Correct Answers: Display after submission
  • Immediate Results: Show score instantly

Grading Features:

  • Auto-grading for MC and T/F (instant results)
  • Manual grading interface for text responses
  • Partial credit support
  • Bulk grading capabilities
  • Score analytics and statistics

Quiz Player (Student)

Optimized quiz-taking experience:

  • Visual Timer: Countdown with color-coded alerts
  • Progress Tracker: Question completion indicator
  • Smart Navigation: Jump to any question
  • Auto-Save: Progress saved every 30 seconds
  • Visual Feedback: Answered vs unanswered highlighting
  • Results Display:
    • Total score and percentage
    • Pass/Fail indicator
    • Question-by-question breakdown
    • Correct answer reveal (if enabled)
    • Explanation display

Assignment System (File Submission)

Comprehensive assignment management for file-based submissions:

Assignment Creation (Admin/Lecturer):

  • Rich Instructions: Full text editor for detailed requirements
  • Due Date Management: UTC-based deadline with timezone handling
  • Late Submission Control: Toggle to allow/deny late submissions
  • File Restrictions:
    • Configurable allowed file types (PDF, DOCX, images, etc.)
    • Maximum file size limit (configurable, default 10MB)
    • Maximum number of files per submission
  • Point System: Set maximum points for grading

Student Submission:

  • Drag & Drop Upload: Modern dropzone interface
  • Multi-File Support: Submit multiple files per assignment
  • Submission Notes: Optional text notes with submission
  • Status Tracking: Draft, Submitted, Graded states
  • Download Own Files: Access submitted files anytime
  • Deadline Awareness: Real-time countdown and status indicators

Grading Interface (Admin/Lecturer):

  • File Preview: Download and view submitted files
  • Grade Entry: Numeric grade with max points validation
  • Feedback Field: Detailed text feedback for students
  • Late Indicator: Visual badge for late submissions
  • Grade History: Track when submissions were graded

Bulk Submission Actions:

  • Export to Excel: Comprehensive XLSX report with 3 sheets:
    • Submissions Sheet: Full details including student info, grades, file download links
    • All Files Sheet: Every submitted file with download links
    • Summary Report: Statistics (total, graded, pending, late, averages)
  • Bulk Download ZIP: Download all submission files as organized ZIP
    • Batched downloads (5 files at a time) to prevent server overload
    • Progress indicator with current file, batch progress, and completion status
    • Cancel button for long downloads
    • Files organized by student folders: StudentName_email/filename.pdf

Secure File Downloads:

  • Proxy Download Endpoint: All downloads go through /api/download/
  • Branded URLs: Users see your domain, not Backblaze/R2 URLs
  • Permission Verification: Every download checks authentication
  • Streaming Response: Memory-efficient, handles large files
  • 1-Hour Cache: Optimized for repeated downloads

πŸ“ Resource Library

Supported Resource Types

  1. FILE Upload (Cloudflare R2)

    • Supported Formats: PDF, DOCX, XLSX, PPT, images, videos, archives
    • File Size Limit: 20MB per file
    • Drag & Drop: Modern upload interface with progress bars
    • Signed URLs: Secure downloads with 1-hour expiry
    • Version Control: Complete upload history
    • Metadata: Filename, MIME type, file size tracking
  2. EXTERNAL_LINK

    • Link to any web resource
    • Documentation sites
    • Online articles
    • Reference materials
    • Opens in new tab
  3. EMBEDDED Content

    • YouTube videos (auto-detection)
    • Vimeo videos (auto-detection)
    • Custom iframe embeds
    • Interactive content (CodePen, JSFiddle)
    • Google Forms/Slides
    • Aspect-ratio responsive containers
  4. TEXT_NOTE

    • Rich HTML content
    • Custom terminal-themed prose styling
    • Syntax-highlighted code blocks
    • Markdown-style formatting
    • Tables and lists
    • Embedded images

Resource Management Features

  • Drag-and-Drop Reordering: Change resource sequence
  • Visibility Controls:
    • PUBLIC: Visible to all enrolled students
    • SCHEDULED: Visible after specific date/time
    • HIDDEN: Accessible only to lecturers/admins
  • Downloadable Toggle: Enable/disable download button
  • Edit Metadata: Update title, description, visibility
  • Version History: Track all resource changes
  • Bulk Actions: Delete multiple resources
  • Preview Support: View before publishing

πŸ” Security & Compliance

Authentication & Authorization

  • NextAuth v5: Industry-standard authentication
  • JWT Tokens: Secure session management (30-day expiry)
  • bcrypt Hashing: Password security with 12 salt rounds
  • HTTP-Only Cookies: XSS attack prevention
  • CSRF Protection: Built-in Next.js security
  • Role-Based Access: Enforced at API and UI levels

Database Security

  • Row-Level Security (RLS): PostgreSQL policies on all 15 tables
  • Prepared Statements: Prisma prevents SQL injection
  • Connection Pooling: Optimized database connections
  • Encrypted Connections: SSL/TLS for all database traffic
  • Automated Backups: Daily full database backups to Cloudflare R2

Backup & Recovery

  • Daily Automated Backups: Full database export via Vercel Cron at 2:00 AM UTC
  • 14-Day Retention: Automatic cleanup of older backups
  • Compressed Storage: Gzipped JSON backups (~85% size reduction)
  • Secure Storage: Private R2 bucket, no public access
  • Audit Logged: All backup operations tracked (BACKUP_CREATED, BACKUP_FAILED, BACKUP_CLEANUP)
  • Easy Restore: CLI script for disaster recovery

File Security

  • Type Validation: MIME type checking
  • Size Limits: 20MB hard cap
  • Virus Scanning: Cloudflare security features
  • Signed URLs: Expiring download links (1 hour)
  • Access Control: File access tied to enrollment

Audit Logging

Every action tracked with:

  • User ID and role
  • Action type (20+ types)
  • Entity type and ID
  • Metadata (JSON)
  • IP address
  • User agent
  • Timestamp

Tracked Actions:

  • USER_CREATED, USER_UPDATED, USER_DELETED
  • PROGRAMME_CREATED, PROGRAMME_UPDATED, PROGRAMME_DELETED
  • MODULE_CREATED, MODULE_UPDATED, MODULE_DELETED, MODULE_REORDERED
  • LESSON_CREATED, LESSON_UPDATED, LESSON_DELETED, LESSON_REORDERED
  • QUIZ_CREATED, QUIZ_UPDATED, QUIZ_DELETED
  • RESOURCE_UPLOADED, RESOURCE_UPDATED, RESOURCE_DELETED
  • ENROLLMENT_CREATED, ENROLLMENT_DELETED
  • BULK_ENROLLMENT_STARTED, BULK_ENROLLMENT_COMPLETED
  • BACKUP_CREATED, BACKUP_FAILED, BACKUP_CLEANUP, BACKUP_RESTORED

SEO & Privacy

  • robots.txt: Blocks all search engines (Google, Bing, DuckDuckGo)
  • Meta Tags: noindex, nofollow on all pages
  • Open Graph: Disabled for privacy
  • Google Analytics: G-S1F397DHHS (configurable)
  • No Public Indexing: LMS content stays private

πŸ“Š Analytics & Reporting

Admin Dashboard

  • Total registered users (by role)
  • Active programmes and enrollments
  • System activity timeline
  • Storage usage statistics
  • Quiz completion rates

Lecturer Dashboard

  • My programmes overview
  • Student enrollment counts
  • Lesson completion rates
  • Quiz score averages
  • Recent student activity

Student Dashboard

  • Enrolled programmes (admin-assigned only)
  • Progress percentages
  • Recently accessed lessons
  • Upcoming quizzes
  • Completed assessments

πŸ›  Tech Stack

Core Framework

Technology Version Purpose
Next.js 16.1.4 React framework with App Router
React 19.0.2 UI library with Server Components
TypeScript 5.7 Type safety across the entire stack
Turbopack Latest Fast development bundler (3x faster)

Backend & Database

Technology Version Purpose
PostgreSQL 14+ Primary relational database
Prisma 6.19.2 Type-safe ORM with migration management
NextAuth.js 5.0.0-beta.30 Authentication and session management
bcryptjs 3.0.3 Password hashing with salt rounds
Zod 4.3.6 Runtime schema validation
Nanoid 5.1.6 Unique ID generation (CUID alternative)

Cloud Services

Service Purpose
Vercel Edge runtime hosting with instant deploys
Supabase PostgreSQL database with RLS and backups
Backblaze B2 S3-compatible object storage for files
Cloudflare R2 Alternative object storage (supported)
Resend Transactional email delivery (optional)
Google Analytics User behavior tracking and insights

UI & Styling

Technology Version Purpose
Tailwind CSS 4.0 Utility-first CSS framework
Radix UI Latest Accessible component primitives
Lucide React 0.562.0 Beautiful icon library (1000+ icons)
next-themes 0.4.6 Dark/Light mode with system detect
Sonner 2.0.7 Toast notifications
react-dropzone 14.3.8 File upload with drag-and-drop
date-fns 4.1.0 Date manipulation and formatting
tw-animate-css 1.4.0 Tailwind animation utilities
xlsx Latest Excel spreadsheet generation
jszip Latest Client-side ZIP file creation
file-saver Latest Download generated files

Development Tools

Tool Purpose
ESLint Code linting and consistency
TypeScript Static type checking
tsx TypeScript execution for scripts
Prisma Studio Visual database browser
Git Version control

πŸ— Architecture

System Architecture Diagram

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                         CLIENT LAYER                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Next.js App Router (React 19 Server Components)               β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚  β”‚   Admin UI   β”‚  β”‚ Lecturer UI  β”‚  β”‚  Student UI  β”‚         β”‚
β”‚  β”‚  Dashboard   β”‚  β”‚  Dashboard   β”‚  β”‚  Dashboard   β”‚         β”‚
β”‚  β”‚  Users       β”‚  β”‚  Programmes  β”‚  β”‚  Programmes  β”‚         β”‚
β”‚  β”‚  Programmes  β”‚  β”‚  Quizzes     β”‚  β”‚  Lessons     β”‚         β”‚
β”‚  β”‚  Analytics   β”‚  β”‚  Resources   β”‚  β”‚  Quizzes     β”‚         β”‚
β”‚  β”‚  Audit Logs  β”‚  β”‚  Students    β”‚  β”‚  Progress    β”‚         β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚ HTTP/HTTPS
                            ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                      APPLICATION LAYER                          β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Next.js API Routes (Edge Runtime)                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                     β”‚
β”‚  β”‚   /api/admin    β”‚  β”‚   /api/student  β”‚                     β”‚
β”‚  β”‚   /api/lecturer β”‚  β”‚   /api/auth     β”‚                     β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                     β”‚
β”‚                                                                 β”‚
β”‚  Middleware Layer                                              β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                  β”‚
β”‚  β”‚  β€’ Authentication (NextAuth)            β”‚                  β”‚
β”‚  β”‚  β€’ Authorization (Role-based)           β”‚                  β”‚
β”‚  β”‚  β€’ Request Validation (Zod)             β”‚                  β”‚
β”‚  β”‚  β€’ Error Handling                       β”‚                  β”‚
β”‚  β”‚  β€’ Audit Logging                        β”‚                  β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚ Prisma Client
                            ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                        DATA LAYER                               β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  PostgreSQL (Supabase) - 15 Models                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚  β”‚   Users      β”‚  β”‚  Programmes  β”‚  β”‚    Quizzes   β”‚         β”‚
β”‚  β”‚   Sessions   β”‚  β”‚   Modules    β”‚  β”‚   Questions  β”‚         β”‚
β”‚  β”‚   Accounts   β”‚  β”‚   Lessons    β”‚  β”‚   Attempts   β”‚         β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”         β”‚
β”‚  β”‚  Resources   β”‚  β”‚ Enrollments  β”‚  β”‚  Audit Logs  β”‚         β”‚
β”‚  β”‚  Versions    β”‚  β”‚   Progress   β”‚  β”‚ Notificationsβ”‚         β”‚
β”‚  β”‚  Files       β”‚  β”‚  Submissions β”‚  β”‚              β”‚         β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜         β”‚
β”‚                                                                 β”‚
β”‚  Row-Level Security (RLS) Policies                             β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”             β”‚
β”‚  β”‚  β€’ User-based access control                 β”‚             β”‚
β”‚  β”‚  β€’ Role-based data filtering                 β”‚             β”‚
β”‚  β”‚  β€’ Automatic policy enforcement              β”‚             β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜             β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                            β”‚
                            ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    EXTERNAL SERVICES                            β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                    β”‚
β”‚  β”‚  Cloudflare R2   β”‚  β”‚     Resend       β”‚                    β”‚
β”‚  β”‚  (File Storage)  β”‚  β”‚   (Email API)    β”‚                    β”‚
β”‚  β”‚  β€’ Videos        β”‚  β”‚  β€’ Password Resetβ”‚                    β”‚
β”‚  β”‚  β€’ Documents     β”‚  β”‚  β€’ Notifications β”‚                    β”‚
β”‚  β”‚  β€’ Images        β”‚  β”‚  β€’ Invitations   β”‚                    β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                    β”‚
β”‚                                                                 β”‚
β”‚  β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”                                          β”‚
β”‚  β”‚ Google Analytics β”‚                                          β”‚
β”‚  β”‚  (G-S1F397DHHS)  β”‚                                          β”‚
β”‚  β”‚  β€’ Page views    β”‚                                          β”‚
β”‚  β”‚  β€’ User behavior β”‚                                          β”‚
β”‚  β”‚  β€’ Conversions   β”‚                                          β”‚
β”‚  β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜                                          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Authentication Flow

User Login
    β”‚
    ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Submit Email/Password  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ POST /api/auth/callback/credentials β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  NextAuth Validate       β”‚
β”‚  β€’ Email exists?         β”‚
β”‚  β€’ Status = ACTIVE?      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  bcrypt.compare()        β”‚
β”‚  Password Hash Match?    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            ↓ (Success)
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Generate JWT Token      β”‚
β”‚  β€’ user.id               β”‚
β”‚  β€’ user.email            β”‚
β”‚  β€’ user.role             β”‚
β”‚  β€’ 30 day expiration     β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Set HTTP-Only Cookie    β”‚
β”‚  β€’ Secure flag           β”‚
β”‚  β€’ SameSite: Lax         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Redirect to Dashboard   β”‚
β”‚  β€’ /dashboard (admin)    β”‚
β”‚  β€’ /dashboard (lecturer) β”‚
β”‚  β€’ /dashboard (student)  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Subsequent Requests:
    β”‚
    ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  Middleware validates    β”‚
β”‚  JWT from cookie         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
            β”‚
            ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  auth() in Server        β”‚
β”‚  Components returns      β”‚
β”‚  session object          β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Data Flow: Student Taking Quiz

Student clicks "Start Quiz"
    β”‚
    ↓
POST /api/quizzes/attempts
    β”‚
    β”œβ”€ Verify enrollment
    β”œβ”€ Check attempt limit
    β”œβ”€ Create QuizAttempt (status: IN_PROGRESS)
    └─ Return attempt ID
    β”‚
    ↓
Quiz Player Component Renders
    β”‚
    β”œβ”€ Load questions (shuffled if enabled)
    β”œβ”€ Start countdown timer
    └─ Auto-save every 30 seconds
    β”‚
    ↓
Student answers questions
    β”‚
    └─ Store answers in state (not yet saved)
    β”‚
    ↓
Student clicks "Submit Quiz"
    β”‚
    ↓
POST /api/quizzes/attempts/[id]/submit
    β”‚
    β”œβ”€ Verify time limit
    β”œβ”€ Create QuizResponse records
    β”œβ”€ Auto-grade MC and T/F questions
    β”œβ”€ Calculate total score
    β”œβ”€ Update attempt status to COMPLETED
    β”œβ”€ Check passing threshold
    β”œβ”€ Update lesson progress
    └─ Create audit log entry
    β”‚
    ↓
Display Results
    β”‚
    β”œβ”€ Total score and percentage
    β”œβ”€ Pass/Fail status
    β”œβ”€ Question-by-question breakdown
    └─ Correct answers (if enabled)

File Upload Flow

User drags file to dropzone
    β”‚
    ↓
Client-side validation
    β”‚
    β”œβ”€ Check file size (< 20MB)
    β”œβ”€ Check file type (MIME)
    └─ Generate preview
    β”‚
    ↓
POST /api/admin/resources
    β”‚
    └─ Body: multipart/form-data
    β”‚
    ↓
Server-side processing
    β”‚
    β”œβ”€ Validate session & role
    β”œβ”€ Validate lesson exists
    β”œβ”€ Parse form data
    └─ Validate file again
    β”‚
    ↓
Upload to Cloudflare R2
    β”‚
    β”œβ”€ Generate unique file key
    β”œβ”€ Set content type
    β”œβ”€ Upload with AWS S3 SDK
    └─ Get file metadata
    β”‚
    ↓
Save to database
    β”‚
    β”œβ”€ Create LessonResource record
    β”œβ”€ Create ResourceVersion record
    β”œβ”€ Link to lesson
    └─ Set order number
    β”‚
    ↓
Create audit log
    β”‚
    └─ RESOURCE_UPLOADED action
    β”‚
    ↓
Return success
    β”‚
    └─ Client updates UI

πŸš€ Getting Started

Prerequisites

Before you begin, ensure you have the following installed:

  • Node.js: Version 18.x or higher (Download)
  • npm: Version 9.x or higher (comes with Node.js)
  • Git: Latest version (Download)
  • PostgreSQL: 14.x or higher, OR a Supabase account (recommended)
  • Cloudflare Account: For R2 storage (Sign up)
  • Resend Account: For email functionality (Sign up) - Optional

Installation

Step 1: Clone the Repository

git clone https://github.com/codezela/cca-lms.git
cd cca-lms

Step 2: Install Dependencies

npm install

This will install all required packages including Next.js, Prisma, NextAuth, and UI libraries.

Step 3: Environment Setup

Create a .env file in the root directory:

cp .env.example .env

Edit .env with your configuration:

# Database (Supabase or local PostgreSQL)
DATABASE_URL="postgresql://user:password@host:5432/database?pgbouncer=true"
DIRECT_DATABASE_URL="postgresql://user:password@host:5432/database"

# NextAuth Configuration
NEXTAUTH_SECRET="your-secret-key-here-generate-with-openssl"
NEXTAUTH_URL="http://localhost:3000"

# Cloudflare R2 (File Storage)
CLOUDFLARE_R2_ACCOUNT_ID="your-account-id"
CLOUDFLARE_R2_ACCESS_KEY_ID="your-access-key"
CLOUDFLARE_R2_SECRET_ACCESS_KEY="your-secret-key"
CLOUDFLARE_R2_BUCKET_NAME="your-bucket-name"
CLOUDFLARE_R2_PUBLIC_URL="https://your-bucket.r2.cloudflarestorage.com"

# Resend (Email - Optional)
RESEND_API_KEY="re_your_api_key_here"
RESEND_FROM_EMAIL="noreply@yourdomain.com"

# Cron Jobs Security (Required for Vercel)
# Generate with: openssl rand -base64 32
CRON_SECRET="your-cron-secret-here"

# Google Analytics (Optional)
NEXT_PUBLIC_GA_ID="G-S1F397DHHS"

Generate NextAuth Secret:

openssl rand -base64 32

Step 4: Database Setup

Option A: Using Supabase (Recommended)

  1. Create a new project at Supabase
  2. Get your connection string from Project Settings β†’ Database
  3. Use the pooler URL for DATABASE_URL (for serverless)
  4. Use the direct URL for DIRECT_DATABASE_URL (for migrations)

Option B: Local PostgreSQL

# Create database
createdb cca_lms

# Update .env with connection string
DATABASE_URL="postgresql://localhost:5432/cca_lms"
DIRECT_DATABASE_URL="postgresql://localhost:5432/cca_lms"

Generate Prisma Client:

npm run db:generate

Run Database Migrations:

npm run db:push

Enable Row-Level Security:

psql $DATABASE_URL < prisma/migrations/enable_rls.sql

Seed Database with Initial Data:

npm run db:seed

This creates:

  • Admin user: admin@codezela.com / Admin@123
  • Lecturer user: lecturer@codezela.com / Lecturer@123
  • Student user: student@codezela.com / Student@123
  • Sample programme with modules and lessons

Step 5: Cloudflare R2 Setup

  1. Go to Cloudflare Dashboard β†’ R2
  2. Create a new bucket (e.g., cca-lms-files)
  3. Generate API credentials (Access Key ID and Secret)
  4. Configure CORS for your bucket:
[
  {
    "AllowedOrigins": ["http://localhost:3000", "https://yourdomain.com"],
    "AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
    "AllowedHeaders": ["*"],
    "MaxAgeSeconds": 3000
  }
]
  1. Update .env with your R2 credentials

Step 6: Start Development Server

npm run dev

Open http://localhost:3000 in your browser.

Verify Installation

  1. Login as Admin:

    • Email: admin@codezela.com
    • Password: Admin@123
  2. Check Features:

    • Navigate to Users page
    • View Programmes
    • Check Analytics dashboard
    • Test file upload in Resources
  3. Login as Student:

    • Email: student@codezela.com
    • Password: Student@123
    • View assigned programmes
    • Access a lesson

πŸ“ Project Structure

cca-lms/
β”œβ”€β”€ app/                                    # Next.js App Router
β”‚   β”œβ”€β”€ api/                               # API Routes (Edge Runtime)
β”‚   β”‚   β”œβ”€β”€ admin/                         # Admin-only endpoints
β”‚   β”‚   β”‚   β”œβ”€β”€ analytics/                # System analytics
β”‚   β”‚   β”‚   β”œβ”€β”€ activity-logs/            # Audit log retrieval
β”‚   β”‚   β”‚   β”œβ”€β”€ assignments/              # Assignment CRUD
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ [id]/                # Single assignment
β”‚   β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ analytics/       # Submission analytics
β”‚   β”‚   β”‚   β”‚   β”‚   └── bulk-download/   # Bulk file download URLs
β”‚   β”‚   β”‚   β”œβ”€β”€ bulk-enroll/              # CSV bulk enrollment
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ template/            # Download CSV template
β”‚   β”‚   β”‚   β”‚   β”œβ”€β”€ preview/             # Validate CSV preview
β”‚   β”‚   β”‚   β”‚   └── submit/              # Process enrollments
β”‚   β”‚   β”‚   β”œβ”€β”€ dashboard-stats/          # Admin dashboard data
β”‚   β”‚   β”‚   β”œβ”€β”€ lessons/                  # Lesson CRUD + reorder
β”‚   β”‚   β”‚   β”œβ”€β”€ modules/                  # Module CRUD + reorder
β”‚   β”‚   β”‚   β”œβ”€β”€ programmes/               # Programme CRUD
β”‚   β”‚   β”‚   β”œβ”€β”€ quizzes/                  # Quiz CRUD
β”‚   β”‚   β”‚   β”œβ”€β”€ resources/                # Resource CRUD + reorder
β”‚   β”‚   β”‚   β”œβ”€β”€ submissions/[id]/         # Submission grading
β”‚   β”‚   β”‚   └── users/                    # User management CRUD
β”‚   β”‚   β”œβ”€β”€ auth/                         # Authentication
β”‚   β”‚   β”‚   β”œβ”€β”€ [...nextauth]/           # NextAuth handlers
β”‚   β”‚   β”‚   β”œβ”€β”€ change-password/         # Password update
β”‚   β”‚   β”‚   β”œβ”€β”€ request-reset/           # Reset request
β”‚   β”‚   β”‚   └── reset-password/          # Password reset
β”‚   β”‚   β”œβ”€β”€ lecturer/                     # Lecturer endpoints
β”‚   β”‚   β”‚   β”œβ”€β”€ dashboard/               # Lecturer stats
β”‚   β”‚   β”‚   β”œβ”€β”€ programmes/              # Own programmes
β”‚   β”‚   β”‚   └── students/                # Enrolled students
β”‚   β”‚   β”œβ”€β”€ student/                      # Student endpoints
β”‚   β”‚   β”‚   β”œβ”€β”€ assignments/[id]/        # Assignment details
β”‚   β”‚   β”‚   β”œβ”€β”€ dashboard/               # Student stats
β”‚   β”‚   β”‚   β”œβ”€β”€ lessons/[id]/progress/   # Mark complete
β”‚   β”‚   β”‚   β”œβ”€β”€ profile/                 # User profile
β”‚   β”‚   β”‚   β”œβ”€β”€ submissions/             # Submit assignment
β”‚   β”‚   β”‚   β”‚   └── [id]/download/       # Download submission file
β”‚   β”‚   β”‚   └── programmes/              # Enrolled programmes
β”‚   β”‚   β”‚       β”œβ”€β”€ [id]/                # Programme details
β”‚   β”‚   β”‚       β”œβ”€β”€ [id]/enroll/         # Self-enroll (disabled)
β”‚   β”‚   β”‚       └── [id]/lessons/[id]/   # Lesson content
β”‚   β”‚   β”œβ”€β”€ download/[...fileKey]/       # Secure file download proxy
β”‚   β”‚   └── quizzes/                      # Quiz endpoints
β”‚   β”‚       └── attempts/                # Quiz submissions
β”‚   β”œβ”€β”€ activity-logs/                    # Audit log viewer
β”‚   β”œβ”€β”€ analytics/                        # Analytics dashboard
β”‚   β”œβ”€β”€ auth/                             # Auth pages
β”‚   β”‚   β”œβ”€β”€ first-login/                 # First login flow
β”‚   β”‚   β”œβ”€β”€ login/                       # Login page
β”‚   β”‚   └── reset-password/              # Password reset page
β”‚   β”œβ”€β”€ bulk-enroll/                      # Bulk enrollment UI
β”‚   β”œβ”€β”€ dashboard/                        # Main dashboard (role-aware)
β”‚   β”œβ”€β”€ learn/                            # Student learning interface
β”‚   β”‚   β”œβ”€β”€ assignment/[id]/             # Assignment submission page
β”‚   β”‚   └── [id]/                        # Programme view
β”‚   β”‚       β”œβ”€β”€ lesson/[lessonId]/       # Lesson player
β”‚   β”‚       └── page.tsx                 # Programme overview
β”‚   β”œβ”€β”€ my-programmes/                    # Student programme list
β”‚   β”œβ”€β”€ programmes/                       # Programme management
β”‚   β”‚   β”œβ”€β”€ new/                         # Create programme
β”‚   β”‚   └── [id]/                        # Edit programme
β”‚   β”œβ”€β”€ resources/                        # Resource library
β”‚   β”œβ”€β”€ settings/                         # User settings
β”‚   β”œβ”€β”€ students/                         # Lecturer student view
β”‚   β”œβ”€β”€ users/                            # Admin user management
β”‚   β”œβ”€β”€ globals.css                       # Global styles + prose
β”‚   β”œβ”€β”€ layout.tsx                        # Root layout
β”‚   └── page.tsx                          # Landing page
β”‚
β”œβ”€β”€ components/                           # React Components
β”‚   β”œβ”€β”€ assignments/                     # Assignment components
β”‚   β”‚   β”œβ”€β”€ assignment-list.tsx         # Assignment manager for lessons
β”‚   β”‚   β”œβ”€β”€ assignment-form.tsx         # Create/edit assignment form
β”‚   β”‚   β”œβ”€β”€ assignment-analytics.tsx    # Submission statistics
β”‚   β”‚   β”œβ”€β”€ student-submission.tsx      # Student file upload UI
β”‚   β”‚   β”œβ”€β”€ submission-grading.tsx      # Admin/lecturer grading interface
β”‚   β”‚   └── bulk-submission-actions.tsx # Excel export & ZIP download
β”‚   β”œβ”€β”€ bulk-enroll/                     # Bulk enrollment components
β”‚   β”‚   └── bulk-enroll-client.tsx      # CSV upload UI (488 lines)
β”‚   β”œβ”€β”€ dashboards/                      # Role-specific dashboards
β”‚   β”‚   β”œβ”€β”€ admin-dashboard.tsx         # Admin overview
β”‚   β”‚   β”œβ”€β”€ lecturer-dashboard.tsx      # Lecturer overview
β”‚   β”‚   └── student-dashboard.tsx       # Student overview
β”‚   β”œβ”€β”€ programmes/                      # Programme components
β”‚   β”‚   β”œβ”€β”€ module-list.tsx             # Module manager
β”‚   β”‚   β”œβ”€β”€ lesson-list.tsx             # Lesson manager
β”‚   β”‚   └── content-editor.tsx          # Rich text editor
β”‚   β”œβ”€β”€ quizzes/                         # Quiz components
β”‚   β”‚   β”œβ”€β”€ quiz-builder.tsx            # Visual quiz creator (673 lines)
β”‚   β”‚   β”œβ”€β”€ quiz-player.tsx             # Quiz taking UI (530 lines)
β”‚   β”‚   β”œβ”€β”€ question-editor.tsx         # Question form
β”‚   β”‚   └── grading-interface.tsx       # Manual grading
β”‚   β”œβ”€β”€ resources/                       # Resource components
β”‚   β”‚   β”œβ”€β”€ resource-manager.tsx        # CRUD interface (468 lines)
β”‚   β”‚   β”œβ”€β”€ file-upload.tsx             # Upload component (338 lines)
β”‚   β”‚   └── resource-list.tsx           # Display resources
β”‚   β”œβ”€β”€ users/                           # User components
β”‚   β”‚   β”œβ”€β”€ user-table.tsx              # User list
β”‚   β”‚   └── user-form.tsx               # Create/edit user
β”‚   β”œβ”€β”€ ui/                              # Radix UI components
β”‚   β”‚   β”œβ”€β”€ button.tsx                  # Button variants
β”‚   β”‚   β”œβ”€β”€ card.tsx                    # Card component
β”‚   β”‚   β”œβ”€β”€ dialog.tsx                  # Modal dialogs
β”‚   β”‚   β”œβ”€β”€ dropdown-menu.tsx           # Dropdown menus
β”‚   β”‚   β”œβ”€β”€ input.tsx                   # Form inputs
β”‚   β”‚   β”œβ”€β”€ select.tsx                  # Select dropdowns
β”‚   β”‚   β”œβ”€β”€ table.tsx                   # Data tables
β”‚   β”‚   β”œβ”€β”€ tabs.tsx                    # Tab navigation
β”‚   β”‚   └── ...                         # 20+ more components
β”‚   β”œβ”€β”€ footer.tsx                       # Site footer
β”‚   β”œβ”€β”€ navbar.tsx                       # Navigation (role-based)
β”‚   β”œβ”€β”€ theme-provider.tsx              # Dark/light theme
β”‚   └── theme-toggle.tsx                # Theme switcher
β”‚
β”œβ”€β”€ lib/                                 # Utility Libraries
β”‚   β”œβ”€β”€ auth.ts                         # NextAuth configuration
β”‚   β”œβ”€β”€ prisma.ts                       # Prisma client singleton
β”‚   β”œβ”€β”€ r2.ts                           # Cloudflare R2 helpers
β”‚   β”‚   β”œβ”€β”€ uploadFile()                # Upload to R2
β”‚   β”‚   β”œβ”€β”€ getSignedUrl()              # Generate download URL
β”‚   β”‚   └── deleteFile()                # Delete from R2
β”‚   β”œβ”€β”€ resend.ts                       # Email client
β”‚   β”œβ”€β”€ audit.ts                        # Audit logging
β”‚   β”‚   └── createAuditLog()            # Log user actions
β”‚   β”œβ”€β”€ b2.ts                           # Backblaze B2 helpers
β”‚   β”‚   β”œβ”€β”€ uploadToB2()                # Upload file to B2
β”‚   β”‚   β”œβ”€β”€ getB2SignedUrl()            # Generate signed download URL
β”‚   β”‚   └── deleteFromB2()              # Delete file from B2
β”‚   β”œβ”€β”€ utils.ts                        # Helper functions
β”‚   β”‚   β”œβ”€β”€ cn()                        # Class name merger
β”‚   β”‚   β”œβ”€β”€ formatDate()                # Date formatting
β”‚   β”‚   β”œβ”€β”€ isDeadlinePassed()          # UTC deadline comparison
β”‚   β”‚   └── getServerTime()             # Current server time
β”‚   └── validations.ts                  # Zod schemas
β”‚       β”œβ”€β”€ userSchema                  # User validation
β”‚       β”œβ”€β”€ programmeSchema             # Programme validation
β”‚       β”œβ”€β”€ quizSchema                  # Quiz validation
β”‚       β”œβ”€β”€ assignmentSchema            # Assignment validation
β”‚       └── ...                         # More schemas
β”‚
β”œβ”€β”€ prisma/                              # Database
β”‚   β”œβ”€β”€ schema.prisma                   # Schema definition (580 lines)
β”‚   β”‚   β”œβ”€β”€ 15 Models                   # Database tables
β”‚   β”‚   └── 10 Enums                    # Type definitions
β”‚   β”œβ”€β”€ seed.ts                         # Seed script
β”‚   β”‚   β”œβ”€β”€ Demo users (3)              # Admin, lecturer, student
β”‚   β”‚   β”œβ”€β”€ Sample programme (1)        # With modules & lessons
β”‚   β”‚   └── Sample resources (5)        # Various types
β”‚   β”œβ”€β”€ migrations/                     # SQL migrations
β”‚   β”‚   └── enable_rls.sql              # RLS policies (15 tables)
β”‚   └── verify_rls.sql                  # RLS verification
β”‚
β”œβ”€β”€ generated/                           # Auto-generated
β”‚   └── prisma/                         # Prisma Client
β”‚       β”œβ”€β”€ client.ts                   # Type-safe client
β”‚       β”œβ”€β”€ models/                     # Model types
β”‚       └── enums.ts                    # Enum types
β”‚
β”œβ”€β”€ public/                              # Static Assets
β”‚   β”œβ”€β”€ robots.txt                      # Search engine rules
β”‚   └── ...                             # Images, icons, etc.
β”‚
β”œβ”€β”€ types/                               # TypeScript Definitions
β”‚   └── next-auth.d.ts                  # NextAuth extensions
β”‚
β”œβ”€β”€ .env                                 # Environment variables
β”œβ”€β”€ .env.example                         # Example env file
β”œβ”€β”€ .gitignore                          # Git ignore rules
β”œβ”€β”€ eslint.config.mjs                   # ESLint configuration
β”œβ”€β”€ next.config.ts                      # Next.js configuration
β”œβ”€β”€ next-env.d.ts                       # Next.js types
β”œβ”€β”€ package.json                        # Dependencies & scripts
β”œβ”€β”€ postcss.config.mjs                  # PostCSS config
β”œβ”€β”€ prisma.config.ts                    # Prisma config
β”œβ”€β”€ README.md                           # This file
β”œβ”€β”€ tailwind.config.ts                  # Tailwind configuration
└── tsconfig.json                       # TypeScript configuration

πŸ”Œ API Reference

Authentication Endpoints

POST /api/auth/callback/credentials

Login with email and password

Request Body:

{
  "email": "admin@codezela.com",
  "password": "Admin@123"
}

Response:

{
  "user": {
    "id": "clx123...",
    "email": "admin@codezela.com",
    "name": "Admin User",
    "role": "ADMIN"
  }
}

Admin Endpoints

GET /api/admin/users

List all users with pagination

Query Parameters:

  • page (optional): Page number (default: 1)
  • limit (optional): Items per page (default: 50)
  • role (optional): Filter by role (ADMIN, LECTURER, STUDENT)
  • search (optional): Search by name or email

POST /api/admin/bulk-enroll/preview

Preview CSV bulk enrollment

Request Body (multipart/form-data):

  • file: CSV file with columns: Email,Programme Code,Name (optional)

Response:

{
  "preview": [
    {
      "email": "student1@example.com",
      "programmeCode": "CS101",
      "name": "Student One",
      "status": "valid",
      "user": { "id": "...", "name": "..." },
      "programme": { "id": "...", "title": "..." }
    }
  ],
  "summary": {
    "total": 100,
    "valid": 98,
    "duplicates": 0,
    "errors": 2
  }
}

Student Endpoints

GET /api/student/programmes?filter=enrolled

List student's assigned programmes only

GET /api/student/programmes/[id]/lessons/[lessonId]

Get lesson content with resources

Response includes:

  • Lesson details (title, description, video URL, duration)
  • All resources (FILE, EXTERNAL_LINK, EMBEDDED, TEXT_NOTE)
  • Navigation (previous/next lessons)
  • Progress tracking data

πŸ—„ Database Schema

Models Overview

The system uses 15 Prisma models:

Authentication & User Management

  1. User - User accounts with role-based access
  2. Account - OAuth provider accounts (NextAuth)
  3. Session - Active user sessions
  4. VerificationToken - Email verification tokens

Course Content

  1. Course - Main programme entity
  2. Module - Programme sections/chapters
  3. Lesson - Individual learning units
  4. LessonResource - Attachments and materials
  5. ResourceVersion - Resource version history

Assessment

  1. Quiz - Quiz configuration and settings
  2. QuizQuestion - Individual questions
  3. QuizAnswer - Answer options for questions
  4. QuizAttempt - Student quiz submissions
  5. QuizResponse - Individual question responses

Progress & Tracking

  1. CourseEnrollment - Student programme enrollments
  2. LessonProgress - Lesson completion tracking

System

  1. Notification - User notifications
  2. AuditLog - Action audit trail
  3. UploadedFile - File metadata registry

πŸ—„ Backup & Recovery

Automated Daily Backups

The LMS includes a production-ready backup system that automatically backs up your entire database to Cloudflare R2 storage.

Features

  • ⏰ Daily Schedule: Runs at 2:00 AM UTC via Vercel Cron
  • πŸ“¦ Full Database Export: All 23 tables backed up
  • πŸ—œοΈ Compression: ~85% size reduction with gzip
  • πŸ”’ Secure Storage: Private R2 bucket, not publicly accessible
  • 🧹 Auto-Cleanup: Backups older than 14 days automatically deleted
  • πŸ“ Audit Logged: All operations tracked in AuditLog

Backup Location

R2 Bucket: cca-lms-uploads
└── backups/
    └── 2026-02-02/
        └── 2026-02-02_02-00-00_full.json.gz

API Endpoints

Endpoint Method Description
/api/cron/db-backup POST Trigger backup (Vercel Cron or manual)
/api/cron/db-backup GET Check backup health status
/api/admin/backups GET List all available backups

Manual Backup Trigger

curl -X POST https://your-app.vercel.app/api/cron/db-backup \
  -H "Authorization: Bearer YOUR_CRON_SECRET"

Check Backup Health

curl https://your-app.vercel.app/api/cron/db-backup \
  -H "Authorization: Bearer YOUR_CRON_SECRET"

Restore from Backup

  1. Download backup from R2 (using Cloudflare dashboard or CLI)
  2. Run the restore script:
# Dry run (preview only)
npx tsx scripts/restore-backup.ts ./backup-2026-02-02.json.gz --dry-run

# Actual restore
npx tsx scripts/restore-backup.ts ./backup-2026-02-02.json.gz

⚠️ Warning: Restore will DELETE all existing data and replace with backup contents.

Security

  • CRON_SECRET Required: All backup endpoints require Authorization: Bearer <CRON_SECRET>
  • Vercel Auto-Auth: Vercel Cron automatically includes the secret
  • No Public Access: R2 bucket is private
  • Audit Trail: All backup operations logged

πŸš€ Deployment

Vercel Deployment (Recommended)

  1. Push to GitHub:
git add .
git commit -m "Initial commit"
git push -u origin main
  1. Import to Vercel:

  2. Set Environment Variables in Vercel project settings:

Variable Description Required
DATABASE_URL Supabase PostgreSQL connection string βœ…
DIRECT_URL Direct database URL (for migrations) βœ…
AUTH_SECRET NextAuth.js secret key βœ…
R2_ACCOUNT_ID Cloudflare R2 account ID βœ…
R2_ACCESS_KEY_ID R2 access key βœ…
R2_SECRET_ACCESS_KEY R2 secret key βœ…
R2_BUCKET_NAME R2 bucket name βœ…
R2_PUBLIC_URL R2 public URL for file access βœ…
CRON_SECRET Secret for authenticating Vercel Cron jobs βœ…
RESEND_API_KEY Resend email API key βœ…
ADMIN_API_SECRET Admin API authentication secret Optional
  1. Deploy - Vercel auto-deploys on push to main

  2. Verify Cron Jobs:

    • Go to your Vercel project β†’ Settings β†’ Cron Jobs
    • Confirm db-backup job is scheduled for 0 2 * * * (2:00 AM UTC daily)
    • Test manually: curl -X POST https://your-domain.vercel.app/api/cron/db-backup -H "Authorization: Bearer YOUR_CRON_SECRET"

πŸ’‘ Best Practices

Security Best Practices

Input Validation

// βœ… Always validate with Zod
import { z } from "zod";

const userSchema = z.object({
  email: z.string().email(),
  password: z.string().min(8).regex(/[A-Z]/).regex(/[0-9]/),
  name: z.string().min(1).max(100),
  role: z.enum(["ADMIN", "LECTURER", "STUDENT"]),
});

Authentication Checks

// βœ… Always check session
const session = await auth();
if (!session?.user) {
  return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}

Performance Tips

Use Server Components

// βœ… Default to server components
export default async function UsersPage() {
  const users = await prisma.user.findMany();
  return <UserList users={users} />;
}

🀝 Contributing

We welcome contributions from the community!

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes
  4. Commit: git commit -m "Add amazing feature"
  5. Push: git push origin feature/amazing-feature
  6. Open a Pull Request

πŸ“„ License

This project is proprietary software developed by Codezela Technologies for Codezela Career Accelerator.

Copyright Β© 2024-2026 Codezela Technologies. All rights reserved.

For licensing inquiries, contact: contact@codezela.com


πŸ™ Acknowledgments

Built with ❀️ by Codezela Technologies

Technologies Used


πŸ“ž Support

Need help? Have questions?


Made with ❀️ by Codezela Technologies

Website β€’ GitHub β€’ Facebook β€’ Instagram

About

Enterprise-Grade Learning Management System with Terminal Aesthetic

Topics

Resources

Stars

Watchers

Forks

Languages

  • TypeScript 83.7%
  • JavaScript 13.2%
  • PLpgSQL 1.8%
  • CSS 1.3%