Files
gridpilot.gg/apps/api/src/domain/dashboard/DashboardService.ts
2026-01-01 15:17:09 +01:00

237 lines
7.3 KiB
TypeScript

import { DashboardOverviewUseCase } from '@core/racing/application/use-cases/DashboardOverviewUseCase';
import { Inject, Injectable } from '@nestjs/common';
import { DashboardOverviewDTO } from './dtos/DashboardOverviewDTO';
import { DashboardOverviewPresenter } from './presenters/DashboardOverviewPresenter';
// Core imports
import type { Logger } from '@core/shared/application/Logger';
import type { ImageServicePort } from '@core/media/application/ports/ImageServicePort';
// Tokens (standalone to avoid circular imports)
import {
DASHBOARD_OVERVIEW_OUTPUT_PORT_TOKEN,
DASHBOARD_OVERVIEW_USE_CASE_TOKEN,
IMAGE_SERVICE_TOKEN,
LOGGER_TOKEN,
} from './DashboardTokens';
@Injectable()
export class DashboardService {
constructor(
@Inject(LOGGER_TOKEN) private readonly logger: Logger,
@Inject(DASHBOARD_OVERVIEW_USE_CASE_TOKEN) private readonly dashboardOverviewUseCase: DashboardOverviewUseCase,
@Inject(DASHBOARD_OVERVIEW_OUTPUT_PORT_TOKEN) private readonly presenter: DashboardOverviewPresenter,
@Inject(IMAGE_SERVICE_TOKEN) private readonly imageService: ImageServicePort,
) {}
async getDashboardOverview(driverId: string): Promise<DashboardOverviewDTO> {
this.logger.debug('[DashboardService] Getting dashboard overview:', { driverId });
// Check if this is a demo user
const isDemoUser = driverId.startsWith('demo-driver-') ||
driverId.startsWith('demo-sponsor-') ||
driverId.startsWith('demo-league-owner-') ||
driverId.startsWith('demo-league-steward-') ||
driverId.startsWith('demo-league-admin-') ||
driverId.startsWith('demo-system-owner-') ||
driverId.startsWith('demo-super-admin-');
if (isDemoUser) {
// Return mock dashboard data for demo users
this.logger.info('[DashboardService] Returning mock data for demo user', { driverId });
return await this.getMockDashboardData(driverId);
}
const result = await this.dashboardOverviewUseCase.execute({ driverId });
if (result.isErr()) {
const error = result.error;
const message = error?.details?.message || 'Unknown error';
throw new Error(`Failed to get dashboard overview: ${message}`);
}
return this.presenter.getResponseModel();
}
private async getMockDashboardData(driverId: string): Promise<DashboardOverviewDTO> {
// Determine role from driverId prefix
const isSponsor = driverId.startsWith('demo-sponsor-');
const isLeagueOwner = driverId.startsWith('demo-league-owner-');
const isLeagueSteward = driverId.startsWith('demo-league-steward-');
const isLeagueAdmin = driverId.startsWith('demo-league-admin-');
const isSystemOwner = driverId.startsWith('demo-system-owner-');
const isSuperAdmin = driverId.startsWith('demo-super-admin-');
// Get avatar URL using the image service (same as real drivers)
const avatarUrl = this.imageService.getDriverAvatar(driverId);
// Mock sponsor dashboard
if (isSponsor) {
return {
currentDriver: null,
myUpcomingRaces: [],
otherUpcomingRaces: [],
upcomingRaces: [],
activeLeaguesCount: 0,
nextRace: null,
recentResults: [],
leagueStandingsSummaries: [],
feedSummary: {
notificationCount: 0,
items: [],
},
friends: [],
};
}
// Mock league admin/owner/steward dashboard (similar to driver but with more leagues)
if (isLeagueOwner || isLeagueSteward || isLeagueAdmin) {
const roleTitle = isLeagueOwner ? 'League Owner' : isLeagueSteward ? 'League Steward' : 'League Admin';
return {
currentDriver: {
id: driverId,
name: `Demo ${roleTitle}`,
country: 'US',
avatarUrl,
rating: 1600,
globalRank: 15,
totalRaces: 8,
wins: 3,
podiums: 5,
consistency: 90,
},
myUpcomingRaces: [],
otherUpcomingRaces: [],
upcomingRaces: [],
activeLeaguesCount: 2,
nextRace: null,
recentResults: [],
leagueStandingsSummaries: [],
feedSummary: {
notificationCount: 2,
items: [
{
id: 'feed-1',
type: 'league_update',
headline: 'New league season starting',
body: 'Your league "Demo League" is about to start a new season',
timestamp: new Date().toISOString(),
ctaLabel: 'View League',
ctaHref: '/leagues',
},
],
},
friends: [],
};
}
// Mock system owner dashboard (highest privileges)
if (isSystemOwner) {
return {
currentDriver: {
id: driverId,
name: 'System Owner',
country: 'US',
avatarUrl,
rating: 2000,
globalRank: 1,
totalRaces: 50,
wins: 25,
podiums: 40,
consistency: 95,
},
myUpcomingRaces: [],
otherUpcomingRaces: [],
upcomingRaces: [],
activeLeaguesCount: 10,
nextRace: null,
recentResults: [],
leagueStandingsSummaries: [],
feedSummary: {
notificationCount: 5,
items: [
{
id: 'feed-1',
type: 'system_alert',
headline: 'System maintenance scheduled',
body: 'Platform will undergo maintenance in 24 hours',
timestamp: new Date().toISOString(),
ctaLabel: 'View Details',
ctaHref: '/admin/system',
},
],
},
friends: [],
};
}
// Mock super admin dashboard (all access)
if (isSuperAdmin) {
return {
currentDriver: {
id: driverId,
name: 'Super Admin',
country: 'US',
avatarUrl,
rating: 1800,
globalRank: 5,
totalRaces: 30,
wins: 15,
podiums: 25,
consistency: 92,
},
myUpcomingRaces: [],
otherUpcomingRaces: [],
upcomingRaces: [],
activeLeaguesCount: 5,
nextRace: null,
recentResults: [],
leagueStandingsSummaries: [],
feedSummary: {
notificationCount: 3,
items: [
{
id: 'feed-1',
type: 'admin_notification',
headline: 'Admin dashboard access granted',
body: 'You have full administrative access to all platform features',
timestamp: new Date().toISOString(),
ctaLabel: 'Admin Panel',
ctaHref: '/admin',
},
],
},
friends: [],
};
}
// Mock driver dashboard (default)
return {
currentDriver: {
id: driverId,
name: 'John Demo',
country: 'US',
avatarUrl,
rating: 1500,
globalRank: 25,
totalRaces: 5,
wins: 2,
podiums: 3,
consistency: 85,
},
myUpcomingRaces: [],
otherUpcomingRaces: [],
upcomingRaces: [],
activeLeaguesCount: 0,
nextRace: null,
recentResults: [],
leagueStandingsSummaries: [],
feedSummary: {
notificationCount: 0,
items: [],
},
friends: [],
};
}
}