-- CourseHub schema (MySQL / MariaDB) CREATE DATABASE IF NOT EXISTS coursehub CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; USE coursehub; CREATE TABLE IF NOT EXISTS users ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL UNIQUE, password_hash VARCHAR(255) NOT NULL, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ) ENGINE=InnoDB; -- One row per directory found under VIDEOS_ROOT. -- `path` is the relative path from VIDEOS_ROOT, e.g. "Course 1/Intro". CREATE TABLE IF NOT EXISTS folders ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, parent_id INT UNSIGNED NULL, name VARCHAR(255) NOT NULL, path VARCHAR(700) NOT NULL UNIQUE, depth INT UNSIGNED NOT NULL DEFAULT 0, sort_order INT UNSIGNED NOT NULL DEFAULT 0, is_missing TINYINT(1) NOT NULL DEFAULT 0, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT fk_folders_parent FOREIGN KEY (parent_id) REFERENCES folders(id) ON DELETE CASCADE, INDEX idx_folders_parent (parent_id) ) ENGINE=InnoDB; CREATE TABLE IF NOT EXISTS videos ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, folder_id INT UNSIGNED NOT NULL, name VARCHAR(255) NOT NULL, -- display name, filename without .mp4 filename VARCHAR(255) NOT NULL, path VARCHAR(700) NOT NULL UNIQUE, -- relative path incl. filename size_bytes BIGINT UNSIGNED NOT NULL DEFAULT 0, duration_seconds FLOAT NULL, -- filled in by the player on first load sort_order INT UNSIGNED NOT NULL DEFAULT 0, is_missing TINYINT(1) NOT NULL DEFAULT 0, created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, CONSTRAINT fk_videos_folder FOREIGN KEY (folder_id) REFERENCES folders(id) ON DELETE CASCADE, INDEX idx_videos_folder (folder_id) ) ENGINE=InnoDB; -- Per-user playback state: resume position + completion flag. CREATE TABLE IF NOT EXISTS video_progress ( user_id INT UNSIGNED NOT NULL, video_id INT UNSIGNED NOT NULL, position_seconds FLOAT NOT NULL DEFAULT 0, duration_seconds FLOAT NULL, completed TINYINT(1) NOT NULL DEFAULT 0, updated_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, PRIMARY KEY (user_id, video_id), CONSTRAINT fk_vp_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE, CONSTRAINT fk_vp_video FOREIGN KEY (video_id) REFERENCES videos(id) ON DELETE CASCADE, INDEX idx_vp_user_updated (user_id, updated_at) ) ENGINE=InnoDB;