const sqlite3 = require('sqlite3').verbose(); const path = require('path'); const fs = require('fs'); const dbPath = path.join(__dirname, 'data', 'school.db'); const dataDir = path.join(__dirname, 'data'); if (!fs.existsSync(dataDir)) { fs.mkdirSync(dataDir); } const db = new sqlite3.Database(dbPath); // Инициализация таблиц db.serialize(() => { db.run(` CREATE TABLE IF NOT EXISTS lessons ( id INTEGER PRIMARY KEY AUTOINCREMENT, class_name TEXT NOT NULL, parallel INTEGER NOT NULL, subject TEXT NOT NULL, teacher TEXT NOT NULL, topic TEXT, max_slots INTEGER NOT NULL DEFAULT 4, current_slots INTEGER NOT NULL DEFAULT 0, date TEXT NOT NULL, time TEXT NOT NULL ) `); db.run(` CREATE TABLE IF NOT EXISTS registrations ( id INTEGER PRIMARY KEY AUTOINCREMENT, lesson_id INTEGER NOT NULL, parent_name TEXT NOT NULL, parent_phone TEXT NOT NULL, created_at TEXT DEFAULT CURRENT_TIMESTAMP, FOREIGN KEY (lesson_id) REFERENCES lessons(id) ON DELETE CASCADE ) `); }); function runQuery(sql, params = []) { return new Promise((resolve, reject) => { db.run(sql, params, function(err) { if (err) reject(err); else resolve(this); }); }); } function getQuery(sql, params = []) { return new Promise((resolve, reject) => { db.get(sql, params, (err, row) => { if (err) reject(err); else resolve(row); }); }); } function allQuery(sql, params = []) { return new Promise((resolve, reject) => { db.all(sql, params, (err, rows) => { if (err) reject(err); else resolve(rows); }); }); } module.exports = { db, runQuery, getQuery, allQuery, getLessons: (filter = {}) => { let sql = 'SELECT * FROM lessons WHERE 1=1'; const params = []; if (filter.class_name) { sql += ' AND class_name LIKE ?'; params.push(`%${filter.class_name}%`); } if (filter.parallel) { sql += ' AND parallel = ?'; params.push(filter.parallel); } if (filter.teacher) { sql += ' AND teacher LIKE ?'; params.push(`%${filter.teacher}%`); } if (filter.topic) { sql += ' AND topic LIKE ?'; params.push(`%${filter.topic}%`); } sql += ' ORDER BY parallel, class_name, time'; return allQuery(sql, params); }, getLessonById: (id) => { return getQuery('SELECT * FROM lessons WHERE id = ?', [id]); }, createLesson: (lesson) => { const { class_name, parallel, subject, teacher, topic, max_slots, date, time } = lesson; return runQuery( `INSERT INTO lessons (class_name, parallel, subject, teacher, topic, max_slots, current_slots, date, time) VALUES (?, ?, ?, ?, ?, ?, 0, ?, ?)`, [class_name, parallel, subject, teacher, topic || '', max_slots, date, time] ).then(result => result.lastID); }, updateLesson: (id, lesson) => { const { class_name, parallel, subject, teacher, topic, max_slots, date, time } = lesson; return runQuery( `UPDATE lessons SET class_name=?, parallel=?, subject=?, teacher=?, topic=?, max_slots=?, date=?, time=? WHERE id=?`, [class_name, parallel, subject, teacher, topic || '', max_slots, date, time, id] ); }, deleteLesson: (id) => { return runQuery('DELETE FROM lessons WHERE id = ?', [id]); }, incrementCurrentSlots: (lessonId) => { return runQuery( `UPDATE lessons SET current_slots = current_slots + 1 WHERE id = ? AND current_slots < max_slots`, [lessonId] ); }, addRegistration: (lessonId, parentName, parentPhone) => { return runQuery( `INSERT INTO registrations (lesson_id, parent_name, parent_phone) VALUES (?, ?, ?)`, [lessonId, parentName, parentPhone] ); }, getRegistrationsByLesson: (lessonId) => { return allQuery('SELECT * FROM registrations WHERE lesson_id = ? ORDER BY created_at DESC', [lessonId]); }, getAllRegistrations: () => { return allQuery(` SELECT r.*, l.class_name, l.subject, l.teacher, l.date, l.time FROM registrations r JOIN lessons l ON r.lesson_id = l.id ORDER BY r.created_at DESC `); }, getRegistrationsWithFilters: (filters) => { let sql = ` SELECT r.id, r.parent_name, r.parent_phone, r.created_at, l.class_name, l.subject, l.teacher, l.topic, l.date, l.time FROM registrations r JOIN lessons l ON r.lesson_id = l.id WHERE 1=1 `; const params = []; if (filters.parent_name) { sql += ' AND r.parent_name LIKE ?'; params.push(`%${filters.parent_name}%`); } if (filters.class_name) { sql += ' AND l.class_name LIKE ?'; params.push(`%${filters.class_name}%`); } if (filters.subject) { sql += ' AND l.subject LIKE ?'; params.push(`%${filters.subject}%`); } if (filters.teacher) { sql += ' AND l.teacher LIKE ?'; params.push(`%${filters.teacher}%`); } sql += ' ORDER BY r.created_at DESC'; return allQuery(sql, params); }, // НОВЫЙ МЕТОД – полная очистка базы clearAllData: async () => { await runQuery('DELETE FROM registrations'); await runQuery('DELETE FROM lessons'); await runQuery("DELETE FROM sqlite_sequence WHERE name IN ('lessons', 'registrations')"); } };