Files
gameno-api/components/dashboard/dashboardService.js
T
kavehhn f04c797be6 Initial commit: teaching institution management API.
Express/MongoDB backend with JWT auth, RBAC, S3 uploads, notifications, and scheduled jobs.
2026-08-09 04:18:08 +02:00

124 lines
3.2 KiB
JavaScript

// /components/dashboard/dashboardService.js
'use strict';
const User = require('../users/userModel');
const Professor = require('../professors/professorModel');
const Course = require('../courses/courseModel');
const Session = require('../sessions/sessionModel');
/**
* Returns aggregated statistics for the admin dashboard
*/
const getAdminStats = async () => {
const [
totalUsers,
activeUsers,
totalProfessors,
activeProfessors,
totalCourses,
totalSessions,
recentSessions
] = await Promise.all([
User.countDocuments({}),
User.countDocuments({ isActive: true }),
Professor.countDocuments({}),
Professor.countDocuments({ isActive: true }),
Course.countDocuments({}),
Session.countDocuments({}),
Session.find({})
.sort({ day: -1 })
.limit(8)
.populate('course', 'title type')
.populate('class', 'name')
.populate('professor', 'name surname')
.lean()
]);
// Daily enrollment trend (last 14 days via User.createdAt)
const daysBack = 13;
const rangeStart = new Date();
rangeStart.setHours(0, 0, 0, 0);
rangeStart.setDate(rangeStart.getDate() - daysBack);
const dailyUsersRaw = await User.aggregate([
{ $match: { createdAt: { $gte: rangeStart } } },
{
$group: {
_id: {
year: { $year: '$createdAt' },
month: { $month: '$createdAt' },
day: { $dayOfMonth: '$createdAt' }
},
count: { $sum: 1 }
}
},
{ $sort: { '_id.year': 1, '_id.month': 1, '_id.day': 1 } }
]);
// Fill every day in the range so the chart stays continuous
const dailyUsers = [];
for (let i = 0; i <= daysBack; i += 1) {
const date = new Date(rangeStart);
date.setDate(rangeStart.getDate() + i);
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const match = dailyUsersRaw.find(
(item) => item._id.year === year && item._id.month === month && item._id.day === day
);
dailyUsers.push({
_id: { year, month, day },
date: date.toISOString(),
count: match ? match.count : 0
});
}
// Daily sessions trend (same window)
const dailySessionsRaw = await Session.aggregate([
{ $match: { createdAt: { $gte: rangeStart } } },
{
$group: {
_id: {
year: { $year: '$createdAt' },
month: { $month: '$createdAt' },
day: { $dayOfMonth: '$createdAt' }
},
count: { $sum: 1 }
}
},
{ $sort: { '_id.year': 1, '_id.month': 1, '_id.day': 1 } }
]);
const dailySessions = dailyUsers.map((day) => {
const match = dailySessionsRaw.find(
(item) =>
item._id.year === day._id.year &&
item._id.month === day._id.month &&
item._id.day === day._id.day
);
return {
_id: day._id,
date: day.date,
count: match ? match.count : 0
};
});
return {
totals: {
users: totalUsers,
activeUsers,
professors: totalProfessors,
activeProfessors,
courses: totalCourses,
sessions: totalSessions
},
recentSessions,
charts: {
dailyUsers,
dailySessions
}
};
};
module.exports = { getAdminStats };