import { Router } from 'express'; import db from '../db/index.js'; import { requireAuth } from '../auth/middleware.js'; import { getGame } from '../games/registry.js'; const router = Router(); // GET /api/puzzles/:slug/progress // Returns the highest contiguous level the signed-in user has cleared. router.get('/:slug/progress', requireAuth, (req, res) => { const { slug } = req.params; if (!getGame(slug)) return res.status(400).json({ error: 'Unknown game slug.' }); const row = db .prepare('SELECT levels_completed FROM puzzle_progress WHERE user_id = ? AND slug = ?') .get(req.user.id, slug); res.json({ levelsCompleted: row?.levels_completed ?? 0 }); }); // POST /api/puzzles/:slug/complete body: { level } // Records completion of `level`. Levels must be cleared in order, so this only // advances progress when level === current + 1; replaying an earlier level is a // no-op that still returns the current high-water mark. router.post('/:slug/complete', requireAuth, (req, res) => { const { slug } = req.params; const { level } = req.body ?? {}; if (!getGame(slug)) return res.status(400).json({ error: 'Unknown game slug.' }); if (!Number.isInteger(level) || level < 1) { return res.status(400).json({ error: 'Invalid level.' }); } const row = db .prepare('SELECT levels_completed FROM puzzle_progress WHERE user_id = ? AND slug = ?') .get(req.user.id, slug); const current = row?.levels_completed ?? 0; if (level !== current + 1) { return res.json({ levelsCompleted: current }); } db.prepare( `INSERT INTO puzzle_progress (user_id, slug, levels_completed, updated_at) VALUES (?, ?, ?, datetime('now')) ON CONFLICT(user_id, slug) DO UPDATE SET levels_completed = excluded.levels_completed, updated_at = excluded.updated_at`, ).run(req.user.id, slug, level); res.json({ levelsCompleted: level }); }); // POST /api/puzzles/:slug/reset // Clears the signed-in user's progress for this puzzle (back to level 0). router.post('/:slug/reset', requireAuth, (req, res) => { const { slug } = req.params; if (!getGame(slug)) return res.status(400).json({ error: 'Unknown game slug.' }); db.prepare('DELETE FROM puzzle_progress WHERE user_id = ? AND slug = ?').run(req.user.id, slug); res.json({ levelsCompleted: 0 }); }); export default router;