Files
Learn_System/backend/scripts/seed_biochem_challenges.js
T
Maxim Dolgolyov 3b637d154f feat(biochem): Фаза 5.1 — сид заданий balance/match/classify/complete
backend/scripts/seed_biochem_challenges.js (идемпотентно) — 16 заданий
недостающих типов (balance 5, match 3, classify 4, complete 4). Заполняет
пустовавшие фильтры заданий в редакторе; контроллер их уже валидирует.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-05-30 13:59:02 +03:00

117 lines
7.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
'use strict';
/*
* Сид недостающих типов биохим-заданий: balance / match / classify / complete.
* Контроллер biochemController.js эти типы уже поддерживает, а данных в БД не было
* (фильтры в UI были пустыми). Идемпотентно: пропускает уже существующие по title.
*
* Запуск: node backend/scripts/seed_biochem_challenges.js
*/
const db = require('../src/db/db');
const getMaxOrder = db.prepare('SELECT MAX(order_n) AS m FROM bio_challenges');
const existsByTitle = db.prepare('SELECT 1 FROM bio_challenges WHERE title = ?');
const insert = db.prepare(`INSERT INTO bio_challenges
(title, description, type, target_formula, hint, xp_reward, difficulty, topic_tag, order_n, data_json)
VALUES (@title, @description, @type, @target_formula, @hint, @xp_reward, @difficulty, @topic_tag, @order_n, @data_json)`);
// data_json-схемы (совпадают с UI biochem.html и контроллером):
// balance: { reactants:[...], products:[...], coefficients:[...] } (порядок: реагенты, затем продукты)
// match: { pairs:[{left, right}, ...] }
// classify: { target, choices:[...], answer }
// complete: { equation, choices:[...], answer }
const CHALLENGES = [
// ── balance ──────────────────────────────────────────────────────────────
{ type: 'balance', difficulty: 1, xp: 40, title: 'Баланс: синтез воды',
desc: 'Расставь коэффициенты в уравнении образования воды.',
data: { reactants: ['H2', 'O2'], products: ['H2O'], coefficients: [2, 1, 2] } },
{ type: 'balance', difficulty: 2, xp: 50, title: 'Баланс: горение метана',
desc: 'Сбалансируй уравнение полного сгорания метана.',
data: { reactants: ['CH4', 'O2'], products: ['CO2', 'H2O'], coefficients: [1, 2, 1, 2] } },
{ type: 'balance', difficulty: 2, xp: 50, title: 'Баланс: синтез аммиака',
desc: 'Процесс Габера — расставь коэффициенты.',
data: { reactants: ['N2', 'H2'], products: ['NH3'], coefficients: [1, 3, 2] } },
{ type: 'balance', difficulty: 3, xp: 60, title: 'Баланс: горение этана',
desc: 'Сбалансируй сгорание этана (дробные множители убери).',
data: { reactants: ['C2H6', 'O2'], products: ['CO2', 'H2O'], coefficients: [2, 7, 4, 6] } },
{ type: 'balance', difficulty: 2, xp: 50, title: 'Баланс: ржавление железа',
desc: 'Окисление железа кислородом.',
data: { reactants: ['Fe', 'O2'], products: ['Fe2O3'], coefficients: [4, 3, 2] } },
// ── match ────────────────────────────────────────────────────────────────
{ type: 'match', difficulty: 1, xp: 40, title: 'Сопоставь: простые молекулы',
desc: 'Совмести формулу с названием.',
data: { pairs: [
{ left: 'H2O', right: 'Вода' }, { left: 'CO2', right: 'Углекислый газ' },
{ left: 'NH3', right: 'Аммиак' }, { left: 'CH4', right: 'Метан' } ] } },
{ type: 'match', difficulty: 2, xp: 50, title: 'Сопоставь: органические вещества',
desc: 'Совмести формулу с названием.',
data: { pairs: [
{ left: 'C2H5OH', right: 'Этанол' }, { left: 'CH3COOH', right: 'Уксусная кислота' },
{ left: 'C6H6', right: 'Бензол' }, { left: 'C2H4', right: 'Этилен' } ] } },
{ type: 'match', difficulty: 2, xp: 50, title: 'Сопоставь: кислоты и основания',
desc: 'Совмести формулу с названием.',
data: { pairs: [
{ left: 'HCl', right: 'Соляная кислота' }, { left: 'H2SO4', right: 'Серная кислота' },
{ left: 'NaOH', right: 'Гидроксид натрия' }, { left: 'HNO3', right: 'Азотная кислота' } ] } },
// ── classify ─────────────────────────────────────────────────────────────
{ type: 'classify', difficulty: 1, xp: 40, title: 'Класс: метан', target: 'CH4',
desc: 'К какому классу относится CH₄?',
data: { target: 'CH4', choices: ['Алкан', 'Алкен', 'Алкин', 'Арен'], answer: 'Алкан' } },
{ type: 'classify', difficulty: 2, xp: 45, title: 'Класс: этанол', target: 'C2H5OH',
desc: 'К какому классу относится C₂H₅OH?',
data: { target: 'C2H5OH', choices: ['Спирт', 'Карбоновая кислота', 'Альдегид', 'Кетон'], answer: 'Спирт' } },
{ type: 'classify', difficulty: 2, xp: 45, title: 'Класс: уксусная кислота', target: 'CH3COOH',
desc: 'К какому классу относится CH₃COOH?',
data: { target: 'CH3COOH', choices: ['Карбоновая кислота', 'Спирт', 'Сложный эфир', 'Альдегид'], answer: 'Карбоновая кислота' } },
{ type: 'classify', difficulty: 2, xp: 45, title: 'Класс: бензол', target: 'C6H6',
desc: 'К какому классу относится C₆H₆?',
data: { target: 'C6H6', choices: ['Ароматическое', 'Алкан', 'Алкен', 'Спирт'], answer: 'Ароматическое' } },
// ── complete ─────────────────────────────────────────────────────────────
{ type: 'complete', difficulty: 1, xp: 40, title: 'Заверши: образование воды',
desc: 'Какого реагента не хватает?',
data: { equation: '2H₂ + ? → 2H₂O', choices: ['O2', 'CO2', 'N2', 'H2'], answer: 'O2' } },
{ type: 'complete', difficulty: 2, xp: 45, title: 'Заверши: горение метана',
desc: 'Какого продукта не хватает?',
data: { equation: 'CH₄ + 2O₂ → CO₂ + ?', choices: ['H2O', 'H2', 'O2', 'CO'], answer: 'H2O' } },
{ type: 'complete', difficulty: 2, xp: 45, title: 'Заверши: синтез аммиака',
desc: 'Какой продукт образуется?',
data: { equation: 'N₂ + 3H₂ → ?', choices: ['2NH3', 'NH3', 'N2H4', '2NO'], answer: '2NH3' } },
{ type: 'complete', difficulty: 1, xp: 40, title: 'Заверши: горение углерода',
desc: 'Какой продукт образуется при избытке кислорода?',
data: { equation: 'C + O₂ → ?', choices: ['CO2', 'CO', 'C2O', 'O3'], answer: 'CO2' } },
];
let order = (getMaxOrder.get().m || 0);
let added = 0, skipped = 0;
db.exec('BEGIN');
try {
for (const c of CHALLENGES) {
if (existsByTitle.get(c.title)) { skipped++; continue; }
order++;
insert.run({
title: c.title,
description: c.desc || '',
type: c.type,
target_formula: c.target || '',
hint: c.hint || null,
xp_reward: c.xp || 40,
difficulty: c.difficulty || 1,
topic_tag: c.type,
order_n: order,
data_json: JSON.stringify(c.data),
});
added++;
}
db.exec('COMMIT');
} catch (e) {
db.exec('ROLLBACK');
throw e;
}
console.log(`biochem challenges seed: добавлено ${added}, пропущено ${skipped} (уже были).`);
console.log('типы теперь:', db.prepare('SELECT type, COUNT(*) c FROM bio_challenges GROUP BY type ORDER BY type').all()
.map(r => `${r.type}:${r.c}`).join(' '));