import type { AdminUser } from '@core/admin/domain/entities/AdminUser'; import type { AdminUserRepository } from '@core/admin/domain/repositories/AdminUserRepository'; import { AuthorizationService } from '@core/admin/domain/services/AuthorizationService'; import { UserId } from '@core/admin/domain/value-objects/UserId'; import type { UserRole } from '@core/admin/domain/value-objects/UserRole'; import { Result } from '@core/shared/domain/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; export interface DashboardStatsResult { totalUsers: number; activeUsers: number; suspendedUsers: number; deletedUsers: number; systemAdmins: number; recentLogins: number; newUsersToday: number; userGrowth: { label: string; value: number; color: string; }[]; roleDistribution: { label: string; value: number; color: string; }[]; statusDistribution: { active: number; suspended: number; deleted: number; }; activityTimeline: { date: string; newUsers: number; logins: number; }[]; } export type GetDashboardStatsInput = { actorId: string; }; export type GetDashboardStatsErrorCode = 'AUTHORIZATION_ERROR' | 'REPOSITORY_ERROR'; export type GetDashboardStatsApplicationError = ApplicationErrorCode; export class GetDashboardStatsUseCase { constructor( private readonly adminUserRepo: AdminUserRepository, ) {} async execute(input: GetDashboardStatsInput): Promise> { try { // Get actor (current user) const actor = await this.adminUserRepo.findById(UserId.fromString(input.actorId)); if (!actor) { return Result.err({ code: 'AUTHORIZATION_ERROR', details: { message: 'Actor not found' }, }); } // Check authorization if (!AuthorizationService.canListUsers(actor)) { return Result.err({ code: 'AUTHORIZATION_ERROR', details: { message: 'User is not authorized to view dashboard' }, }); } // Get all users const allUsersResult = await this.adminUserRepo.list(); const allUsers = allUsersResult.users; // Calculate basic stats const totalUsers = allUsers.length; const activeUsers = allUsers.filter((u: AdminUser) => u.status.value === 'active').length; const suspendedUsers = allUsers.filter((u: AdminUser) => u.status.value === 'suspended').length; const deletedUsers = allUsers.filter((u: AdminUser) => u.status.value === 'deleted').length; const systemAdmins = allUsers.filter((u: AdminUser) => u.isSystemAdmin()).length; // Recent logins (last 24 hours) const oneDayAgo = new Date(); oneDayAgo.setDate(oneDayAgo.getDate() - 1); const recentLogins = allUsers.filter((u: AdminUser) => u.lastLoginAt && u.lastLoginAt > oneDayAgo).length; // New users today const today = new Date(); today.setHours(0, 0, 0, 0); const newUsersToday = allUsers.filter((u: AdminUser) => u.createdAt > today).length; // Role distribution const roleCounts: Record = {}; allUsers.forEach((user: AdminUser) => { user.roles.forEach((role: UserRole) => { const roleValue = role.value; roleCounts[roleValue] = (roleCounts[roleValue] || 0) + 1; }); }); const roleDistribution = Object.entries(roleCounts).map(([role, count]) => ({ label: role.charAt(0).toUpperCase() + role.slice(1), value: count, color: role === 'owner' ? 'text-purple-500' : role === 'admin' ? 'text-blue-500' : 'text-gray-500', })); // User growth (last 7 days) const userGrowth: DashboardStatsResult['userGrowth'] = []; if (allUsers.length > 0) { for (let i = 6; i >= 0; i--) { const date = new Date(); date.setDate(date.getDate() - i); const dateStr = date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }); const count = allUsers.filter((u: AdminUser) => { const userDate = u.createdAt; return userDate.toDateString() === date.toDateString(); }).length; userGrowth.push({ label: dateStr, value: count, color: 'text-primary-blue', }); } } // Activity timeline (last 7 days) const activityTimeline: DashboardStatsResult['activityTimeline'] = []; if (allUsers.length > 0) { for (let i = 6; i >= 0; i--) { const date = new Date(); date.setDate(date.getDate() - i); const dateStr = date.toLocaleDateString('en-US', { month: 'short', day: 'numeric' }); const newUsers = allUsers.filter((u: AdminUser) => { const userDate = u.createdAt; return userDate.toDateString() === date.toDateString(); }).length; const logins = allUsers.filter((u: AdminUser) => { const loginDate = u.lastLoginAt; return loginDate && loginDate.toDateString() === date.toDateString(); }).length; activityTimeline.push({ date: dateStr, newUsers, logins, }); } } const result: DashboardStatsResult = { totalUsers, activeUsers, suspendedUsers, deletedUsers, systemAdmins, recentLogins, newUsersToday, userGrowth, roleDistribution, statusDistribution: { active: activeUsers, suspended: suspendedUsers, deleted: deletedUsers, }, activityTimeline, }; return Result.ok(result); } catch (error) { const message = error instanceof Error ? error.message : 'Failed to get dashboard stats'; return Result.err({ code: 'REPOSITORY_ERROR', details: { message }, }); } } }