'use strict'; const db = require('../db/db'); function _tier(total, correct) { if (total === 0) return 'locked'; const pct = correct / total * 100; if (total >= 10 && pct >= 90) return 'platinum'; if (total >= 5 && pct >= 80) return 'gold'; if (total >= 3 && pct >= 50) return 'silver'; if (correct >= 1) return 'bronze'; return 'locked'; } /* ── GET /api/collection ──────────────────────────────────────────────── */ function getCollection(req, res) { const rows = db.prepare(` SELECT t.id AS topic_id, t.name AS topic_name, s.name AS subject_name, s.slug AS subject_slug, s.icon AS subject_icon, COALESCE(agg.total_attempts, 0) AS total_attempts, COALESCE(agg.correct_count, 0) AS correct_count, agg.first_seen_at FROM topics t JOIN subjects s ON s.id = t.subject_id LEFT JOIN ( SELECT q.topic_id, COUNT(ua.id) AS total_attempts, SUM(CASE WHEN ua.is_correct=1 THEN 1 ELSE 0 END) AS correct_count, MIN(ua.answered_at) AS first_seen_at FROM user_answers ua JOIN questions q ON q.id = ua.question_id WHERE ua.session_id IN ( SELECT id FROM test_sessions WHERE user_id = ? AND status = 'completed' ) GROUP BY q.topic_id ) agg ON agg.topic_id = t.id ORDER BY s.slug, t.order_index, t.name `).all(req.user.id); const cards = rows.map(r => ({ topicId: r.topic_id, topicName: r.topic_name, subjectName: r.subject_name, subjectSlug: r.subject_slug, subjectIcon: r.subject_icon, tier: _tier(r.total_attempts, r.correct_count), totalAttempts: r.total_attempts, correctCount: r.correct_count, masteryPct: r.total_attempts > 0 ? Math.round(r.correct_count / r.total_attempts * 100) : 0, firstSeenAt: r.first_seen_at || null, })); const unlocked = cards.filter(c => c.tier !== 'locked').length; res.json({ totalTopics: cards.length, unlockedTopics: unlocked, platinumCount: cards.filter(c => c.tier === 'platinum').length, goldCount: cards.filter(c => c.tier === 'gold').length, silverCount: cards.filter(c => c.tier === 'silver').length, bronzeCount: cards.filter(c => c.tier === 'bronze').length, cards, }); } module.exports = { getCollection };