be4d43105e
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>
45 lines
1.9 KiB
JavaScript
45 lines
1.9 KiB
JavaScript
const router = require('express').Router();
|
|
const db = require('../db/db');
|
|
const { authMiddleware, requireRole } = require('../middleware/auth');
|
|
|
|
router.get('/', (_req, res) => {
|
|
res.json(db.prepare(`
|
|
SELECT s.*, (SELECT COUNT(*) FROM questions q WHERE q.subject_id = s.id) AS question_count
|
|
FROM subjects s ORDER BY s.id
|
|
`).all());
|
|
});
|
|
|
|
router.patch('/:slug', authMiddleware, requireRole('admin'), (req, res) => {
|
|
const { default_mode, default_count, default_test_id } = req.body;
|
|
const valid_modes = ['exam', 'practice', 'topic', 'random'];
|
|
if (default_mode && !valid_modes.includes(default_mode))
|
|
return res.status(400).json({ error: 'Invalid mode' });
|
|
|
|
const subj = db.prepare('SELECT id FROM subjects WHERE slug = ?').get(req.params.slug);
|
|
if (!subj) return res.status(404).json({ error: 'Subject not found' });
|
|
|
|
const updates = [];
|
|
const args = [];
|
|
if (default_mode !== undefined) { updates.push('default_mode = ?'); args.push(default_mode); }
|
|
if (default_count !== undefined) { updates.push('default_count = ?'); args.push(Number(default_count) || 25); }
|
|
if (default_test_id !== undefined) { updates.push('default_test_id = ?'); args.push(default_test_id || null); }
|
|
if (!updates.length) return res.status(400).json({ error: 'Nothing to update' });
|
|
|
|
args.push(req.params.slug);
|
|
db.prepare(`UPDATE subjects SET ${updates.join(', ')} WHERE slug = ?`).run(...args);
|
|
res.json(db.prepare('SELECT * FROM subjects WHERE slug = ?').get(req.params.slug));
|
|
});
|
|
|
|
router.get('/:slug/topics', (req, res) => {
|
|
const subject = db.prepare('SELECT id FROM subjects WHERE slug = ?').get(req.params.slug);
|
|
if (!subject) return res.status(404).json({ error: 'Subject not found' });
|
|
|
|
const topics = db.prepare(
|
|
'SELECT MIN(id) AS id, subject_id, name, MIN(order_index) AS order_index FROM topics WHERE subject_id = ? GROUP BY name ORDER BY MIN(order_index)'
|
|
).all(subject.id);
|
|
|
|
res.json(topics);
|
|
});
|
|
|
|
module.exports = router;
|