Files
Learn_System/backend/scripts/seed_biochem_challenges.js
T
Maxim Dolgolyov 5381679c68 chore: консолидация незакоммиченной работы (биохимия + System Health + lab/textbooks)
Зафиксирована накопленная незакоммиченная работа рабочего дерева, КРОМЕ файлов
учебника «Химия 7» (migration 046, chemistry_7_*.html, chem7_svg.js, тест —
оставлены незакоммиченными по запросу).

Включает: модуль биохимии (ядро BIO, 3D VSEPR, химдвижок, баланс, challenges,
пути из БД), System Health Level 1 (вердикт/мониторинг), а также frontend-
страницы и lab/textbooks-правки параллельной сессии.

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

136 lines
9.8 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' } },
// ── build со структурной проверкой (3D-build, Фаза 5.3) ───────────────────
// target_formula — в Hill-нотации (как считает контроллер); эталон по molecule_id.
{ type: 'build', difficulty: 1, xp: 45, title: 'Собери: углекислый газ (структура)', target: 'CO2',
desc: 'Построй CO₂: углерод с двумя двойными связями к кислороду. Проверяется связность.',
hint: 'O=C=O — две двойные связи',
data: { requireStructure: true, molecule_id: 2 } },
{ type: 'build', difficulty: 2, xp: 55, title: 'Собери: этилен (структура)', target: 'C2H4',
desc: 'Построй этилен C₂H₄: двойная связь C=C и по два H на каждом углероде.',
hint: 'H₂C=CH₂ — двойная связь между углеродами',
data: { requireStructure: true, molecule_id: 12 } },
{ type: 'build', difficulty: 2, xp: 60, title: 'Собери: этанол (структура)', target: 'C2H6O',
desc: 'Построй этанол: скелет C–C–O, заполни валентности водородами. Важна именно связность (не диметиловый эфир!).',
hint: 'CH₃–CH₂–OH: цепочка CCO',
data: { requireStructure: true, molecule_id: 14 } },
{ type: 'build', difficulty: 3, xp: 70, title: 'Собери: уксусную кислоту (структура)', target: 'C2H4O2',
desc: 'Построй уксусную кислоту CH₃COOH: метил + карбоксильная группа (C=O и COH).',
hint: 'CH₃–COOH: карбоксил COOH',
data: { requireStructure: true, molecule_id: 15 } },
];
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(' '));