diff --git a/adapters/analytics/persistence/inmemory/InMemoryAnalyticsSnapshotRepository.ts b/adapters/analytics/persistence/inmemory/InMemoryAnalyticsSnapshotRepository.ts index 722f4acd2..5605a4681 100644 --- a/adapters/analytics/persistence/inmemory/InMemoryAnalyticsSnapshotRepository.ts +++ b/adapters/analytics/persistence/inmemory/InMemoryAnalyticsSnapshotRepository.ts @@ -4,7 +4,8 @@ * In-memory implementation of IAnalyticsSnapshotRepository for development/testing. */ -import { AnalyticsSnapshot, SnapshotPeriod } from '@core/analytics/application/repositories/PageViewRepository'; +import { AnalyticsSnapshot, type SnapshotEntityType, type SnapshotPeriod } from '@core/analytics/domain/entities/AnalyticsSnapshot'; +import type { AnalyticsSnapshotRepository } from '@core/analytics/domain/repositories/AnalyticsSnapshotRepository'; import { Logger } from '@core/shared/domain/Logger'; export class InMemoryAnalyticsSnapshotRepository implements AnalyticsSnapshotRepository { diff --git a/adapters/analytics/persistence/inmemory/InMemoryPageViewRepository.ts b/adapters/analytics/persistence/inmemory/InMemoryPageViewRepository.ts index eb5957323..a799c4ef0 100644 --- a/adapters/analytics/persistence/inmemory/InMemoryPageViewRepository.ts +++ b/adapters/analytics/persistence/inmemory/InMemoryPageViewRepository.ts @@ -6,7 +6,7 @@ import type { PageViewRepository } from '@core/analytics/application/repositories/PageViewRepository'; import { PageView, type EntityType } from '@core/analytics/domain/entities/PageView'; -import { Logger } from '@core/shared/domain'; +import { Logger } from '@core/shared/domain/Logger'; export class InMemoryPageViewRepository implements PageViewRepository { private pageViews: Map = new Map(); diff --git a/adapters/bootstrap/SeedDemoUsers.ts b/adapters/bootstrap/SeedDemoUsers.ts index 0e3388da2..6de5595ce 100644 --- a/adapters/bootstrap/SeedDemoUsers.ts +++ b/adapters/bootstrap/SeedDemoUsers.ts @@ -1,6 +1,10 @@ import { AdminUser } from '@core/admin/domain/entities/AdminUser'; import { Email } from '@core/admin/domain/value-objects/Email'; +import type { AdminUserRepository } from '@core/admin/domain/repositories/AdminUserRepository'; import { User } from '@core/identity/domain/entities/User'; +import type { AuthRepository } from '@core/identity/domain/repositories/AuthRepository'; +import type { UserRepository } from '@core/identity/domain/repositories/UserRepository'; +import type { PasswordHashingService } from '@core/identity/domain/services/PasswordHashingService'; import { EmailAddress } from '@core/identity/domain/value-objects/EmailAddress'; import { PasswordHash } from '@core/identity/domain/value-objects/PasswordHash'; import { UserId } from '@core/identity/domain/value-objects/UserId'; @@ -84,9 +88,9 @@ export class SeedDemoUsers { constructor( private readonly logger: Logger, - private readonly authRepository: IAuthRepository, - private readonly passwordHashingService: IPasswordHashingService, - private readonly adminUserRepository: IAdminUserRepository, + private readonly authRepository: AuthRepository, + private readonly passwordHashingService: PasswordHashingService, + private readonly adminUserRepository: AdminUserRepository, ) {} private getApiPersistence(): 'postgres' | 'inmemory' { diff --git a/adapters/bootstrap/SeedRacingData.ts b/adapters/bootstrap/SeedRacingData.ts index cb4791f0f..36cfb9800 100644 --- a/adapters/bootstrap/SeedRacingData.ts +++ b/adapters/bootstrap/SeedRacingData.ts @@ -4,40 +4,65 @@ import { Result } from '@core/racing/domain/entities/result/Result'; import type { Season } from '@core/racing/domain/entities/season/Season'; import { Standing } from '@core/racing/domain/entities/Standing'; import { Team } from '@core/racing/domain/entities/Team'; -import type { TeamStats } from '@core/racing/domain/repositories/TeamStatsRepository'; +import type { DriverRepository } from '@core/racing/domain/repositories/DriverRepository'; +import type { LeagueRepository } from '@core/racing/domain/repositories/LeagueRepository'; +import type { SeasonRepository } from '@core/racing/domain/repositories/SeasonRepository'; +import type { LeagueScoringConfigRepository } from '@core/racing/domain/repositories/LeagueScoringConfigRepository'; +import type { SeasonSponsorshipRepository } from '@core/racing/domain/repositories/SeasonSponsorshipRepository'; +import type { SponsorshipRequestRepository } from '@core/racing/domain/repositories/SponsorshipRequestRepository'; +import type { LeagueWalletRepository } from '@core/racing/domain/repositories/LeagueWalletRepository'; +import type { TransactionRepository } from '@core/racing/domain/repositories/TransactionRepository'; +import type { ProtestRepository } from '@core/racing/domain/repositories/ProtestRepository'; +import type { PenaltyRepository } from '@core/racing/domain/repositories/PenaltyRepository'; +import type { RaceRepository } from '@core/racing/domain/repositories/RaceRepository'; +import type { ResultRepository } from '@core/racing/domain/repositories/ResultRepository'; +import type { StandingRepository } from '@core/racing/domain/repositories/StandingRepository'; +import type { LeagueMembershipRepository } from '@core/racing/domain/repositories/LeagueMembershipRepository'; +import type { RaceRegistrationRepository } from '@core/racing/domain/repositories/RaceRegistrationRepository'; +import type { TeamRepository } from '@core/racing/domain/repositories/TeamRepository'; +import type { TeamMembershipRepository } from '@core/racing/domain/repositories/TeamMembershipRepository'; +import type { SponsorRepository } from '@core/racing/domain/repositories/SponsorRepository'; +import type { FeedRepository } from '@core/social/domain/repositories/FeedRepository'; +import type { SocialGraphRepository } from '@core/social/domain/repositories/SocialGraphRepository'; +import type { DriverStatsRepository } from '@core/racing/domain/repositories/DriverStatsRepository'; +import type { TeamStatsRepository, TeamStats } from '@core/racing/domain/repositories/TeamStatsRepository'; +import type { MediaRepository } from '@core/racing/domain/repositories/MediaRepository'; +import type { AuthRepository } from '@core/identity/domain/repositories/AuthRepository'; +import type { PasswordHashingService } from '@core/identity/domain/services/PasswordHashingService'; +import type { AdminUserRepository } from '@core/admin/domain/repositories/AdminUserRepository'; import type { Logger } from '@core/shared/domain/Logger'; import { getLeagueScoringPresetById } from './LeagueScoringPresets'; import { createRacingSeed } from './racing/RacingSeed'; import { seedId } from './racing/SeedIdHelper'; export type RacingSeedDependencies = { - driverRepository: IDriverRepository; - leagueRepository: ILeagueRepository; - seasonRepository: ISeasonRepository; - leagueScoringConfigRepository: ILeagueScoringConfigRepository; - seasonSponsorshipRepository: ISeasonSponsorshipRepository; - sponsorshipRequestRepository: ISponsorshipRequestRepository; - leagueWalletRepository: ILeagueWalletRepository; - transactionRepository: ITransactionRepository; - protestRepository: IProtestRepository; - penaltyRepository: IPenaltyRepository; - raceRepository: IRaceRepository; - resultRepository: IResultRepository; - standingRepository: IStandingRepository; - leagueMembershipRepository: ILeagueMembershipRepository; - raceRegistrationRepository: IRaceRegistrationRepository; - teamRepository: ITeamRepository; - teamMembershipRepository: ITeamMembershipRepository; - sponsorRepository: ISponsorRepository; - feedRepository: IFeedRepository; - socialGraphRepository: ISocialGraphRepository; - driverStatsRepository: IDriverStatsRepository; - teamStatsRepository: ITeamStatsRepository; - mediaRepository: IMediaRepository; + driverRepository: DriverRepository; + leagueRepository: LeagueRepository; + seasonRepository: SeasonRepository; + leagueScoringConfigRepository: LeagueScoringConfigRepository; + seasonSponsorshipRepository: SeasonSponsorshipRepository; + sponsorshipRequestRepository: SponsorshipRequestRepository; + leagueWalletRepository: LeagueWalletRepository; + transactionRepository: TransactionRepository; + protestRepository: ProtestRepository; + penaltyRepository: PenaltyRepository; + raceRepository: RaceRepository; + resultRepository: ResultRepository; + standingRepository: StandingRepository; + leagueMembershipRepository: LeagueMembershipRepository; + raceRegistrationRepository: RaceRegistrationRepository; + teamRepository: TeamRepository; + teamMembershipRepository: TeamMembershipRepository; + sponsorRepository: SponsorRepository; + feedRepository: FeedRepository; + socialGraphRepository: SocialGraphRepository; + driverStatsRepository: DriverStatsRepository; + teamStatsRepository: TeamStatsRepository; + mediaRepository: MediaRepository; // Identity dependencies for demo user seed - authRepository: IAuthRepository; - passwordHashingService: IPasswordHashingService; - adminUserRepository: IAdminUserRepository; + authRepository: AuthRepository; + passwordHashingService: PasswordHashingService; + adminUserRepository: AdminUserRepository; }; export class SeedRacingData { @@ -280,7 +305,7 @@ export class SeedRacingData { // ignore duplicates } - const seedableFeed = this.seedDeps.feedRepository as unknown as { seed?: (input: unknown) => void }; + const seedableFeed = this.seedDeps.feedRepository as unknown as { seed?: (input: any) => void }; if (typeof seedableFeed.seed === 'function') { seedableFeed.seed({ drivers: seed.drivers, @@ -289,7 +314,7 @@ export class SeedRacingData { }); } - const seedableSocial = this.seedDeps.socialGraphRepository as unknown as { seed?: (input: unknown) => void }; + const seedableSocial = this.seedDeps.socialGraphRepository as unknown as { seed?: (input: any) => void }; if (typeof seedableSocial.seed === 'function') { seedableSocial.seed({ drivers: seed.drivers, @@ -317,8 +342,8 @@ export class SeedRacingData { this.logger.info(`[Bootstrap] Computing stats for ${drivers.length} drivers from ${standings.length} standings and ${results.length} results`); for (const driver of drivers) { - const driverResults = results.filter(r => r.driverId.toString() === driver.id); - const driverStandings = standings.filter(s => s.driverId.toString() === driver.id); + const driverResults = results.filter((r: Result) => r.driverId.toString() === driver.id); + const driverStandings = standings.filter((s: Standing) => s.driverId.toString() === driver.id); if (driverResults.length === 0) continue; @@ -398,13 +423,13 @@ export class SeedRacingData { for (const team of teams) { // Get team members using the correct method const teamMemberships = await this.seedDeps.teamMembershipRepository.getTeamMembers(team.id); - const teamMemberIds = teamMemberships.map(m => m.driverId.toString()); + const teamMemberIds = teamMemberships.map((m: any) => m.driverId.toString()); // Get results for team members - const teamResults = results.filter(r => teamMemberIds.includes(r.driverId.toString())); + const teamResults = results.filter((r: Result) => teamMemberIds.includes(r.driverId.toString())); // Get team drivers for name resolution - const teamDrivers = drivers.filter(d => teamMemberIds.includes(d.id)); + const teamDrivers = drivers.filter((d: Driver) => teamMemberIds.includes(d.id)); const stats = this.calculateTeamStats(team, teamResults, teamDrivers); await this.seedDeps.teamStatsRepository.saveTeamStats(team.id, stats); diff --git a/adapters/eslint-rules/adapter-naming.js b/adapters/eslint-rules/adapter-naming.js deleted file mode 100644 index 7968c5bab..000000000 --- a/adapters/eslint-rules/adapter-naming.js +++ /dev/null @@ -1,37 +0,0 @@ -module.exports = { - meta: { - type: 'problem', - docs: { - description: 'Enforce adapter naming conventions', - category: 'Architecture', - recommended: true, - }, - fixable: null, - schema: [], - messages: { - invalidNaming: 'Adapter classes should end with "Adapter", "Repository", "Service", "Factory" or "Entity". Found: {{name}}', - }, - }, - - create(context) { - return { - ClassDeclaration(node) { - const filename = context.getFilename(); - if (!filename.includes('adapters/')) return; - - const name = node.id.name; - const isValidName = /(.+)(Adapter|Factory|Repository|Service|Entity|Mapper|Schema|Guard|Module|Controller)$/.test(name); - - if (!isValidName) { - context.report({ - node, - messageId: 'invalidNaming', - data: { - name, - }, - }); - } - }, - }; - }, -}; diff --git a/adapters/eslint-rules/index.js b/adapters/eslint-rules/index.js index 4df3e52bb..43ac9b106 100644 --- a/adapters/eslint-rules/index.js +++ b/adapters/eslint-rules/index.js @@ -1,17 +1,14 @@ const noIndexFiles = require('./no-index-files'); -const adapterNaming = require('./adapter-naming'); module.exports = { rules: { 'no-index-files': noIndexFiles, - 'adapter-naming': adapterNaming, }, configs: { recommended: { plugins: ['gridpilot-adapters-rules'], rules: { 'gridpilot-adapters-rules/no-index-files': 'error', - 'gridpilot-adapters-rules/adapter-naming': 'error', }, }, }, diff --git a/adapters/identity/persistence/inmemory/InMemoryAchievementRepository.ts b/adapters/identity/persistence/inmemory/InMemoryAchievementRepository.ts index e7d7ba94d..d09a7d821 100644 --- a/adapters/identity/persistence/inmemory/InMemoryAchievementRepository.ts +++ b/adapters/identity/persistence/inmemory/InMemoryAchievementRepository.ts @@ -5,11 +5,10 @@ */ import { ADMIN_ACHIEVEMENTS, COMMUNITY_ACHIEVEMENTS, DRIVER_ACHIEVEMENTS, STEWARD_ACHIEVEMENTS } from "@core/identity/domain/AchievementConstants"; -import { Achievement } from "@core/identity/domain/entities/Achievement"; +import { Achievement, type AchievementCategory } from "@core/identity/domain/entities/Achievement"; import { UserAchievement } from "@core/identity/domain/entities/UserAchievement"; import { AchievementRepository } from "@core/identity/domain/repositories/AchievementRepository"; -import { AchievementCategory } from "@core/identity/domain/types/AchievementTypes"; -import { Logger } from "@core/shared/domain"; +import type { Logger } from "@core/shared/domain/Logger"; export class InMemoryAchievementRepository implements AchievementRepository { private achievements: Map = new Map(); diff --git a/adapters/identity/persistence/inmemory/InMemoryAuthRepository.ts b/adapters/identity/persistence/inmemory/InMemoryAuthRepository.ts index 8b865e7e1..a7abda2ea 100644 --- a/adapters/identity/persistence/inmemory/InMemoryAuthRepository.ts +++ b/adapters/identity/persistence/inmemory/InMemoryAuthRepository.ts @@ -1,14 +1,14 @@ import { User } from '@core/identity/domain/entities/User'; -import { AuthRepository } from '@core/identity/domain/repositories/AuthRepository'; -import { StoredUser } from '@core/identity/domain/repositories/UserRepository'; - +import type { AuthRepository } from '@core/identity/domain/repositories/AuthRepository'; +import type { UserRepository, StoredUser } from '@core/identity/domain/repositories/UserRepository'; +import type { PasswordHashingService } from '@core/identity/domain/services/PasswordHashingService'; import { EmailAddress } from '@core/identity/domain/value-objects/EmailAddress'; -import { Logger } from '@core/shared/domain'; +import type { Logger } from '@core/shared/domain/Logger'; export class InMemoryAuthRepository implements AuthRepository { constructor( - private readonly userRepository: IUserRepository, - private readonly passwordHashingService: IPasswordHashingService, + private readonly userRepository: UserRepository, + private readonly passwordHashingService: PasswordHashingService, private readonly logger: Logger, ) {} diff --git a/adapters/identity/persistence/inmemory/InMemoryMagicLinkRepository.ts b/adapters/identity/persistence/inmemory/InMemoryMagicLinkRepository.ts index 6239b5412..d3bc9f8c4 100644 --- a/adapters/identity/persistence/inmemory/InMemoryMagicLinkRepository.ts +++ b/adapters/identity/persistence/inmemory/InMemoryMagicLinkRepository.ts @@ -1,5 +1,5 @@ -import { MagicLinkRepository, PasswordResetRequest } from '@core/identity/domain/repositories/MagicLinkRepository'; -import { Logger } from '@core/shared/domain'; +import type { MagicLinkRepository, PasswordResetRequest } from '@core/identity/domain/repositories/MagicLinkRepository'; +import type { Logger } from '@core/shared/domain/Logger'; import { Result } from '@core/shared/domain/Result'; export class InMemoryMagicLinkRepository implements MagicLinkRepository { diff --git a/adapters/identity/persistence/inmemory/InMemorySponsorAccountRepository.ts b/adapters/identity/persistence/inmemory/InMemorySponsorAccountRepository.ts index f8fcd0890..aa4f64f0c 100644 --- a/adapters/identity/persistence/inmemory/InMemorySponsorAccountRepository.ts +++ b/adapters/identity/persistence/inmemory/InMemorySponsorAccountRepository.ts @@ -4,8 +4,10 @@ * In-memory implementation of ISponsorAccountRepository for development/testing. */ -import { SponsorAccount, SponsorAccountRepository, UserId } from '@core/identity'; -import { Logger } from '@core/shared/domain'; +import { SponsorAccount } from '@core/identity/domain/entities/SponsorAccount'; +import type { SponsorAccountRepository } from '@core/identity/domain/repositories/SponsorAccountRepository'; +import { UserId } from '@core/identity/domain/value-objects/UserId'; +import type { Logger } from '@core/shared/domain/Logger'; export class InMemorySponsorAccountRepository implements SponsorAccountRepository { private accounts: Map = new Map(); diff --git a/adapters/identity/persistence/inmemory/InMemoryUserRatingRepository.ts b/adapters/identity/persistence/inmemory/InMemoryUserRatingRepository.ts index 4999a7d62..8a92737bb 100644 --- a/adapters/identity/persistence/inmemory/InMemoryUserRatingRepository.ts +++ b/adapters/identity/persistence/inmemory/InMemoryUserRatingRepository.ts @@ -4,8 +4,9 @@ * In-memory implementation of IUserRatingRepository */ -import { UserRating, UserRatingRepository } from '@core/identity'; -import { Logger } from '@core/shared/domain'; +import { UserRating } from '@core/identity/domain/value-objects/UserRating'; +import type { UserRatingRepository } from '@core/identity/domain/repositories/UserRatingRepository'; +import type { Logger } from '@core/shared/domain/Logger'; export class InMemoryUserRatingRepository implements UserRatingRepository { private ratings: Map = new Map(); diff --git a/adapters/identity/persistence/inmemory/InMemoryUserRepository.ts b/adapters/identity/persistence/inmemory/InMemoryUserRepository.ts index 94a0ff7a6..0a27fbef1 100644 --- a/adapters/identity/persistence/inmemory/InMemoryUserRepository.ts +++ b/adapters/identity/persistence/inmemory/InMemoryUserRepository.ts @@ -5,7 +5,7 @@ */ import type { StoredUser, UserRepository } from '@core/identity/domain/repositories/UserRepository'; -import { Logger } from '@core/shared/domain'; +import type { Logger } from '@core/shared/domain/Logger'; export class InMemoryUserRepository implements UserRepository { private users: Map = new Map(); diff --git a/adapters/identity/persistence/typeorm/repositories/TypeOrmMagicLinkRepository.ts b/adapters/identity/persistence/typeorm/repositories/TypeOrmMagicLinkRepository.ts index 7a03d82da..535ee281a 100644 --- a/adapters/identity/persistence/typeorm/repositories/TypeOrmMagicLinkRepository.ts +++ b/adapters/identity/persistence/typeorm/repositories/TypeOrmMagicLinkRepository.ts @@ -1,5 +1,5 @@ -import { MagicLinkRepository, PasswordResetRequest } from '@core/identity/domain/repositories/MagicLinkRepository'; -import { Logger } from '@core/shared/domain'; +import type { MagicLinkRepository, PasswordResetRequest } from '@core/identity/domain/repositories/MagicLinkRepository'; +import type { Logger } from '@core/shared/domain/Logger'; import { Result } from '@core/shared/domain/Result'; import type { DataSource } from 'typeorm'; import { PasswordResetRequestOrmEntity } from '../entities/PasswordResetRequestOrmEntity'; diff --git a/adapters/logging/ConsoleErrorReporter.ts b/adapters/logging/ConsoleErrorReporter.ts index 6aee80948..80d13514a 100644 --- a/adapters/logging/ConsoleErrorReporter.ts +++ b/adapters/logging/ConsoleErrorReporter.ts @@ -1,4 +1,4 @@ -import { ErrorReporter } from "@core/shared/domain"; +import type { ErrorReporter } from "@core/shared/application/ErrorReporter"; export class ConsoleErrorReporter implements ErrorReporter { report(error: Error, context?: unknown): void { diff --git a/adapters/logging/ConsoleLogger.ts b/adapters/logging/ConsoleLogger.ts index a5cb8d595..d8041eba9 100644 --- a/adapters/logging/ConsoleLogger.ts +++ b/adapters/logging/ConsoleLogger.ts @@ -1,4 +1,4 @@ -import { Logger } from "@core/shared/domain"; +import type { Logger } from "@core/shared/domain/Logger"; export class ConsoleLogger implements Logger { private formatMessage(level: string, message: string, context?: unknown): string { diff --git a/adapters/media/persistence/inmemory/InMemoryAvatarGenerationRepository.ts b/adapters/media/persistence/inmemory/InMemoryAvatarGenerationRepository.ts index 450536449..fb63b56b0 100644 --- a/adapters/media/persistence/inmemory/InMemoryAvatarGenerationRepository.ts +++ b/adapters/media/persistence/inmemory/InMemoryAvatarGenerationRepository.ts @@ -1,6 +1,6 @@ import { AvatarGenerationRequest } from '@core/media/domain/entities/AvatarGenerationRequest'; -import { AvatarGenerationRepository } from '@core/media/domain/repositories/AvatarGenerationRepository'; -import { Logger } from '@core/shared/domain'; +import type { AvatarGenerationRepository } from '@core/media/domain/repositories/AvatarGenerationRepository'; +import type { Logger } from '@core/shared/domain/Logger'; export class InMemoryAvatarGenerationRepository implements AvatarGenerationRepository { private requests: Map = new Map(); // Key: requestId diff --git a/adapters/notifications/gateways/InAppNotificationGateway.ts b/adapters/notifications/gateways/InAppNotificationGateway.ts index 436010497..4bfabc8c9 100644 --- a/adapters/notifications/gateways/InAppNotificationGateway.ts +++ b/adapters/notifications/gateways/InAppNotificationGateway.ts @@ -32,7 +32,7 @@ export class InAppNotificationAdapter implements NotificationGateway { return { success: true, channel: this.channel, - externalId: notification.id, + externalId: notification.id.value, attemptedAt: new Date(), }; } diff --git a/adapters/notifications/persistence/inmemory/InMemoryNotificationPreferenceRepository.ts b/adapters/notifications/persistence/inmemory/InMemoryNotificationPreferenceRepository.ts index 66165599f..52a08852b 100644 --- a/adapters/notifications/persistence/inmemory/InMemoryNotificationPreferenceRepository.ts +++ b/adapters/notifications/persistence/inmemory/InMemoryNotificationPreferenceRepository.ts @@ -1,6 +1,6 @@ import { NotificationPreference } from '@core/notifications/domain/entities/NotificationPreference'; -import { NotificationPreferenceRepository } from '@core/notifications/domain/repositories/NotificationPreferenceRepository'; -import { Logger } from '@core/shared/domain'; +import type { NotificationPreferenceRepository } from '@core/notifications/domain/repositories/NotificationPreferenceRepository'; +import type { Logger } from '@core/shared/domain/Logger'; export class InMemoryNotificationPreferenceRepository implements NotificationPreferenceRepository { private preferences: Map = new Map(); diff --git a/adapters/notifications/persistence/inmemory/InMemoryNotificationRepository.ts b/adapters/notifications/persistence/inmemory/InMemoryNotificationRepository.ts index b5769dfc0..5093e5ac4 100644 --- a/adapters/notifications/persistence/inmemory/InMemoryNotificationRepository.ts +++ b/adapters/notifications/persistence/inmemory/InMemoryNotificationRepository.ts @@ -17,8 +17,8 @@ export class InMemoryNotificationRepository implements NotificationRepository { this.logger = logger; this.logger.info('InMemoryNotificationRepository initialized.'); initialNotifications.forEach(notification => { - this.notifications.set(notification.id, notification); - this.logger.debug(`Seeded notification: ${notification.id}`); + this.notifications.set(notification.id.value, notification); + this.logger.debug(`Seeded notification: ${notification.id.value}`); }); } @@ -95,31 +95,31 @@ export class InMemoryNotificationRepository implements NotificationRepository { } async create(notification: Notification): Promise { - this.logger.debug(`Creating notification: ${notification.id}`); + this.logger.debug(`Creating notification: ${notification.id.value}`); try { - if (this.notifications.has(notification.id)) { - this.logger.warn(`Notification with ID ${notification.id} already exists. Throwing error.`); - throw new Error(`Notification with ID ${notification.id} already exists`); + if (this.notifications.has(notification.id.value)) { + this.logger.warn(`Notification with ID ${notification.id.value} already exists. Throwing error.`); + throw new Error(`Notification with ID ${notification.id.value} already exists`); } - this.notifications.set(notification.id, notification); - this.logger.info(`Notification ${notification.id} created successfully.`); + this.notifications.set(notification.id.value, notification); + this.logger.info(`Notification ${notification.id.value} created successfully.`); } catch (error) { - this.logger.error(`Error creating notification ${notification.id}:`, error instanceof Error ? error : new Error(String(error))); + this.logger.error(`Error creating notification ${notification.id.value}:`, error instanceof Error ? error : new Error(String(error))); throw error; } } async update(notification: Notification): Promise { - this.logger.debug(`Updating notification: ${notification.id}`); + this.logger.debug(`Updating notification: ${notification.id.value}`); try { - if (!this.notifications.has(notification.id)) { - this.logger.warn(`Notification with ID ${notification.id} not found for update. Throwing error.`); - throw new Error(`Notification with ID ${notification.id} not found`); + if (!this.notifications.has(notification.id.value)) { + this.logger.warn(`Notification with ID ${notification.id.value} not found for update. Throwing error.`); + throw new Error(`Notification with ID ${notification.id.value} not found`); } - this.notifications.set(notification.id, notification); - this.logger.info(`Notification ${notification.id} updated successfully.`); + this.notifications.set(notification.id.value, notification); + this.logger.info(`Notification ${notification.id.value} updated successfully.`); } catch (error) { - this.logger.error(`Error updating notification ${notification.id}:`, error instanceof Error ? error : new Error(String(error))); + this.logger.error(`Error updating notification ${notification.id.value}:`, error instanceof Error ? error : new Error(String(error))); throw error; } } @@ -143,7 +143,7 @@ export class InMemoryNotificationRepository implements NotificationRepository { try { const toDelete = Array.from(this.notifications.values()) .filter(n => n.recipientId === recipientId) - .map(n => n.id); + .map(n => n.id.value); toDelete.forEach(id => this.notifications.delete(id)); this.logger.info(`Deleted ${toDelete.length} notifications for recipient ID: ${recipientId}.`); @@ -163,7 +163,7 @@ export class InMemoryNotificationRepository implements NotificationRepository { toUpdate.forEach(n => { const updated = n.markAsRead(); - this.notifications.set(updated.id, updated); + this.notifications.set(updated.id.value, updated); }); this.logger.info(`Marked ${toUpdate.length} notifications as read for recipient ID: ${recipientId}.`); } catch (error) { diff --git a/adapters/notifications/ports/ConsoleMagicLinkNotificationAdapter.ts b/adapters/notifications/ports/ConsoleMagicLinkNotificationAdapter.ts index 026c3be9f..575eb735e 100644 --- a/adapters/notifications/ports/ConsoleMagicLinkNotificationAdapter.ts +++ b/adapters/notifications/ports/ConsoleMagicLinkNotificationAdapter.ts @@ -1,5 +1,5 @@ -import { MagicLinkNotificationInput, MagicLinkNotificationPort } from '@core/identity/domain/ports/MagicLinkNotificationPort'; -import { Logger } from '@core/shared/domain'; +import type { MagicLinkNotificationInput, MagicLinkNotificationPort } from '@core/identity/domain/ports/MagicLinkNotificationPort'; +import type { Logger } from '@core/shared/domain/Logger'; /** * Console adapter for magic link notifications diff --git a/adapters/notifications/ports/NotificationServiceAdapter.ts b/adapters/notifications/ports/NotificationServiceAdapter.ts index d105e96cc..0b4dd6074 100644 --- a/adapters/notifications/ports/NotificationServiceAdapter.ts +++ b/adapters/notifications/ports/NotificationServiceAdapter.ts @@ -1,6 +1,8 @@ import type { NotificationGatewayRegistry } from '@core/notifications/application/ports/NotificationGateway'; import type { NotificationService, SendNotificationCommand } from '@core/notifications/application/ports/NotificationService'; import { SendNotificationUseCase } from '@core/notifications/application/use-cases/SendNotificationUseCase'; +import type { NotificationRepository } from '@core/notifications/domain/repositories/NotificationRepository'; +import type { NotificationPreferenceRepository } from '@core/notifications/domain/repositories/NotificationPreferenceRepository'; import type { Logger } from '@core/shared/domain/Logger'; export class NotificationServiceAdapter implements NotificationService { @@ -8,8 +10,8 @@ export class NotificationServiceAdapter implements NotificationService { private readonly logger: Logger; constructor( - notificationRepository: INotificationRepository, - preferenceRepository: INotificationPreferenceRepository, + notificationRepository: NotificationRepository, + preferenceRepository: NotificationPreferenceRepository, gatewayRegistry: NotificationGatewayRegistry, logger: Logger, ) { diff --git a/adapters/payments/persistence/inmemory/InMemoryMembershipFeeRepository.ts b/adapters/payments/persistence/inmemory/InMemoryMembershipFeeRepository.ts index d0bb6eb45..065070f99 100644 --- a/adapters/payments/persistence/inmemory/InMemoryMembershipFeeRepository.ts +++ b/adapters/payments/persistence/inmemory/InMemoryMembershipFeeRepository.ts @@ -4,7 +4,7 @@ import type { MemberPayment } from '@core/payments/domain/entities/MemberPayment'; import type { MembershipFee } from '@core/payments/domain/entities/MembershipFee'; -import type { MembershipFeeRepository } from '@core/payments/domain/repositories/MembershipFeeRepository'; +import type { MembershipFeeRepository, MemberPaymentRepository } from '@core/payments/domain/repositories/MembershipFeeRepository'; import type { Logger } from '@core/shared/domain/Logger'; const membershipFees: Map = new Map(); @@ -51,7 +51,7 @@ export class InMemoryMemberPaymentRepository implements MemberPaymentRepository ) || null; } - async findByLeagueIdAndDriverId(leagueId: string, driverId: string, membershipFeeRepo: IMembershipFeeRepository): Promise { + async findByLeagueIdAndDriverId(leagueId: string, driverId: string, membershipFeeRepo: MembershipFeeRepository): Promise { this.logger.debug('[InMemoryMemberPaymentRepository] findByLeagueIdAndDriverId', { leagueId, driverId }); const results: MemberPayment[] = []; for (const payment of memberPayments.values()) { diff --git a/adapters/payments/persistence/inmemory/InMemoryWalletRepository.ts b/adapters/payments/persistence/inmemory/InMemoryWalletRepository.ts index 76be205dc..93c7cb2d4 100644 --- a/adapters/payments/persistence/inmemory/InMemoryWalletRepository.ts +++ b/adapters/payments/persistence/inmemory/InMemoryWalletRepository.ts @@ -3,7 +3,7 @@ */ import type { Transaction, Wallet } from '@core/payments/domain/entities/Wallet'; -import type { WalletRepository } from '@core/payments/domain/repositories/WalletRepository'; +import type { WalletRepository, TransactionRepository } from '@core/payments/domain/repositories/WalletRepository'; import type { Logger } from '@core/shared/domain/Logger'; const wallets: Map = new Map(); diff --git a/adapters/payments/persistence/typeorm/repositories/TypeOrmMembershipFeeRepository.ts b/adapters/payments/persistence/typeorm/repositories/TypeOrmMembershipFeeRepository.ts index fb825920c..14c2a8197 100644 --- a/adapters/payments/persistence/typeorm/repositories/TypeOrmMembershipFeeRepository.ts +++ b/adapters/payments/persistence/typeorm/repositories/TypeOrmMembershipFeeRepository.ts @@ -2,7 +2,7 @@ import type { DataSource } from 'typeorm'; import type { MemberPayment } from '@core/payments/domain/entities/MemberPayment'; import type { MembershipFee } from '@core/payments/domain/entities/MembershipFee'; -import type { IMembershipFeeRepository, MemberPaymentRepository } from '@core/payments/domain/repositories/MembershipFeeRepository'; +import type { MembershipFeeRepository, MemberPaymentRepository } from '@core/payments/domain/repositories/MembershipFeeRepository'; import { PaymentsMemberPaymentOrmEntity } from '../entities/PaymentsMemberPaymentOrmEntity'; import { PaymentsMembershipFeeOrmEntity } from '../entities/PaymentsMembershipFeeOrmEntity'; @@ -61,7 +61,7 @@ export class TypeOrmMemberPaymentRepository implements MemberPaymentRepository { async findByLeagueIdAndDriverId( leagueId: string, driverId: string, - membershipFeeRepo: IMembershipFeeRepository, + membershipFeeRepo: MembershipFeeRepository, ): Promise { const fee = await membershipFeeRepo.findByLeagueId(leagueId); if (!fee) { diff --git a/adapters/payments/persistence/typeorm/repositories/TypeOrmWalletRepository.ts b/adapters/payments/persistence/typeorm/repositories/TypeOrmWalletRepository.ts index 18429fd7b..f9f6ffaa7 100644 --- a/adapters/payments/persistence/typeorm/repositories/TypeOrmWalletRepository.ts +++ b/adapters/payments/persistence/typeorm/repositories/TypeOrmWalletRepository.ts @@ -1,7 +1,7 @@ import type { DataSource } from 'typeorm'; import type { Transaction, Wallet } from '@core/payments/domain/entities/Wallet'; -import type { TransactionRepository } from '@core/payments/domain/repositories/WalletRepository'; +import type { WalletRepository, TransactionRepository } from '@core/payments/domain/repositories/WalletRepository'; import { PaymentsTransactionOrmEntity } from '../entities/PaymentsTransactionOrmEntity'; import { PaymentsWalletOrmEntity } from '../entities/PaymentsWalletOrmEntity'; diff --git a/adapters/racing/persistence/inmemory/InMemoryPenaltyRepository.ts b/adapters/racing/persistence/inmemory/InMemoryPenaltyRepository.ts index 65d8f200a..ce0bd7046 100644 --- a/adapters/racing/persistence/inmemory/InMemoryPenaltyRepository.ts +++ b/adapters/racing/persistence/inmemory/InMemoryPenaltyRepository.ts @@ -16,8 +16,8 @@ export class InMemoryPenaltyRepository implements PenaltyRepository { this.logger = logger; this.logger.info('InMemoryPenaltyRepository initialized.'); initialPenalties.forEach(penalty => { - this.penalties.set(penalty.id, penalty); - this.logger.debug(`Seeded penalty: ${penalty.id}`); + this.penalties.set(penalty.id.toString(), penalty); + this.logger.debug(`Seeded penalty: ${penalty.id.toString()}`); }); } @@ -108,31 +108,31 @@ export class InMemoryPenaltyRepository implements PenaltyRepository { } async create(penalty: Penalty): Promise { - this.logger.debug(`Creating penalty: ${penalty.id}`); + this.logger.debug(`Creating penalty: ${penalty.id.toString()}`); try { - if (this.penalties.has(penalty.id)) { - this.logger.warn(`Penalty with ID ${penalty.id} already exists.`); - throw new Error(`Penalty with ID ${penalty.id} already exists`); + if (this.penalties.has(penalty.id.toString())) { + this.logger.warn(`Penalty with ID ${penalty.id.toString()} already exists.`); + throw new Error(`Penalty with ID ${penalty.id.toString()} already exists`); } - this.penalties.set(penalty.id, penalty); - this.logger.info(`Penalty ${penalty.id} created successfully.`); + this.penalties.set(penalty.id.toString(), penalty); + this.logger.info(`Penalty ${penalty.id.toString()} created successfully.`); } catch (error) { - this.logger.error(`Error creating penalty ${penalty.id}:`, error instanceof Error ? error : new Error(String(error))); + this.logger.error(`Error creating penalty ${penalty.id.toString()}:`, error instanceof Error ? error : new Error(String(error))); throw error; } } async update(penalty: Penalty): Promise { - this.logger.debug(`Updating penalty: ${penalty.id}`); + this.logger.debug(`Updating penalty: ${penalty.id.toString()}`); try { - if (!this.penalties.has(penalty.id)) { - this.logger.warn(`Penalty with ID ${penalty.id} not found for update.`); - throw new Error(`Penalty with ID ${penalty.id} not found`); + if (!this.penalties.has(penalty.id.toString())) { + this.logger.warn(`Penalty with ID ${penalty.id.toString()} not found for update.`); + throw new Error(`Penalty with ID ${penalty.id.toString()} not found`); } - this.penalties.set(penalty.id, penalty); - this.logger.info(`Penalty ${penalty.id} updated successfully.`); + this.penalties.set(penalty.id.toString(), penalty); + this.logger.info(`Penalty ${penalty.id.toString()} updated successfully.`); } catch (error) { - this.logger.error(`Error updating penalty ${penalty.id}:`, error instanceof Error ? error : new Error(String(error))); + this.logger.error(`Error updating penalty ${penalty.id.toString()}:`, error instanceof Error ? error : new Error(String(error))); throw error; } } diff --git a/adapters/racing/persistence/inmemory/InMemoryResultRepository.ts b/adapters/racing/persistence/inmemory/InMemoryResultRepository.ts index c3b83cfd9..dc326a153 100644 --- a/adapters/racing/persistence/inmemory/InMemoryResultRepository.ts +++ b/adapters/racing/persistence/inmemory/InMemoryResultRepository.ts @@ -7,15 +7,16 @@ import { Result } from '@core/racing/domain/entities/result/Result'; import type { ResultRepository } from '@core/racing/domain/repositories/ResultRepository'; +import type { RaceRepository } from '@core/racing/domain/repositories/RaceRepository'; import type { Logger } from '@core/shared/domain/Logger'; import { v4 as uuidv4 } from 'uuid'; export class InMemoryResultRepository implements ResultRepository { private results: Map; - private raceRepository: IRaceRepository | null; + private raceRepository: RaceRepository | null; private readonly logger: Logger; - constructor(logger: Logger, raceRepository?: IRaceRepository | null) { + constructor(logger: Logger, raceRepository?: RaceRepository | null) { this.logger = logger; this.logger.info('[InMemoryResultRepository] Initialized.'); this.results = new Map(); @@ -86,7 +87,7 @@ export class InMemoryResultRepository implements ResultRepository { } const leagueRaces = await this.raceRepository.findByLeagueId(leagueId); - const leagueRaceIds = new Set(leagueRaces.map(race => race.id)); + const leagueRaceIds = new Set(leagueRaces.map((race: any) => race.id)); this.logger.debug(`[InMemoryResultRepository] Found ${leagueRaces.length} races in league ${leagueId}.`); const results = Array.from(this.results.values()) diff --git a/adapters/racing/persistence/inmemory/InMemoryStandingRepository.ts b/adapters/racing/persistence/inmemory/InMemoryStandingRepository.ts index 610b1464c..457a570d5 100644 --- a/adapters/racing/persistence/inmemory/InMemoryStandingRepository.ts +++ b/adapters/racing/persistence/inmemory/InMemoryStandingRepository.ts @@ -7,22 +7,25 @@ import { Standing } from '@core/racing/domain/entities/Standing'; import type { StandingRepository } from '@core/racing/domain/repositories/StandingRepository'; +import type { ResultRepository } from '@core/racing/domain/repositories/ResultRepository'; +import type { RaceRepository } from '@core/racing/domain/repositories/RaceRepository'; +import type { LeagueRepository } from '@core/racing/domain/repositories/LeagueRepository'; import type { Logger } from '@core/shared/domain/Logger'; export class InMemoryStandingRepository implements StandingRepository { private standings: Map; - private resultRepository: IResultRepository | null; - private raceRepository: IRaceRepository | null; - private leagueRepository: ILeagueRepository | null; + private resultRepository: ResultRepository | null; + private raceRepository: RaceRepository | null; + private leagueRepository: LeagueRepository | null; private readonly logger: Logger; private readonly pointsSystems: Record>; constructor( logger: Logger, pointsSystems: Record>, - resultRepository?: IResultRepository | null, - raceRepository?: IRaceRepository | null, - leagueRepository?: ILeagueRepository | null + resultRepository?: ResultRepository | null, + raceRepository?: RaceRepository | null, + leagueRepository?: LeagueRepository | null ) { this.logger = logger; this.pointsSystems = pointsSystems; @@ -198,7 +201,7 @@ export class InMemoryStandingRepository implements StandingRepository { } const allResults = await Promise.all( - races.map(async race => { + races.map(async (race: any) => { this.logger.debug(`Fetching results for race ${race.id}.`); const results = await this.resultRepository!.findByRaceId(race.id); this.logger.debug(`Found ${results.length} results for race ${race.id}.`); @@ -219,7 +222,7 @@ export class InMemoryStandingRepository implements StandingRepository { return Number(position); }; - results.forEach((result) => { + results.forEach((result: any) => { const driverIdStr = result.driverId.toString(); let standing = standingsMap.get(driverIdStr); diff --git a/adapters/racing/persistence/typeorm/mappers/StewardingOrmMappers.ts b/adapters/racing/persistence/typeorm/mappers/StewardingOrmMappers.ts index 87710a720..f74a2c5e1 100644 --- a/adapters/racing/persistence/typeorm/mappers/StewardingOrmMappers.ts +++ b/adapters/racing/persistence/typeorm/mappers/StewardingOrmMappers.ts @@ -136,7 +136,7 @@ function serializeProtestDefense(defense: Protest['defense']): SerializedProtest export class PenaltyOrmMapper { toOrmEntity(domain: Penalty): PenaltyOrmEntity { const entity = new PenaltyOrmEntity(); - entity.id = domain.id; + entity.id = domain.id.toString(); entity.leagueId = domain.leagueId; entity.raceId = domain.raceId; entity.driverId = domain.driverId; @@ -197,7 +197,7 @@ export class PenaltyOrmMapper { export class ProtestOrmMapper { toOrmEntity(domain: Protest): ProtestOrmEntity { const entity = new ProtestOrmEntity(); - entity.id = domain.id; + entity.id = domain.id.toString(); entity.raceId = domain.raceId; entity.protestingDriverId = domain.protestingDriverId; entity.accusedDriverId = domain.accusedDriverId; diff --git a/core/shared/domain/index.ts b/core/shared/domain/index.ts new file mode 100644 index 000000000..743ec3813 --- /dev/null +++ b/core/shared/domain/index.ts @@ -0,0 +1,7 @@ +export * from './DomainEvent'; +export * from './Entity'; +export * from './Logger'; +export * from './Option'; +export * from './Result'; +export * from './Service'; +export * from './ValueObject';