99 Zeilen
3 KiB
SQL
99 Zeilen
3 KiB
SQL
-- 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);
|