-- ═══════════════════════════════════════════════════════════════ -- 022: Exam Preparation Module -- -- Generic exam preparation infrastructure parameterized by exam_key. -- Supports multiple exams (math9, phys9, chem9, math11ce, etc.) sharing -- the same task bank, attempts tracking, mock sessions, and study plans. -- -- See docs/exam-prep-plan.md for full architecture. -- ═══════════════════════════════════════════════════════════════ -- ── Exam tracks registry ──────────────────────────────────────── CREATE TABLE exam_tracks ( exam_key TEXT PRIMARY KEY, title TEXT NOT NULL, subject_slug TEXT NOT NULL, grade INTEGER NOT NULL, duration_min INTEGER NOT NULL, tasks_per_variant INTEGER NOT NULL, variants_count INTEGER NOT NULL, scoring_json TEXT, intro_html TEXT, enabled INTEGER NOT NULL DEFAULT 1, sort_order INTEGER NOT NULL DEFAULT 0 ); -- ── Task bank (one row per task across all variants) ──────────── CREATE TABLE exam_tasks ( id INTEGER PRIMARY KEY, exam_key TEXT NOT NULL REFERENCES exam_tracks(exam_key) ON DELETE CASCADE, variant INTEGER NOT NULL, task_idx INTEGER NOT NULL, task_type TEXT NOT NULL CHECK (task_type IN ('mc','open','long')), text_html TEXT NOT NULL, figure_html TEXT, opts_json TEXT, answer TEXT, solution_html TEXT NOT NULL, topic TEXT, subtopic TEXT, difficulty INTEGER, UNIQUE(exam_key, variant, task_idx) ); CREATE INDEX idx_exam_tasks_topic ON exam_tasks(exam_key, topic); CREATE INDEX idx_exam_tasks_variant ON exam_tasks(exam_key, variant); CREATE INDEX idx_exam_tasks_type ON exam_tasks(exam_key, task_type); -- ── User attempts ─────────────────────────────────────────────── CREATE TABLE exam_attempts ( id INTEGER PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, exam_task_id INTEGER NOT NULL REFERENCES exam_tasks(id) ON DELETE CASCADE, user_answer TEXT, is_correct INTEGER, time_ms INTEGER, mode TEXT NOT NULL CHECK (mode IN ('practice','variant','topic','mock')), session_id INTEGER, hint_used INTEGER NOT NULL DEFAULT 0, solution_viewed INTEGER NOT NULL DEFAULT 0, created_at INTEGER NOT NULL ); CREATE INDEX idx_exam_attempts_user_time ON exam_attempts(user_id, created_at DESC); CREATE INDEX idx_exam_attempts_task ON exam_attempts(exam_task_id); CREATE INDEX idx_exam_attempts_session ON exam_attempts(session_id); CREATE INDEX idx_exam_attempts_user_task ON exam_attempts(user_id, exam_task_id, created_at DESC); -- ── Mock exam sessions ────────────────────────────────────────── CREATE TABLE exam_mock_sessions ( id INTEGER PRIMARY KEY, user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, exam_key TEXT NOT NULL, variant INTEGER, source TEXT NOT NULL CHECK (source IN ('variant','random','weak-topics')), task_ids_json TEXT NOT NULL, started_at INTEGER NOT NULL, finished_at INTEGER, duration_planned_min INTEGER NOT NULL, score INTEGER, total_correct INTEGER, total_tasks INTEGER, status TEXT NOT NULL DEFAULT 'active' CHECK (status IN ('active','finished','abandoned')) ); CREATE INDEX idx_mock_user ON exam_mock_sessions(user_id, started_at DESC); -- ── User preparation plan ─────────────────────────────────────── CREATE TABLE exam_user_plan ( user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE, exam_key TEXT NOT NULL, exam_date TEXT NOT NULL, daily_target INTEGER NOT NULL DEFAULT 10, weak_focus INTEGER NOT NULL DEFAULT 1, created_at INTEGER NOT NULL, updated_at INTEGER NOT NULL, PRIMARY KEY (user_id, exam_key) ); -- ── Topic dictionary (populated in F6) ────────────────────────── CREATE TABLE exam_topics ( slug TEXT PRIMARY KEY, exam_key TEXT NOT NULL, parent_slug TEXT, title TEXT NOT NULL, description TEXT, sort_order INTEGER NOT NULL DEFAULT 0 ); CREATE INDEX idx_topics_exam ON exam_topics(exam_key, parent_slug); -- ── Seed: math9 track ─────────────────────────────────────────── -- Placeholder scoring grid (simple proportional). Replace with the actual -- Belarus 9th-grade math exam grid once published per academic year. INSERT INTO exam_tracks ( exam_key, title, subject_slug, grade, duration_min, tasks_per_variant, variants_count, scoring_json, intro_html, enabled, sort_order ) VALUES ( 'math9', 'Экзамен 9 класс — Математика', 'math', 9, 180, 10, 80, '[{"correct":30,"score":10},{"correct":27,"score":9},{"correct":24,"score":8},{"correct":21,"score":7},{"correct":18,"score":6},{"correct":15,"score":5},{"correct":12,"score":4},{"correct":9,"score":3},{"correct":6,"score":2},{"correct":3,"score":1},{"correct":0,"score":0}]', '

Полная подготовка к выпускному экзамену по математике за 9 класс. 80 реальных вариантов, разбор каждого задания, тренажёр по темам, пробные экзамены с таймером.

', 1, 10 );