'use strict'; const db = require('../db/db'); /* ── GET /api/knowledge-map?subject_slug=bio ──────────────────────────── */ function getMap(req, res) { const { subject_slug } = req.query; const uid = req.user.id; let subjects; if (subject_slug) { subjects = db.prepare('SELECT id, slug, name, icon FROM subjects WHERE slug = ?').all(subject_slug); } else { subjects = db.prepare('SELECT id, slug, name, icon FROM subjects ORDER BY name').all(); } const nodes = []; const links = []; for (const subj of subjects) { nodes.push({ id: `subj_${subj.id}`, type: 'subject', label: subj.name, icon: subj.icon, slug: subj.slug, mastery: null, }); const topics = db.prepare(` SELECT t.id, t.name, COUNT(DISTINCT q.id) AS total_q, COUNT(DISTINCT CASE WHEN ua.is_correct = 1 THEN ua.question_id END) AS correct_q FROM topics t LEFT JOIN questions q ON q.topic_id = t.id LEFT JOIN user_answers ua ON ua.question_id = q.id AND ua.session_id IN ( SELECT id FROM test_sessions WHERE user_id = ? AND status = 'completed' ) WHERE t.subject_id = ? GROUP BY t.id ORDER BY t.order_index `).all(uid, subj.id); for (const topic of topics) { const mastery = topic.total_q > 0 ? Math.round((topic.correct_q / topic.total_q) * 100) : null; nodes.push({ id: `topic_${topic.id}`, type: 'topic', label: topic.name, mastery, totalQ: topic.total_q, correctQ: topic.correct_q, }); links.push({ source: `subj_${subj.id}`, target: `topic_${topic.id}` }); } } res.json({ nodes, links }); } module.exports = { getMap };