courseworx/docs/03-Database-Schema.md
mmabdalla 5477297914 v2.0.2 - Complete Plugin Architecture System and Multi-Currency Implementation
Major Features Added:
- Complete Plugin Architecture System with financial plugin
- Multi-currency support with exchange rates
- Course type system (online, classroom, hybrid)
- Attendance tracking and QR code scanning
- Classroom sessions management
- Course sections and content management
- Professional video player with authentication
- Secure media serving system
- Shopping cart and checkout system
- Financial dashboard and earnings tracking
- Trainee progress tracking
- User notes and assignments system

Backend Infrastructure:
- Plugin loader and registry system
- Multi-currency database models
- Secure media middleware
- Course access middleware
- Financial plugin with payment processing
- Database migrations for new features
- API endpoints for all new functionality

Frontend Components:
- Course management interface
- Content creation and editing
- Section management with drag-and-drop
- Professional video player
- QR scanner for attendance
- Shopping cart and checkout flow
- Financial dashboard
- Plugin management interface
- Trainee details and progress views

This represents a major evolution of CourseWorx from a basic LMS to a comprehensive educational platform with plugin architecture.
2025-09-14 04:20:37 +03:00

19 KiB

CourseWorx Database Schema Documentation

📋 Document Information

  • Version: 1.0.0
  • Last Updated: 2024-12-19
  • Author: AI Assistant
  • Status: Draft - Ready for Review

🎯 Database Overview

CourseWorx uses PostgreSQL as the primary database with Sequelize ORM for data modeling and query management. The database is designed to support a comprehensive Learning Management System with user management, course creation, content delivery, and progress tracking.

🗄️ Database Configuration

Connection Settings

{
  host: process.env.DB_HOST || 'localhost',
  port: process.env.DB_PORT || 5432,
  database: process.env.DB_NAME || 'courseworx',
  username: process.env.DB_USER || 'postgres',
  password: process.env.DB_PASSWORD || 'password',
  dialect: 'postgres',
  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  }
}

Environment Variables

DB_HOST=localhost
DB_PORT=5432
DB_NAME=courseworx
DB_USER=mabdalla
DB_PASSWORD=7ouDa-123q

📊 Core Tables

1. Users Table

Purpose: Store user authentication and profile information Table Name: users

Column Type Constraints Description
id UUID PRIMARY KEY, NOT NULL Unique user identifier
firstName VARCHAR(50) NOT NULL, LENGTH(2,50) User's first name
lastName VARCHAR(50) NOT NULL, LENGTH(2,50) User's last name
email VARCHAR(255) UNIQUE, NOT NULL, EMAIL User's email address
password VARCHAR(255) NOT NULL, LENGTH(6,100) Hashed password
role ENUM NOT NULL, DEFAULT 'trainee' User role (super_admin, trainer, trainee)
phone VARCHAR(20) NULL User's phone number
avatar VARCHAR(255) NULL Profile picture URL
isActive BOOLEAN DEFAULT true Account status
lastLogin TIMESTAMP NULL Last login timestamp
requiresPasswordChange BOOLEAN DEFAULT false Password change flag
createdAt TIMESTAMP NOT NULL Record creation time
updatedAt TIMESTAMP NOT NULL Record update time

Indexes:

  • Primary Key: id
  • Unique: email
  • Performance: role, isActive

Hooks:

  • beforeCreate: Hash password with bcrypt
  • beforeUpdate: Hash password if changed

Instance Methods:

  • comparePassword(candidatePassword): Compare password with hash
  • getFullName(): Return full name string

2. Courses Table

Purpose: Store course information and metadata Table Name: courses

Column Type Constraints Description
id UUID PRIMARY KEY, NOT NULL Unique course identifier
trainerId UUID NOT NULL, FOREIGN KEY Reference to users table
title VARCHAR(200) NOT NULL, LENGTH(3,200) Course title
description TEXT NOT NULL Course description
shortDescription VARCHAR(500) NULL, LENGTH(0,500) Brief course summary
thumbnail VARCHAR(255) NULL Course thumbnail image URL
price DECIMAL(10,2) NOT NULL, DEFAULT 0.00, MIN(0) Course price
duration INTEGER NULL Course duration in minutes
level ENUM NOT NULL, DEFAULT 'beginner' Difficulty level
category VARCHAR(100) NULL Course category
tags TEXT[] NULL, DEFAULT [] Course tags array
isPublished BOOLEAN DEFAULT false Publication status
isFeatured BOOLEAN DEFAULT false Featured course flag
maxStudents INTEGER NULL Maximum enrollment capacity
startDate DATE NULL Course start date
endDate DATE NULL Course end date
requirements TEXT NULL Prerequisites
learningOutcomes TEXT NULL Expected learning results
curriculum JSONB NULL, DEFAULT [] Course structure
rating DECIMAL(3,2) NULL, MIN(0), MAX(5) Average course rating
enrollmentCount INTEGER DEFAULT 0 Current enrollment count
completionCount INTEGER DEFAULT 0 Completed enrollments
createdAt TIMESTAMP NOT NULL Record creation time
updatedAt TIMESTAMP NOT NULL Record update time

Indexes:

  • Primary Key: id
  • Foreign Key: trainerIdusers.id
  • Performance: isPublished, category, level, trainerId

Enums:

  • level: ['beginner', 'intermediate', 'advanced']

3. Course Sections Table

Purpose: Organize course content into logical sections Table Name: course_sections

Column Type Constraints Description
id UUID PRIMARY KEY, NOT NULL Unique section identifier
courseId UUID NOT NULL, FOREIGN KEY Reference to courses table
title VARCHAR(200) NOT NULL Section title
description TEXT NULL Section description
order INTEGER NOT NULL, DEFAULT 0 Section display order
isPublished BOOLEAN DEFAULT true Publication status
createdAt TIMESTAMP NOT NULL Record creation time
updatedAt TIMESTAMP NOT NULL Record update time

Indexes:

  • Primary Key: id
  • Foreign Key: courseIdcourses.id
  • Performance: courseId, order

4. Course Content Table

Purpose: Store individual learning content items Table Name: course_contents

Column Type Constraints Description
id UUID PRIMARY KEY, NOT NULL Unique content identifier
courseId UUID NOT NULL, FOREIGN KEY Reference to courses table
sectionId UUID NULL, FOREIGN KEY Reference to course_sections table
title VARCHAR(200) NOT NULL, LENGTH(1,200) Content title
description TEXT NULL Content description
type ENUM NOT NULL Content type
content JSONB NULL, DEFAULT {} Content metadata
fileUrl VARCHAR(255) NULL File storage URL
fileSize INTEGER NULL File size in bytes
fileType VARCHAR(50) NULL File MIME type
duration INTEGER NULL Content duration in seconds
order INTEGER NOT NULL, DEFAULT 0 Display order
isPublished BOOLEAN DEFAULT true Publication status
isRequired BOOLEAN DEFAULT true Completion requirement
points INTEGER NULL, DEFAULT 0 Points value
quizData JSONB NULL, DEFAULT {} Quiz-specific data
articleContent TEXT NULL Article text content
certificateTemplate JSONB NULL, DEFAULT {} Certificate data
metadata JSONB NULL, DEFAULT {} Additional metadata
createdAt TIMESTAMP NOT NULL Record creation time
updatedAt TIMESTAMP NOT NULL Record update time

Indexes:

  • Primary Key: id
  • Foreign Key: courseIdcourses.id
  • Foreign Key: sectionIdcourse_sections.id
  • Performance: courseId, sectionId, type, order

Enums:

  • type: ['document', 'image', 'video', 'article', 'quiz', 'certificate']

5. Quiz Questions Table

Purpose: Store quiz questions and answers Table Name: quiz_questions

Column Type Constraints Description
id UUID PRIMARY KEY, NOT NULL Unique question identifier
contentId UUID NOT NULL, FOREIGN KEY Reference to course_contents table
question TEXT NOT NULL Question text
questionType ENUM NOT NULL Question type
options TEXT[] NULL Answer options array
correctAnswer TEXT NOT NULL Correct answer
points INTEGER NOT NULL, DEFAULT 1 Points value
explanation TEXT NULL Answer explanation
order INTEGER NOT NULL, DEFAULT 0 Question order
isActive BOOLEAN DEFAULT true Question status
createdAt TIMESTAMP NOT NULL Record creation time
updatedAt TIMESTAMP NOT NULL Record update time

Indexes:

  • Primary Key: id
  • Foreign Key: contentIdcourse_contents.id
  • Performance: contentId, order

Enums:

  • questionType: ['single_choice', 'multiple_choice', 'true_false', 'text']

6. Enrollments Table

Purpose: Track student course enrollments Table Name: enrollments

Column Type Constraints Description
id UUID PRIMARY KEY, NOT NULL Unique enrollment identifier
userId UUID NOT NULL, FOREIGN KEY Reference to users table
courseId UUID NOT NULL, FOREIGN KEY Reference to courses table
status ENUM NOT NULL, DEFAULT 'enrolled' Enrollment status
enrolledAt TIMESTAMP NOT NULL, DEFAULT NOW() Enrollment date
completedAt TIMESTAMP NULL Completion date
progress DECIMAL(5,2) DEFAULT 0.00 Progress percentage
grade VARCHAR(2) NULL Final grade
notes TEXT NULL Admin notes
createdAt TIMESTAMP NOT NULL Record creation time
updatedAt TIMESTAMP NOT NULL Record update time

Indexes:

  • Primary Key: id
  • Foreign Key: userIdusers.id
  • Foreign Key: courseIdcourses.id
  • Performance: userId, courseId, status
  • Unique: userId + courseId (composite)

Enums:

  • status: ['enrolled', 'completed', 'dropped', 'suspended']

7. Lesson Completion Table

Purpose: Track individual content completion Table Name: lesson_completions

Column Type Constraints Description
id UUID PRIMARY KEY, NOT NULL Unique completion identifier
userId UUID NOT NULL, FOREIGN KEY Reference to users table
courseId UUID NOT NULL, FOREIGN KEY Reference to courses table
contentId UUID NOT NULL, FOREIGN KEY Reference to course_contents table
completed BOOLEAN NOT NULL, DEFAULT false Completion status
completedAt TIMESTAMP NULL Completion timestamp
timeSpent INTEGER NULL Time spent in seconds
score INTEGER NULL Quiz score (if applicable)
attempts INTEGER DEFAULT 1 Number of attempts
notes TEXT NULL User notes
createdAt TIMESTAMP NOT NULL Record creation time
updatedAt TIMESTAMP NOT NULL Record update time

Indexes:

  • Primary Key: id
  • Foreign Key: userIdusers.id
  • Foreign Key: courseIdcourses.id
  • Foreign Key: contentIdcourse_contents.id
  • Performance: userId, courseId, contentId
  • Unique: userId + contentId (composite)

8. Assignments Table

Purpose: Store course assignments and submissions Table Name: assignments

Column Type Constraints Description
id UUID PRIMARY KEY, NOT NULL Unique assignment identifier
courseId UUID NOT NULL, FOREIGN KEY Reference to courses table
trainerId UUID NOT NULL, FOREIGN KEY Reference to users table
title VARCHAR(200) NOT NULL Assignment title
description TEXT NOT NULL Assignment description
dueDate TIMESTAMP NULL Due date and time
points INTEGER NOT NULL, DEFAULT 0 Maximum points
isPublished BOOLEAN DEFAULT false Publication status
allowLateSubmission BOOLEAN DEFAULT false Late submission policy
createdAt TIMESTAMP NOT NULL Record creation time
updatedAt TIMESTAMP NOT NULL Record update time

Indexes:

  • Primary Key: id
  • Foreign Key: courseIdcourses.id
  • Foreign Key: trainerIdusers.id
  • Performance: courseId, trainerId, isPublished

9. Attendance Table

Purpose: Track course attendance Table Name: attendance

Column Type Constraints Description
id UUID PRIMARY KEY, NOT NULL Unique attendance identifier
userId UUID NOT NULL, FOREIGN KEY Reference to users table
courseId UUID NOT NULL, FOREIGN KEY Reference to courses table
sessionDate DATE NOT NULL Session date
signInTime TIMESTAMP NULL Sign-in timestamp
signOutTime TIMESTAMP NULL Sign-out timestamp
duration INTEGER NULL Session duration in minutes
status ENUM NOT NULL, DEFAULT 'present' Attendance status
notes TEXT NULL Additional notes
createdAt TIMESTAMP NOT NULL Record creation time
updatedAt TIMESTAMP NOT NULL Record update time

Indexes:

  • Primary Key: id
  • Foreign Key: userIdusers.id
  • Foreign Key: courseIdcourses.id
  • Performance: userId, courseId, sessionDate
  • Unique: userId + courseId + sessionDate (composite)

Enums:

  • status: ['present', 'absent', 'late', 'excused']

10. Course Statistics Table

Purpose: Store aggregated course performance data Table Name: course_stats

Column Type Constraints Description
id UUID PRIMARY KEY, NOT NULL Unique stats identifier
courseId UUID NOT NULL, FOREIGN KEY Reference to courses table
totalEnrollments INTEGER DEFAULT 0 Total enrollments
activeEnrollments INTEGER DEFAULT 0 Current active enrollments
completedEnrollments INTEGER DEFAULT 0 Completed enrollments
averageProgress DECIMAL(5,2) DEFAULT 0.00 Average progress percentage
averageScore DECIMAL(5,2) DEFAULT 0.00 Average assignment score
completionRate DECIMAL(5,2) DEFAULT 0.00 Course completion rate
totalRevenue DECIMAL(10,2) DEFAULT 0.00 Total course revenue
lastUpdated TIMESTAMP NOT NULL, DEFAULT NOW() Last update timestamp
createdAt TIMESTAMP NOT NULL Record creation time
updatedAt TIMESTAMP NOT NULL Record update time

Indexes:

  • Primary Key: id
  • Foreign Key: courseIdcourses.id
  • Performance: courseId

11. User Notes Table

Purpose: Store user personal notes and annotations Table Name: user_notes

Column Type Constraints Description
id UUID PRIMARY KEY, NOT NULL Unique note identifier
userId UUID NOT NULL, FOREIGN KEY Reference to users table
courseId UUID NOT NULL, FOREIGN KEY Reference to courses table
contentId UUID NULL, FOREIGN KEY Reference to course_contents table
content TEXT NOT NULL Note content
isPrivate BOOLEAN DEFAULT true Note visibility
tags TEXT[] NULL, DEFAULT [] Note tags
createdAt TIMESTAMP NOT NULL Record creation time
updatedAt TIMESTAMP NOT NULL Record update time

Indexes:

  • Primary Key: id
  • Foreign Key: userIdusers.id
  • Foreign Key: courseIdcourses.id
  • Foreign Key: contentIdcourse_contents.id
  • Performance: userId, courseId, contentId

🔗 Database Relationships

Entity Relationship Diagram (ERD)

Users (1) ←→ (Many) Courses (as Trainer)
Users (1) ←→ (Many) Enrollments (as Trainee)
Users (1) ←→ (Many) Assignments (as Trainer)
Users (1) ←→ (Many) Attendance
Users (1) ←→ (Many) LessonCompletions
Users (1) ←→ (Many) UserNotes

Courses (1) ←→ (Many) CourseSections
Courses (1) ←→ (Many) CourseContent
Courses (1) ←→ (Many) Enrollments
Courses (1) ←→ (Many) Assignments
Courses (1) ←→ (Many) Attendance
Courses (1) ←→ (Many) LessonCompletions
Courses (1) ←→ (Many) UserNotes
Courses (1) ←→ (1) CourseStats

CourseSections (1) ←→ (Many) CourseContent

CourseContent (1) ←→ (Many) QuizQuestions
CourseContent (1) ←→ (Many) LessonCompletions
CourseContent (1) ←→ (Many) UserNotes

Foreign Key Constraints

-- Users relationships
ALTER TABLE courses ADD CONSTRAINT fk_courses_trainer FOREIGN KEY (trainerId) REFERENCES users(id);
ALTER TABLE enrollments ADD CONSTRAINT fk_enrollments_user FOREIGN KEY (userId) REFERENCES users(id);
ALTER TABLE assignments ADD CONSTRAINT fk_assignments_trainer FOREIGN KEY (trainerId) REFERENCES users(id);
ALTER TABLE attendance ADD CONSTRAINT fk_attendance_user FOREIGN KEY (userId) REFERENCES users(id);
ALTER TABLE lesson_completions ADD CONSTRAINT fk_lesson_completions_user FOREIGN KEY (userId) REFERENCES users(id);
ALTER TABLE user_notes ADD CONSTRAINT fk_user_notes_user FOREIGN KEY (userId) REFERENCES users(id);

-- Course relationships
ALTER TABLE course_sections ADD CONSTRAINT fk_course_sections_course FOREIGN KEY (courseId) REFERENCES courses(id);
ALTER TABLE course_content ADD CONSTRAINT fk_course_content_course FOREIGN KEY (courseId) REFERENCES courses(id);
ALTER TABLE enrollments ADD CONSTRAINT fk_enrollments_course FOREIGN KEY (courseId) REFERENCES courses(id);
ALTER TABLE assignments ADD CONSTRAINT fk_assignments_course FOREIGN KEY (courseId) REFERENCES courses(id);
ALTER TABLE attendance ADD CONSTRAINT fk_attendance_course FOREIGN KEY (courseId) REFERENCES courses(id);
ALTER TABLE lesson_completions ADD CONSTRAINT fk_lesson_completions_course FOREIGN KEY (courseId) REFERENCES courses(id);
ALTER TABLE user_notes ADD CONSTRAINT fk_user_notes_course FOREIGN KEY (courseId) REFERENCES courses(id);
ALTER TABLE course_stats ADD CONSTRAINT fk_course_stats_course FOREIGN KEY (courseId) REFERENCES courses(id);

-- Section relationships
ALTER TABLE course_content ADD CONSTRAINT fk_course_content_section FOREIGN KEY (sectionId) REFERENCES course_sections(id);

-- Content relationships
ALTER TABLE quiz_questions ADD CONSTRAINT fk_quiz_questions_content FOREIGN KEY (contentId) REFERENCES course_content(id);
ALTER TABLE lesson_completions ADD CONSTRAINT fk_lesson_completions_content FOREIGN KEY (contentId) REFERENCES course_content(id);
ALTER TABLE user_notes ADD CONSTRAINT fk_user_notes_content FOREIGN KEY (contentId) REFERENCES course_content(id);

📊 Database Performance

Indexing Strategy

  1. Primary Keys: All tables use UUID primary keys
  2. Foreign Keys: Indexed for join performance
  3. Search Fields: Email, course titles, user names
  4. Order Fields: Section and content ordering
  5. Status Fields: Publication and enrollment status

Query Optimization

  1. Selective Queries: Use specific field selection
  2. Pagination: Implement LIMIT and OFFSET
  3. Eager Loading: Use Sequelize includes for related data
  4. Database Views: Consider for complex aggregations

Connection Pooling

  • Max Connections: 5 concurrent connections
  • Idle Timeout: 10 seconds
  • Acquire Timeout: 30 seconds

🔒 Data Security

Encryption

  • Passwords: bcrypt hashing with salt rounds 12
  • JWT Tokens: Secure random secret keys
  • File Uploads: Secure file type validation

Access Control

  • Row-Level Security: Not implemented (future consideration)
  • Column-Level Security: Sensitive data filtering
  • Audit Logging: Not implemented (future consideration)

Data Validation

  • Input Sanitization: Express-validator middleware
  • Type Validation: Sequelize data type constraints
  • Business Logic: Application-level validation

📈 Database Maintenance

Backup Strategy

  • Daily Backups: Automated PostgreSQL backups
  • Point-in-Time Recovery: WAL archiving (not configured)
  • Backup Testing: Regular restore testing required

Monitoring

  • Connection Monitoring: Active connection tracking
  • Query Performance: Slow query logging (not configured)
  • Storage Monitoring: Disk space and growth tracking

Next Steps:

  1. Review and validate database schema
  2. Implement proper indexing strategy
  3. Add database migration scripts
  4. Create database backup procedures