/*********************************************************************************************************************************************************************** * File Name: dashboard.controller.js (admin) * Type of Program: Controller * Description: Admin dashboard — users and groups stats + breakdowns. * * Author: rgrgogu * Date Created: Oct. 6, 2025 ***********************************************************************************************************************************************************************/ const { Op, fn, col, literal } = require('sequelize'); const mdl_Users = require('../../models/users/users.mdl'); const { mdl_UserGroups, mdl_UserGroupMembers } = require('../../models/users/user_groups.mdl'); // ─── USERS DASHBOARD ────────────────────────────────────────────────────────── exports.getUsersDashboard = async (req, res) => { try { const [ totalUsers, activeUsers, verifiedUsers, archivedUsers, accTypeBreakdown, regTypeBreakdown, ] = await Promise.all([ mdl_Users.count({ paranoid: false }), mdl_Users.count({ where: { is_active: true } }), mdl_Users.count({ where: { is_verified: true } }), mdl_Users.count({ where: { deletedAt: { [Op.ne]: null } }, paranoid: false }), mdl_Users.findAll({ attributes: ['acc_type', [fn('COUNT', col('user_id')), 'count']], group: ['acc_type'], raw: true, }), mdl_Users.findAll({ attributes: ['reg_type', [fn('COUNT', col('user_id')), 'count']], group: ['reg_type'], raw: true, }), ]); return res.status(200).json({ status: 'success', message: 'Users dashboard data fetched.', data: { stats: [ { key: 'total', label: 'Total Users', value: totalUsers }, { key: 'active', label: 'Active Users', value: activeUsers }, { key: 'inactive', label: 'Inactive Users', value: totalUsers - archivedUsers - activeUsers }, { key: 'verified', label: 'Verified', value: verifiedUsers }, { key: 'archived', label: 'Archived', value: archivedUsers }, ], breakdowns: [ { key: 'acc_type', label: 'By Account Type', data: accTypeBreakdown.map((r) => ({ label: r.acc_type, value: parseInt(r.count, 10) })), }, { key: 'reg_type', label: 'By Registration Type', data: regTypeBreakdown.map((r) => ({ label: r.reg_type, value: parseInt(r.count, 10) })), }, ], }, }); } catch (err) { console.error('[ADMIN][DASHBOARD][USERS]', err); return res.status(500).json({ status: 'error', message: 'Could not fetch users dashboard data.' }); } }; // ─── GROUPS DASHBOARD ───────────────────────────────────────────────────────── exports.getGroupsDashboard = async (req, res) => { try { const [ totalGroups, activeGroups, archivedGroups, emptyGroups, memberCountBreakdown, ] = await Promise.all([ mdl_UserGroups.count({ paranoid: false }), mdl_UserGroups.count({ where: { is_active: true } }), mdl_UserGroups.count({ where: { deletedAt: { [Op.ne]: null } }, paranoid: false }), mdl_UserGroups.count({ where: { is_active: true }, include: [{ model: mdl_UserGroupMembers, required: false, where: { deletedAt: null }, }], having: literal('COUNT("UserGroupMembers"."user_id") = 0'), group: ['UserGroup.group_id'], subQuery: false, }).catch(() => 0), mdl_UserGroupMembers.findAll({ attributes: [ 'group_id', [fn('COUNT', col('user_id')), 'member_count'], ], where: { deletedAt: null }, include: [{ model: mdl_UserGroups, attributes: ['name'], where: { is_active: true }, }], group: ['UserGroupMember.group_id', 'UserGroup.group_id', 'UserGroup.name'], order: [[literal('member_count'), 'DESC']], limit: 10, raw: true, nest: true, }), ]); return res.status(200).json({ status: 'success', message: 'Groups dashboard data fetched.', data: { stats: [ { key: 'total', label: 'Total Groups', value: totalGroups }, { key: 'active', label: 'Active Groups', value: activeGroups }, { key: 'inactive', label: 'Inactive Groups', value: totalGroups - archivedGroups - activeGroups }, { key: 'archived', label: 'Archived', value: archivedGroups }, { key: 'empty', label: 'Empty Groups', value: Array.isArray(emptyGroups) ? emptyGroups.length : emptyGroups }, ], breakdowns: [ { key: 'top_groups', label: 'Top Groups by Members', data: memberCountBreakdown.map((r) => ({ label: r.UserGroup?.name ?? `Group ${r.group_id}`, value: parseInt(r.member_count, 10), })), }, ], }, }); } catch (err) { console.error('[ADMIN][DASHBOARD][GROUPS]', err); return res.status(500).json({ status: 'error', message: 'Could not fetch groups dashboard data.' }); } };