'use strict'; /* * Каркас курса «ЦЭ/ЦТ — Математика» на существующем банке questions. * План: plans/ct-math/ (BUILD_ON_QUESTIONS.md). * ИДЕМПОТЕНТЕН и АДДИТИВЕН: добавляет недостающие темы (topics), * создаёт DRAFT-курс (is_published=0) + 9 секций. Существующие данные не трогает. * Запуск: node backend/scripts/seed_ctmath_course.js (применить) * node backend/scripts/seed_ctmath_course.js --dry (только показать план) */ const db = require('../src/db/db'); const DRY = process.argv.includes('--dry'); const MATH_ID = 3; // 1) Недостающие темы под модульную карту (см. BUILD_ON_QUESTIONS §3) const NEW_TOPICS = [ 'Преобразование выражений', 'Модуль', 'Иррациональные уравнения', 'Показательные уравнения', 'Производная', 'Параметры', ]; // 2) Секции курса = 9 блоков (PLAN §3) const SECTIONS = [ 'Числа и вычисления', 'Алгебраические преобразования', 'Уравнения и неравенства', 'Функции и производная', 'Тригонометрия', 'Прогрессии и текстовые задачи', 'Планиметрия', 'Стереометрия', 'Продвинутое и комбинированное', ]; const COURSE_TITLE = 'ЦЭ/ЦТ — Математика'; const COURSE_DESC = 'Подготовка к ЦЭ/ЦТ по математике: 30 заданий (часть А — А1–А10, часть В — В1–В20). Теория по темам, тренажёр на банке заданий прошлых лет, карточки формул, пробные варианты.'; function topicExists(name) { return db.prepare('SELECT id FROM topics WHERE subject_id=? AND LOWER(name)=LOWER(?)').get(MATH_ID, name); } function adminId() { const u = db.prepare("SELECT id FROM users WHERE role='admin' ORDER BY id LIMIT 1").get() || db.prepare('SELECT id FROM users ORDER BY id LIMIT 1').get(); return u && u.id; } let addedTopics = 0, skippedTopics = 0; console.log(DRY ? '[DRY-RUN] план изменений:' : '[APPLY] вношу изменения:'); console.log('\n— Темы (topics) —'); for (const name of NEW_TOPICS) { const ex = topicExists(name); if (ex) { console.log(` есть: ${name} (id ${ex.id})`); skippedTopics++; continue; } if (DRY) { console.log(` + добавить: ${name}`); addedTopics++; continue; } const id = db.prepare('INSERT INTO topics (subject_id,name) VALUES (?,?)').run(MATH_ID, name).lastInsertRowid; console.log(` + добавлено: ${name} (id ${id})`); addedTopics++; } console.log('\n— Курс (courses) —'); let course = db.prepare("SELECT id,is_published FROM courses WHERE subject_slug='math' AND title=?").get(COURSE_TITLE); let courseId; if (course) { courseId = course.id; console.log(` есть курс «${COURSE_TITLE}» (id ${courseId}, ${course.is_published ? 'published' : 'draft'})`); } else if (DRY) { console.log(` + создать DRAFT-курс «${COURSE_TITLE}» (created_by=${adminId()})`); } else { const by = adminId(); // cover_emoji не указываем — применится дефолт схемы; в коде эмодзи не вводим courseId = db.prepare( 'INSERT INTO courses (subject_slug,title,description,is_published,created_by) VALUES (?,?,?,0,?)' ).run('math', COURSE_TITLE, COURSE_DESC, by).lastInsertRowid; console.log(` + создан DRAFT-курс «${COURSE_TITLE}» (id ${courseId}, created_by=${by})`); } console.log('\n— Секции (course_sections) —'); if (!courseId && DRY) { SECTIONS.forEach((t, i) => console.log(` + секция [${i + 1}] ${t}`)); } else if (courseId) { SECTIONS.forEach((title, i) => { const ex = db.prepare('SELECT id FROM course_sections WHERE course_id=? AND title=?').get(courseId, title); if (ex) { console.log(` есть: [${i + 1}] ${title} (id ${ex.id})`); return; } if (DRY) { console.log(` + секция [${i + 1}] ${title}`); return; } const id = db.prepare('INSERT INTO course_sections (course_id,title,order_index) VALUES (?,?,?)').run(courseId, title, i + 1).lastInsertRowid; console.log(` + секция [${i + 1}] ${title} (id ${id})`); }); } console.log(`\nИтог: темы +${addedTopics} (есть ${skippedTopics}); курс id=${courseId || '(dry)'}; секций ${SECTIONS.length}.`); console.log(DRY ? 'DRY-RUN: ничего не записано.' : 'Готово. Курс создан как ЧЕРНОВИК (is_published=0) — ученикам не виден до публикации.');