Files
Learn_System/backend/src/controllers/knowledgeMapController.js
T
Maxim Dolgolyov be4d43105e LearnSpace: full-stack educational whiteboard platform
Node.js/Express backend + vanilla JS frontend.
Features: real-time collaborative whiteboard (SSE), multi-page support,
LaTeX formulas, shapes/connectors, coordinate systems, number lines,
compass, zoom/pan, Catmull-Rom pencil smoothing, ruler/protractor with
rotation & resize controls, minimap navigation overlay, auto-measurements,
multi-page thumbnails sidebar, PNG export, page templates.
Student/teacher workflows: classes, assignments, library, dashboard.
Mobile responsive. SQLite (better-sqlite3).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 10:10:37 +03:00

66 lines
1.8 KiB
JavaScript

'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 };