'use strict'; const db = require('../../db/db'); const { emitToSession } = require('./_shared'); const _stmtTextbookBySlug = db.prepare( 'SELECT slug, title, subject, grade FROM textbooks WHERE slug=? AND is_active=1' ); function _requireTeacher(req, res) { const sessionId = Number(req.params.id); const session = db.prepare(`SELECT * FROM classroom_sessions WHERE id=? AND status='active'`).get(sessionId); if (!session) { res.status(404).json({ error: 'Сессия не активна' }); return null; } if (session.teacher_id !== req.user.id && req.user.role !== 'admin') { res.status(403).json({ error: 'Нет доступа' }); return null; } return sessionId; } function textbookOpen(req, res) { const sessionId = _requireTeacher(req, res); if (!sessionId) return; const { slug, hash } = req.body || {}; if (!slug || typeof slug !== 'string' || !/^[a-z0-9_-]{1,80}$/i.test(slug)) return res.status(400).json({ error: 'Неверный slug' }); const tb = _stmtTextbookBySlug.get(slug); if (!tb) return res.status(404).json({ error: 'Учебник не найден' }); const safeHash = (typeof hash === 'string' && /^[a-z0-9_-]{1,40}$/i.test(hash)) ? hash : null; emitToSession(sessionId, { type: 'classroom_textbook_open', sessionId, slug: tb.slug, title: tb.title, subject: tb.subject, grade: tb.grade, hash: safeHash, }); res.json({ ok: true }); } function textbookNav(req, res) { const sessionId = _requireTeacher(req, res); if (!sessionId) return; const { slug, hash, scrollY } = req.body || {}; if (!slug || typeof slug !== 'string' || !/^[a-z0-9_-]{1,80}$/i.test(slug)) return res.status(400).json({ error: 'Неверный slug' }); if (!_stmtTextbookBySlug.get(slug)) return res.status(404).json({ error: 'Учебник не найден' }); const safeHash = (typeof hash === 'string' && /^[a-z0-9_-]{1,40}$/i.test(hash)) ? hash : null; const sy = (typeof scrollY === 'number' && isFinite(scrollY)) ? Math.max(0, Math.min(scrollY, 1e6)) : null; emitToSession(sessionId, { type: 'classroom_textbook_nav', sessionId, slug, hash: safeHash, scrollY: sy, }); res.json({ ok: true }); } function textbookMode(req, res) { const sessionId = _requireTeacher(req, res); if (!sessionId) return; const { mode } = req.body || {}; if (mode !== 'demo' && mode !== 'free') return res.status(400).json({ error: 'mode must be demo|free' }); emitToSession(sessionId, { type: 'classroom_textbook_mode', sessionId, mode }); res.json({ ok: true }); } function textbookClose(req, res) { const sessionId = _requireTeacher(req, res); if (!sessionId) return; emitToSession(sessionId, { type: 'classroom_textbook_close', sessionId }); res.json({ ok: true }); } module.exports = { textbookOpen, textbookNav, textbookMode, textbookClose };