Production-Ready Learning Management System by Codezela Technologies
Developed with β€οΈ by Codezela Technologies
Features β’ Tech Stack β’ Getting Started β’ Documentation β’ Architecture
- Overview
- Features
- Tech Stack
- Architecture
- Getting Started
- Project Structure
- API Reference
- Database Schema
- Backup & Recovery
- Deployment
- Best Practices
- Contributing
- License
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.
β
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
- 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
- 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
The system supports diverse lesson formats:
-
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
-
Rich Text Content
- Full HTML support with custom styling
- Code syntax highlighting
- Tables, lists, blockquotes
- Image embedding
- Terminal-themed typography
-
Interactive Quizzes
- Multiple choice questions
- True/False questions
- Short answer (manual grading)
- Essay questions (manual grading)
-
Resource-Based Lessons
- Multiple attachments per lesson
- Mix and match content types
- Scheduled availability
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
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
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
Comprehensive quiz creation tool with:
Question Types:
-
Multiple Choice
- Single correct answer
- Radio button interface
- Up to 10 answer options
- Point value configuration
- Explanation field for feedback
-
True/False
- Binary questions
- Toggle-based selection
- Quick grading
- Explanation support
-
Short Answer
- Text input field
- Manual grading required
- 20 character limit
- Rubric support
-
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
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
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
-
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
-
EXTERNAL_LINK
- Link to any web resource
- Documentation sites
- Online articles
- Reference materials
- Opens in new tab
-
EMBEDDED Content
- YouTube videos (auto-detection)
- Vimeo videos (auto-detection)
- Custom iframe embeds
- Interactive content (CodePen, JSFiddle)
- Google Forms/Slides
- Aspect-ratio responsive containers
-
TEXT_NOTE
- Rich HTML content
- Custom terminal-themed prose styling
- Syntax-highlighted code blocks
- Markdown-style formatting
- Tables and lists
- Embedded images
- 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
- 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
- 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
- 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
- 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
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
- 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
- Total registered users (by role)
- Active programmes and enrollments
- System activity timeline
- Storage usage statistics
- Quiz completion rates
- My programmes overview
- Student enrollment counts
- Lesson completion rates
- Quiz score averages
- Recent student activity
- Enrolled programmes (admin-assigned only)
- Progress percentages
- Recently accessed lessons
- Upcoming quizzes
- Completed assessments
| 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) |
| 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) |
| 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 |
| 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 |
| Tool | Purpose |
|---|---|
| ESLint | Code linting and consistency |
| TypeScript | Static type checking |
| tsx | TypeScript execution for scripts |
| Prisma Studio | Visual database browser |
| Git | Version control |
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β 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 β β
β ββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
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 β
ββββββββββββββββββββββββββββ
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)
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
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
git clone https://github.com/codezela/cca-lms.git
cd cca-lmsnpm installThis will install all required packages including Next.js, Prisma, NextAuth, and UI libraries.
Create a .env file in the root directory:
cp .env.example .envEdit .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 32Option A: Using Supabase (Recommended)
- Create a new project at Supabase
- Get your connection string from Project Settings β Database
- Use the pooler URL for
DATABASE_URL(for serverless) - 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:generateRun Database Migrations:
npm run db:pushEnable Row-Level Security:
psql $DATABASE_URL < prisma/migrations/enable_rls.sqlSeed Database with Initial Data:
npm run db:seedThis 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
- Go to Cloudflare Dashboard β R2
- Create a new bucket (e.g.,
cca-lms-files) - Generate API credentials (Access Key ID and Secret)
- Configure CORS for your bucket:
[
{
"AllowedOrigins": ["http://localhost:3000", "https://yourdomain.com"],
"AllowedMethods": ["GET", "PUT", "POST", "DELETE"],
"AllowedHeaders": ["*"],
"MaxAgeSeconds": 3000
}
]- Update
.envwith your R2 credentials
npm run devOpen http://localhost:3000 in your browser.
-
Login as Admin:
- Email:
admin@codezela.com - Password:
Admin@123
- Email:
-
Check Features:
- Navigate to Users page
- View Programmes
- Check Analytics dashboard
- Test file upload in Resources
-
Login as Student:
- Email:
student@codezela.com - Password:
Student@123 - View assigned programmes
- Access a lesson
- Email:
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
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"
}
}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
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
}
}List student's assigned programmes only
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
The system uses 15 Prisma models:
- User - User accounts with role-based access
- Account - OAuth provider accounts (NextAuth)
- Session - Active user sessions
- VerificationToken - Email verification tokens
- Course - Main programme entity
- Module - Programme sections/chapters
- Lesson - Individual learning units
- LessonResource - Attachments and materials
- ResourceVersion - Resource version history
- Quiz - Quiz configuration and settings
- QuizQuestion - Individual questions
- QuizAnswer - Answer options for questions
- QuizAttempt - Student quiz submissions
- QuizResponse - Individual question responses
- CourseEnrollment - Student programme enrollments
- LessonProgress - Lesson completion tracking
- Notification - User notifications
- AuditLog - Action audit trail
- UploadedFile - File metadata registry
The LMS includes a production-ready backup system that automatically backs up your entire database to Cloudflare R2 storage.
- β° 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
R2 Bucket: cca-lms-uploads
βββ backups/
βββ 2026-02-02/
βββ 2026-02-02_02-00-00_full.json.gz
| 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 |
curl -X POST https://your-app.vercel.app/api/cron/db-backup \
-H "Authorization: Bearer YOUR_CRON_SECRET"curl https://your-app.vercel.app/api/cron/db-backup \
-H "Authorization: Bearer YOUR_CRON_SECRET"- Download backup from R2 (using Cloudflare dashboard or CLI)
- 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- 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
- Push to GitHub:
git add .
git commit -m "Initial commit"
git push -u origin main-
Import to Vercel:
- Go to Vercel Dashboard
- Click "Import Project"
- Select your GitHub repository
-
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 |
-
Deploy - Vercel auto-deploys on push to main
-
Verify Cron Jobs:
- Go to your Vercel project β Settings β Cron Jobs
- Confirm
db-backupjob is scheduled for0 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"
// β
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"]),
});// β
Always check session
const session = await auth();
if (!session?.user) {
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
}// β
Default to server components
export default async function UsersPage() {
const users = await prisma.user.findMany();
return <UserList users={users} />;
}We welcome contributions from the community!
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Commit:
git commit -m "Add amazing feature" - Push:
git push origin feature/amazing-feature - Open a Pull Request
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
Built with β€οΈ by Codezela Technologies
- Next.js - React framework
- Prisma - Database ORM
- NextAuth.js - Authentication
- Tailwind CSS - Styling
- Radix UI - Components
- Cloudflare R2 - Storage
- Supabase - Database hosting
- Vercel - Deployment platform
Need help? Have questions?
- Website: https://codezela.com
- Email: ca@codezela.com