edu-senex/setup/schema.sql

100 Zeilen
3 KiB
MySQL

-- edu.senex.de Training Platform - Database Schema
-- Run: docker exec -i postgres psql -U postgres -d edu < schema.sql
-- Users
CREATE TABLE IF NOT EXISTS users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
password_hash VARCHAR(255) NOT NULL,
display_name VARCHAR(100) NOT NULL,
is_admin BOOLEAN DEFAULT false,
created_at TIMESTAMP DEFAULT NOW()
);
-- Flashcard Decks
CREATE TABLE IF NOT EXISTS decks (
id SERIAL PRIMARY KEY,
slug VARCHAR(100) UNIQUE NOT NULL,
name VARCHAR(200) NOT NULL,
description TEXT DEFAULT '',
card_count INT DEFAULT 0,
sort_order INT DEFAULT 0,
source_file VARCHAR(200),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Flashcards
CREATE TABLE IF NOT EXISTS cards (
id SERIAL PRIMARY KEY,
deck_id INT NOT NULL REFERENCES decks(id) ON DELETE CASCADE,
question TEXT NOT NULL,
answer TEXT NOT NULL,
level VARCHAR(20) DEFAULT 'basis',
sort_order INT DEFAULT 0,
source_file VARCHAR(200),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_cards_deck ON cards(deck_id);
-- SM-2 Spaced Repetition Progress
CREATE TABLE IF NOT EXISTS card_progress (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
card_id INT NOT NULL REFERENCES cards(id) ON DELETE CASCADE,
ease_factor REAL DEFAULT 2.5,
interval_days INT DEFAULT 0,
repetitions INT DEFAULT 0,
next_review DATE DEFAULT CURRENT_DATE,
last_rating VARCHAR(10),
last_reviewed_at TIMESTAMP,
UNIQUE(user_id, card_id)
);
CREATE INDEX IF NOT EXISTS idx_card_progress_due ON card_progress(user_id, next_review);
-- Tutorials
CREATE TABLE IF NOT EXISTS tutorials (
id SERIAL PRIMARY KEY,
slug VARCHAR(100) UNIQUE NOT NULL,
title VARCHAR(200) NOT NULL,
description TEXT DEFAULT '',
content_md TEXT NOT NULL,
duration_min INT,
sort_order INT DEFAULT 0,
source_file VARCHAR(200),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Tutorial Progress
CREATE TABLE IF NOT EXISTS tutorial_progress (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
tutorial_id INT NOT NULL REFERENCES tutorials(id) ON DELETE CASCADE,
completed BOOLEAN DEFAULT false,
completed_at TIMESTAMP,
UNIQUE(user_id, tutorial_id)
);
-- Cheat Sheets
CREATE TABLE IF NOT EXISTS cheatsheets (
id SERIAL PRIMARY KEY,
slug VARCHAR(100) UNIQUE NOT NULL,
title VARCHAR(200) NOT NULL,
category VARCHAR(100) DEFAULT '',
content_md TEXT NOT NULL,
source_file VARCHAR(200),
updated_at TIMESTAMP DEFAULT NOW()
);
-- Quiz Results
CREATE TABLE IF NOT EXISTS quiz_results (
id SERIAL PRIMARY KEY,
user_id INT NOT NULL REFERENCES users(id) ON DELETE CASCADE,
deck_slug VARCHAR(100),
quiz_type VARCHAR(50) DEFAULT 'multiple_choice',
score_percent INT,
total_questions INT,
correct_answers INT,
created_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_quiz_results_user ON quiz_results(user_id, created_at DESC);