'use strict'; /* prepController — управление флагом «подготовки к направлению» (мастер-флаг). * * Флаг student_prep(user_id, track) открывает ученику весь контент трека * (карточки + курс + пробники) — резолв в services/prepTracks.js + contentAccess.js. * * Управление: учитель — СВОИМ ученикам (из своих классов или персональным), * админ — любым. Read own-статус доступен самому ученику (GET /me). */ const db = require('../db/db'); const prepTracks = require('../services/prepTracks'); /* Ученик «свой» для учителя: член одного из его классов ИЛИ персональный ученик. */ function canManageStudent(user, studentId) { if (user.role === 'admin') return true; if (user.role !== 'teacher') return false; return !!db.prepare(` SELECT 1 FROM class_members cm JOIN classes c ON c.id = cm.class_id WHERE cm.user_id = ? AND c.teacher_id = ? UNION SELECT 1 FROM teacher_students WHERE student_id = ? AND teacher_id = ? LIMIT 1 `).get(studentId, user.id, studentId, user.id); } /* Класс «свой» для учителя (admin — любой). */ function canManageClass(user, classId) { if (user.role === 'admin') return true; if (user.role !== 'teacher') return false; return !!db.prepare(`SELECT 1 FROM classes WHERE id = ? AND teacher_id = ?`).get(classId, user.id); } /* ── GET /api/prep/tracks — список доступных направлений (для UI-меток) ── */ function listTracks(req, res) { res.json({ tracks: prepTracks.listTracks() }); } /* ── GET /api/prep/me — мои треки (ученик видит свой статус) ── */ function myTracks(req, res) { const rows = db.prepare(`SELECT track FROM student_prep WHERE user_id = ?`).all(req.user.id); res.json({ tracks: rows.map(r => r.track).filter(prepTracks.isTrack) }); } /* ── GET /api/prep/student/:id — треки ученика (учитель своего / админ) ── */ function studentTracks(req, res) { const studentId = Number(req.params.id) || 0; if (!canManageStudent(req.user, studentId)) return res.status(403).json({ error: 'Forbidden' }); const rows = db.prepare(`SELECT track FROM student_prep WHERE user_id = ?`).all(studentId); res.json({ tracks: rows.map(r => r.track).filter(prepTracks.isTrack) }); } /* ── POST /api/prep/student/:id { track } — включить флаг ── */ function setStudent(req, res) { const studentId = Number(req.params.id) || 0; const track = String(req.body.track || ''); if (!prepTracks.isTrack(track)) return res.status(400).json({ error: 'Неизвестный трек' }); if (!canManageStudent(req.user, studentId)) return res.status(403).json({ error: 'Forbidden' }); // Ставим флаг только реально существующему ученику. const stu = db.prepare(`SELECT id, role FROM users WHERE id = ?`).get(studentId); if (!stu) return res.status(404).json({ error: 'Ученик не найден' }); db.prepare(`INSERT OR IGNORE INTO student_prep (user_id, track, created_by) VALUES (?,?,?)`) .run(studentId, track, req.user.id); res.json({ ok: true }); } /* ── DELETE /api/prep/student/:id?track= — снять флаг ── */ function unsetStudent(req, res) { const studentId = Number(req.params.id) || 0; const track = String(req.query.track || ''); if (!prepTracks.isTrack(track)) return res.status(400).json({ error: 'Неизвестный трек' }); if (!canManageStudent(req.user, studentId)) return res.status(403).json({ error: 'Forbidden' }); db.prepare(`DELETE FROM student_prep WHERE user_id = ? AND track = ?`).run(studentId, track); res.json({ ok: true }); } /* ── GET /api/prep/class/:id?track= — статус флага у членов класса ── */ function classStatus(req, res) { const classId = Number(req.params.id) || 0; const track = String(req.query.track || ''); if (!prepTracks.isTrack(track)) return res.status(400).json({ error: 'Неизвестный трек' }); if (!canManageClass(req.user, classId)) return res.status(403).json({ error: 'Forbidden' }); const rows = db.prepare(` SELECT u.id, u.name, CASE WHEN sp.id IS NULL THEN 0 ELSE 1 END AS prep FROM class_members cm JOIN users u ON u.id = cm.user_id LEFT JOIN student_prep sp ON sp.user_id = u.id AND sp.track = ? WHERE cm.class_id = ? ORDER BY u.name `).all(track, classId); res.json({ students: rows }); } /* ── POST /api/prep/class/:id { track, on } — массово по классу ── */ function setClass(req, res) { const classId = Number(req.params.id) || 0; const track = String(req.body.track || ''); const on = !!req.body.on; if (!prepTracks.isTrack(track)) return res.status(400).json({ error: 'Неизвестный трек' }); if (!canManageClass(req.user, classId)) return res.status(403).json({ error: 'Forbidden' }); const members = db.prepare(`SELECT user_id FROM class_members WHERE class_id = ?`).all(classId); const ins = db.prepare(`INSERT OR IGNORE INTO student_prep (user_id, track, created_by) VALUES (?,?,?)`); const del = db.prepare(`DELETE FROM student_prep WHERE user_id = ? AND track = ?`); const run = db.transaction(() => { for (const m of members) on ? ins.run(m.user_id, track, req.user.id) : del.run(m.user_id, track); }); run(); res.json({ ok: true, count: members.length }); } module.exports = { listTracks, myTracks, studentTracks, setStudent, unsetStudent, classStatus, setClass, };