This commit is contained in:
2025-12-16 13:53:23 +01:00
parent 84f05598a6
commit 29dc11deb9
127 changed files with 538 additions and 547 deletions

View File

@@ -1,6 +1,6 @@
import { Global, Module } from '@nestjs/common';
import { Logger } from '@core/shared/application/Logger';
import { ConsoleLogger } from '@core//logging/ConsoleLogger';
import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
@Global()
@Module({

View File

@@ -1,6 +1,6 @@
import { Controller, Post, Body, Res, HttpStatus } from '@nestjs/common';
import { Response } from 'express';
import { RecordPageViewInput, RecordPageViewOutput, RecordEngagementInput, RecordEngagementOutput } from './dto/AnalyticsDto';
import type { Response } from 'express';
import type { RecordPageViewInput, RecordPageViewOutput, RecordEngagementInput, RecordEngagementOutput } from './dto/AnalyticsDto';
import { AnalyticsService } from './AnalyticsService';
@Controller('analytics')

View File

@@ -9,13 +9,13 @@ const IENGAGEMENT_REPO_TOKEN = 'IEngagementRepository_TOKEN';
const RECORD_PAGE_VIEW_USE_CASE_TOKEN = 'RecordPageViewUseCase_TOKEN';
const RECORD_ENGAGEMENT_USE_CASE_TOKEN = 'RecordEngagementUseCase_TOKEN';
import { Logger } from '@core/shared/application';
import { IPageViewRepository } from '@core/analytics/application/repositories/IPageViewRepository';
import { IEngagementRepository } from '@core/analytics/domain/repositories/IEngagementRepository';
import type { Logger } from '@core/shared/application';
import type { IPageViewRepository } from '@core/analytics/application/repositories/IPageViewRepository';
import type { IEngagementRepository } from '@core/analytics/domain/repositories/IEngagementRepository';
import { ConsoleLogger } from '../../../..//logging/ConsoleLogger';
import { InMemoryPageViewRepository } from '../../../..//analytics/persistence/inmemory/InMemoryPageViewRepository';
import { InMemoryEngagementRepository } from '../../../..//analytics/persistence/inmemory/InMemoryEngagementRepository';
import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
import { InMemoryPageViewRepository } from '@adapters/analytics/persistence/inmemory/InMemoryPageViewRepository';
import { InMemoryEngagementRepository } from '@adapters/analytics/persistence/inmemory/InMemoryEngagementRepository';
export const AnalyticsProviders: Provider[] = [
AnalyticsService,

View File

@@ -1,6 +1,6 @@
import { Injectable, Inject } from '@nestjs/common';
import { RecordEngagementInput, RecordEngagementOutput, RecordPageViewInput, RecordPageViewOutput } from './dto/AnalyticsDto';
import { Logger } from '@core/shared/application';
import type { Logger } from '@core/shared/application';
import { RecordPageViewUseCase } from './use-cases/RecordPageViewUseCase';
import { RecordEngagementUseCase } from './use-cases/RecordEngagementUseCase';

View File

@@ -20,11 +20,11 @@ export enum VisitorType {
export class RecordPageViewInput {
@ApiProperty({ enum: EntityType })
@IsEnum(EntityType)
entityType: EntityType;
entityType!: EntityType;
@ApiProperty()
@IsString()
entityId: string;
entityId!: string;
@ApiProperty({ required: false })
@IsOptional()
@@ -33,11 +33,11 @@ export class RecordPageViewInput {
@ApiProperty({ enum: VisitorType })
@IsEnum(VisitorType)
visitorType: VisitorType;
visitorType!: VisitorType;
@ApiProperty()
@IsString()
sessionId: string;
sessionId!: string;
@ApiProperty({ required: false })
@IsOptional()
@@ -58,7 +58,7 @@ export class RecordPageViewInput {
export class RecordPageViewOutput {
@ApiProperty()
@IsString()
pageViewId: string;
pageViewId!: string;
}
// From core/analytics/domain/types/EngagementEvent.ts
@@ -87,15 +87,15 @@ export enum EngagementEntityType {
export class RecordEngagementInput {
@ApiProperty({ enum: EngagementAction })
@IsEnum(EngagementAction)
action: EngagementAction;
action!: EngagementAction;
@ApiProperty({ enum: EngagementEntityType })
@IsEnum(EngagementEntityType)
entityType: EngagementEntityType;
entityType!: EngagementEntityType;
@ApiProperty()
@IsString()
entityId: string;
entityId!: string;
@ApiProperty({ required: false })
@IsOptional()
@@ -104,13 +104,13 @@ export class RecordEngagementInput {
@ApiProperty({ enum: ['anonymous', 'driver', 'sponsor'] })
@IsEnum(['anonymous', 'driver', 'sponsor'])
actorType: 'anonymous' | 'driver' | 'sponsor';
actorType!: 'anonymous' | 'driver' | 'sponsor';
@ApiProperty()
@IsString()
sessionId: string;
sessionId!: string;
@ApiProperty({ required: false, type: 'object'/*, additionalProperties: { type: 'string' || 'number' || 'boolean' }*/ })
@ApiProperty({ required: false, type: Object })
@IsOptional()
@IsObject()
metadata?: Record<string, string | number | boolean>;
@@ -119,9 +119,9 @@ export class RecordEngagementInput {
export class RecordEngagementOutput {
@ApiProperty()
@IsString()
eventId: string;
eventId!: string;
@ApiProperty()
@IsNumber()
engagementWeight: number;
engagementWeight!: number;
}

View File

@@ -1,7 +1,7 @@
import { Test, TestingModule } from '@nestjs/testing';
import { RecordEngagementUseCase } from './RecordEngagementUseCase';
import { IEngagementRepository } from '@core/analytics/domain/repositories/IEngagementRepository';
import { Logger } from '@core/shared/application';
import type { IEngagementRepository } from '@core/analytics/domain/repositories/IEngagementRepository';
import type { Logger } from '@core/shared/application';
describe('RecordEngagementUseCase', () => {
let useCase: RecordEngagementUseCase;

View File

@@ -1,7 +1,7 @@
import { Injectable, Inject } from '@nestjs/common';
import { RecordEngagementInput, RecordEngagementOutput } from '../dto/AnalyticsDto';
import { IEngagementRepository } from '@core/analytics/domain/repositories/IEngagementRepository';
import { Logger } from '@core/shared/application';
import type { IEngagementRepository } from '@core/analytics/domain/repositories/IEngagementRepository';
import type { Logger } from '@core/shared/application';
import { EngagementEvent } from '@core/analytics/domain/entities/EngagementEvent';
const Logger_TOKEN = 'Logger_TOKEN';

View File

@@ -1,7 +1,7 @@
import { Test, TestingModule } from '@nestjs/testing';
import { RecordPageViewUseCase } from './RecordPageViewUseCase';
import { IPageViewRepository } from '@core/analytics/application/repositories/IPageViewRepository';
import { Logger } from '@core/shared/application';
import type { IPageViewRepository } from '@core/analytics/application/repositories/IPageViewRepository';
import type { Logger } from '@core/shared/application';
describe('RecordPageViewUseCase', () => {
let useCase: RecordPageViewUseCase;

View File

@@ -1,7 +1,7 @@
import { Injectable, Inject } from '@nestjs/common';
import { RecordPageViewInput, RecordPageViewOutput } from '../dto/AnalyticsDto';
import { IPageViewRepository } from '@core/analytics/application/repositories/IPageViewRepository';
import { Logger } from '@core/shared/application';
import type { IPageViewRepository } from '@core/analytics/application/repositories/IPageViewRepository';
import type { Logger } from '@core/shared/application';
import { PageView } from '@core/analytics/domain/entities/PageView';
const Logger_TOKEN = 'Logger_TOKEN';

View File

@@ -2,17 +2,17 @@ import { Provider } from '@nestjs/common';
import { AuthService } from './AuthService';
// Import interfaces and concrete implementations
import { IAuthRepository } from '@core/identity/domain/repositories/IAuthRepository';
import type { IAuthRepository } from '@core/identity/domain/repositories/IAuthRepository';
import { IUserRepository, StoredUser } from '@core/identity/domain/repositories/IUserRepository';
import { IPasswordHashingService } from '@core/identity/domain/services/PasswordHashingService';
import { Logger } from '@core/shared/application';
import type { IPasswordHashingService } from '@core/identity/domain/services/PasswordHashingService';
import type { Logger } from '@core/shared/application';
import { InMemoryAuthRepository } from '../../..//identity/persistence/inmemory/InMemoryAuthRepository';
import { InMemoryUserRepository } from '../../..//identity/persistence/inmemory/InMemoryUserRepository';
import { InMemoryPasswordHashingService } from '../../..//identity/services/InMemoryPasswordHashingService';
import { ConsoleLogger } from '../../..//logging/ConsoleLogger';
import { IdentitySessionPort } from '@core/identity/application/ports/IdentitySessionPort'; // Path from apps/api/src/modules/auth
import { CookieIdentitySessionAdapter } from '../../..//identity/session/CookieIdentitySessionAdapter';
import { InMemoryAuthRepository } from '@adapters/identity/persistence/inmemory/InMemoryAuthRepository';
import { InMemoryUserRepository } from '@adapters/identity/persistence/inmemory/InMemoryUserRepository';
import { InMemoryPasswordHashingService } from '@adapters/identity/services/InMemoryPasswordHashingService';
import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
import { IdentitySessionPort } from '@core/identity/application/ports/IdentitySessionPort';
import { CookieIdentitySessionAdapter } from '@adapters/identity/session/CookieIdentitySessionAdapter';
// Define the tokens for dependency injection
export const AUTH_REPOSITORY_TOKEN = 'IAuthRepository';

View File

@@ -11,13 +11,13 @@ import { LoginWithIracingCallbackUseCase } from '@core/identity/application/use-
// Core Interfaces and Tokens
import { AUTH_REPOSITORY_TOKEN, PASSWORD_HASHING_SERVICE_TOKEN, LOGGER_TOKEN, IDENTITY_SESSION_PORT_TOKEN, USER_REPOSITORY_TOKEN } from './AuthProviders';
import { IAuthRepository } from '@core/identity/domain/repositories/IAuthRepository';
import { IPasswordHashingService } from '@core/identity/domain/services/PasswordHashingService';
import { Logger } from "@gridpilot/core/shared/application";
import type { IAuthRepository } from '@core/identity/domain/repositories/IAuthRepository';
import type { IPasswordHashingService } from '@core/identity/domain/services/PasswordHashingService';
import type { Logger } from "@core/shared/application";
import { IdentitySessionPort } from '@core/identity/application/ports/IdentitySessionPort';
import { UserId } from '@core/identity/domain/value-objects/UserId';
import { User } from '@core/identity/domain/entities/User';
import { IUserRepository } from '@core/identity/domain/repositories/IUserRepository';
import type { IUserRepository } from '@core/identity/domain/repositories/IUserRepository';
import { AuthenticatedUserDTO as CoreAuthenticatedUserDTO } from '@core/identity/application/dto/AuthenticatedUserDTO';
@Injectable()
@@ -47,8 +47,8 @@ export class AuthService {
private mapUserToAuthenticatedUserDTO(user: User): AuthenticatedUserDTO {
return {
userId: user.getId().value,
email: user.getEmail(),
displayName: user.getDisplayName(),
email: user.getEmail() ?? '',
displayName: user.getDisplayName() ?? '',
// Map other fields as necessary
iracingCustomerId: user.getIracingCustomerId() ?? undefined,
primaryDriverId: user.getPrimaryDriverId() ?? undefined,
@@ -106,7 +106,7 @@ export class AuthService {
user: authenticatedUserDTO,
};
} catch (error) {
this.logger.error(`[AuthService] Login failed for email ${params.email}:`, error);
this.logger.error(`[AuthService] Login failed for email ${params.email}:`, error instanceof Error ? error : new Error(String(error)));
throw new InternalServerErrorException('Login failed due to invalid credentials or server error.');
}
}

View File

@@ -2,27 +2,27 @@ import { ApiProperty } from '@nestjs/swagger';
export class AuthenticatedUserDTO {
@ApiProperty()
userId: string;
userId!: string;
@ApiProperty()
email: string;
email!: string;
@ApiProperty()
displayName: string;
displayName!: string;
}
export class AuthSessionDTO {
@ApiProperty()
token: string;
token!: string;
@ApiProperty()
user: AuthenticatedUserDTO;
user!: AuthenticatedUserDTO;
}
export class SignupParams {
@ApiProperty()
email: string;
email!: string;
@ApiProperty()
password: string;
password!: string;
@ApiProperty()
displayName: string;
displayName!: string;
@ApiProperty({ required: false })
iracingCustomerId?: string;
@ApiProperty({ required: false })
@@ -33,23 +33,23 @@ export class SignupParams {
export class LoginParams {
@ApiProperty()
email: string;
email!: string;
@ApiProperty()
password: string;
password!: string;
}
export class IracingAuthRedirectResult {
@ApiProperty()
redirectUrl: string;
redirectUrl!: string;
@ApiProperty()
state: string;
state!: string;
}
export class LoginWithIracingCallbackParams {
@ApiProperty()
code: string;
code!: string;
@ApiProperty()
state: string;
state!: string;
@ApiProperty({ required: false })
returnTo?: string;
}

View File

@@ -9,7 +9,7 @@ import { DriverRatingProvider } from '@core/racing/application/ports/DriverRatin
import { IImageServicePort } from '@core/racing/application/ports/IImageServicePort';
import { IRaceRegistrationRepository } from '@core/racing/domain/repositories/IRaceRegistrationRepository';
import { INotificationPreferenceRepository } from '@core/notifications/domain/repositories/INotificationPreferenceRepository';
import { Logger } from "@gridpilot/core/shared/application";
import type { Logger } from "@gridpilot/core/shared/application";
// Import use cases
import { GetDriversLeaderboardUseCase } from '@core/racing/application/use-cases/GetDriversLeaderboardUseCase';

View File

@@ -4,7 +4,7 @@ import { GetDriversLeaderboardUseCase } from '@core/racing/application/use-cases
import { GetTotalDriversUseCase } from '@core/racing/application/use-cases/GetTotalDriversUseCase';
import { CompleteDriverOnboardingUseCase } from '@core/racing/application/use-cases/CompleteDriverOnboardingUseCase';
import { IsDriverRegisteredForRaceUseCase } from '@core/racing/application/use-cases/IsDriverRegisteredForRaceUseCase';
import { Logger } from '@core/shared/application';
import type { Logger } from '@core/shared/application';
describe('DriverService', () => {
let service: DriverService;

View File

@@ -15,7 +15,7 @@ import { DriverRegistrationStatusPresenter } from './presenters/DriverRegistrati
// Tokens
import { GET_DRIVERS_LEADERBOARD_USE_CASE_TOKEN, GET_TOTAL_DRIVERS_USE_CASE_TOKEN, COMPLETE_DRIVER_ONBOARDING_USE_CASE_TOKEN, IS_DRIVER_REGISTERED_FOR_RACE_USE_CASE_TOKEN, LOGGER_TOKEN } from './DriverProviders';
import { Logger } from '@core/shared/application';
import type { Logger } from '@core/shared/application';
@Injectable()
export class DriverService {

View File

@@ -2,7 +2,7 @@ import { Provider } from '@nestjs/common';
import { LeagueService } from './LeagueService';
// Import core interfaces
import { Logger } from '@core/shared/application/Logger';
import type { Logger } from '@core/shared/application/Logger';
// Import concrete in-memory implementations
import { InMemoryLeagueRepository } from '@adapters/racing/persistence/inmemory/InMemoryLeagueRepository';

View File

@@ -13,7 +13,7 @@ import { RemoveLeagueMemberUseCase } from '@core/racing/application/use-cases/Re
import { UpdateLeagueMemberRoleUseCase } from '@core/racing/application/use-cases/UpdateLeagueMemberRoleUseCase';
import { GetLeagueOwnerSummaryUseCase } from '@core/racing/application/use-cases/GetLeagueOwnerSummaryUseCase';
import { GetLeagueProtestsUseCase } from '@core/racing/application/use-cases/GetLeagueProtestsUseCase';
import { Logger } from '@core/shared/application/Logger';
import type { Logger } from '@core/shared/application/Logger';
describe('LeagueService', () => {
let service: LeagueService;

View File

@@ -2,7 +2,7 @@ import { Injectable, Inject } from '@nestjs/common';
import { AllLeaguesWithCapacityViewModel, LeagueStatsDto, LeagueJoinRequestViewModel, ApproveJoinRequestInput, ApproveJoinRequestOutput, RejectJoinRequestInput, RejectJoinRequestOutput, LeagueAdminPermissionsViewModel, RemoveLeagueMemberInput, RemoveLeagueMemberOutput, UpdateLeagueMemberRoleInput, UpdateLeagueMemberRoleOutput, LeagueOwnerSummaryViewModel, LeagueConfigFormModelDto, LeagueAdminProtestsViewModel, LeagueSeasonSummaryViewModel, GetLeagueAdminPermissionsInput, GetLeagueProtestsQuery, GetLeagueSeasonsQuery, GetLeagueAdminConfigQuery, GetLeagueOwnerSummaryQuery, LeagueMembershipsViewModel, LeagueStandingsViewModel, LeagueScheduleViewModel, LeagueStatsViewModel, LeagueAdminViewModel, CreateLeagueInput, CreateLeagueOutput } from './dto/LeagueDto';
// Core imports
import { Logger } from '@core/shared/application/Logger';
import type { Logger } from '@core/shared/application/Logger';
// Use cases
import { GetAllLeaguesWithCapacityUseCase } from '@core/racing/application/use-cases/GetAllLeaguesWithCapacityUseCase';
@@ -144,7 +144,7 @@ export class LeagueService {
await this.getLeagueFullConfigUseCase.execute({ leagueId: query.leagueId }, presenter);
return presenter.viewModel;
} catch (error) {
this.logger.error('Error getting league full config', error);
this.logger.error('Error getting league full config', error instanceof Error ? error : new Error(String(error)));
return null;
}
}

View File

@@ -5,7 +5,7 @@ import { MediaService } from './MediaService';
import { IAvatarGenerationRepository } from '@core/media/domain/repositories/IAvatarGenerationRepository';
import { FaceValidationPort } from '@core/media/application/ports/FaceValidationPort';
import { AvatarGenerationPort } from '@core/media/application/ports/AvatarGenerationPort';
import { Logger } from '@core/shared/application';
import type { Logger } from '@core/shared/application';
// Import use cases
import { RequestAvatarGenerationUseCase } from '@core/media/application/use-cases/RequestAvatarGenerationUseCase';

View File

@@ -9,7 +9,7 @@ import { RequestAvatarGenerationPresenter } from './presenters/RequestAvatarGene
// Tokens
import { REQUEST_AVATAR_GENERATION_USE_CASE_TOKEN, LOGGER_TOKEN } from './MediaProviders';
import { Logger } from '@core/shared/application';
import type { Logger } from '@core/shared/application';
@Injectable()
export class MediaService {

View File

@@ -2,7 +2,7 @@ import { Provider } from '@nestjs/common';
import { RaceService } from './RaceService';
// Import core interfaces
import { Logger } from '@core/shared/application/Logger';
import type { Logger } from '@core/shared/application/Logger';
import { IRaceRepository } from '@core/racing/domain/repositories/IRaceRepository';
import { ILeagueRepository } from '@core/racing/domain/repositories/ILeagueRepository';

View File

@@ -2,7 +2,7 @@ import { Injectable, Inject } from '@nestjs/common';
import { AllRacesPageViewModel, RaceStatsDto, ImportRaceResultsInput, ImportRaceResultsSummaryViewModel } from './dto/RaceDto';
// Core imports
import { Logger } from '@core/shared/application/Logger';
import type { Logger } from '@core/shared/application/Logger';
// Use cases
import { GetAllRacesUseCase } from '@core/racing/application/use-cases/GetAllRacesUseCase';

View File

@@ -10,7 +10,7 @@ import { ILeagueMembershipRepository } from '@core/racing/domain/repositories/IL
import { IRaceRepository } from '@core/racing/domain/repositories/IRaceRepository';
import { ISponsorshipPricingRepository } from '@core/racing/domain/repositories/ISponsorshipPricingRepository';
import { ISponsorshipRequestRepository } from '@core/racing/domain/repositories/ISponsorshipRequestRepository';
import { Logger } from '@core/shared/application';
import type { Logger } from '@core/shared/application';
// Import use cases
import { GetSponsorshipPricingUseCase } from '@core/racing/application/use-cases/GetSponsorshipPricingUseCase';

View File

@@ -17,7 +17,7 @@ import { GetSponsorSponsorshipsPresenter } from './presenters/GetSponsorSponsors
// Tokens
import { GET_SPONSORSHIP_PRICING_USE_CASE_TOKEN, GET_SPONSORS_USE_CASE_TOKEN, CREATE_SPONSOR_USE_CASE_TOKEN, GET_SPONSOR_DASHBOARD_USE_CASE_TOKEN, GET_SPONSOR_SPONSORSHIPS_USE_CASE_TOKEN, LOGGER_TOKEN } from './SponsorProviders';
import { Logger } from '@core/shared/application';
import type { Logger } from '@core/shared/application';
@Injectable()
export class SponsorService {

View File

@@ -6,7 +6,7 @@ import { ITeamRepository } from '@core/racing/domain/repositories/ITeamRepositor
import { ITeamMembershipRepository } from '@core/racing/domain/repositories/ITeamMembershipRepository';
import { IDriverRepository } from '@core/racing/domain/repositories/IDriverRepository';
import { IImageServicePort } from '@core/racing/application/ports/IImageServicePort';
import { Logger } from '@core/shared/application/Logger';
import type { Logger } from '@core/shared/application/Logger';
// Import concrete in-memory implementations
import { InMemoryTeamRepository } from '@adapters/racing/persistence/inmemory/InMemoryTeamRepository';

View File

@@ -2,7 +2,7 @@ import { Test, TestingModule } from '@nestjs/testing';
import { TeamService } from './TeamService';
import { GetAllTeamsUseCase } from '@core/racing/application/use-cases/GetAllTeamsUseCase';
import { GetDriverTeamUseCase } from '@core/racing/application/use-cases/GetDriverTeamUseCase';
import { Logger } from '@core/shared/application/Logger';
import type { Logger } from '@core/shared/application/Logger';
import { AllTeamsPresenter } from './presenters/AllTeamsPresenter';
import { DriverTeamPresenter } from './presenters/DriverTeamPresenter';
import { AllTeamsViewModel, DriverTeamViewModel, GetDriverTeamQuery } from './dto/TeamDto';

View File

@@ -20,7 +20,7 @@ import { TeamMembersPresenter } from './presenters/TeamMembersPresenter';
import { TeamJoinRequestsPresenter } from './presenters/TeamJoinRequestsPresenter';
// Logger
import { Logger } from '@core/shared/application/Logger';
import type { Logger } from '@core/shared/application/Logger';
// Tokens
import {