'use strict'; /* Dashboard aggregates. /api/dashboard/activity — per-day study activity of the * current user across ALL engagement types (not just tests), for the activity * heatmap. Each source contributes a per-day count by type. */ const express = require('express'); const router = express.Router(); const db = require('../db/db'); const { authMiddleware } = require('../middleware/auth'); router.use(authMiddleware); const WINDOW_DAYS = 182; // ~6 months (max heatmap scale) /* GET /api/dashboard/activity → { days: { 'YYYY-MM-DD': { test, exam, cards, lesson, live, homework } } } */ router.get('/activity', (req, res) => { const uid = req.user.id; const days = {}; const add = (d, type, n) => { if (!d || !n) return; (days[d] || (days[d] = {}))[type] = (days[d][type] || 0) + n; }; // TEXT datetime sources use a SQL cutoff; exam_attempts stores epoch-ms. const txtCut = `datetime('now','-${WINDOW_DAYS} days')`; const epochCut = Date.now() - WINDOW_DAYS * 86400000; const sources = [ ['test', `SELECT DATE(started_at) d, COUNT(*) n FROM test_sessions WHERE user_id=? AND status='completed' AND started_at >= ${txtCut} GROUP BY d`, [uid]], ['exam', `SELECT DATE(created_at/1000,'unixepoch') d, COUNT(*) n FROM exam_attempts WHERE user_id=? AND created_at >= ? GROUP BY d`, [uid, epochCut]], ['cards', `SELECT DATE(last_reviewed) d, COUNT(*) n FROM flashcard_reviews WHERE user_id=? AND last_reviewed IS NOT NULL AND last_reviewed >= ${txtCut} GROUP BY d`, [uid]], ['lesson', `SELECT DATE(updated_at) d, COUNT(*) n FROM lesson_progress WHERE user_id=? AND completed=1 AND updated_at >= ${txtCut} GROUP BY d`, [uid]], ['live', `SELECT DATE(joined_at) d, COUNT(*) n FROM classroom_attendance WHERE user_id=? AND joined_at >= ${txtCut} GROUP BY d`, [uid]], ['homework', `SELECT DATE(completed_at) d, COUNT(*) n FROM assignment_completion WHERE user_id=? AND completed_at >= ${txtCut} GROUP BY d`, [uid]], ]; for (const [type, sql, args] of sources) { try { db.prepare(sql).all(...args).forEach(r => add(r.d, type, r.n)); } catch (e) { /* tolerate a missing/legacy table — skip that source */ } } res.json({ days }); }); module.exports = router;