From 4318b380d91f0c5a66139d420c637903f73d8df2 Mon Sep 17 00:00:00 2001 From: Marc Mintel Date: Tue, 23 Dec 2025 17:31:45 +0100 Subject: [PATCH] fix issues in core --- .eslintrc.json | 49 +++++++++++++++++++ .../session/CookieIdentitySessionAdapter.ts | 15 +++--- .../inmemory/InMemorySocialAndFeed.ts | 0 apps/api/src/domain/driver/DriverProviders.ts | 2 +- .../presenters/GetLeagueProtestsPresenter.ts | 2 +- .../presenters/GetLeagueSeasonsPresenter.ts | 2 +- .../presenters/LeagueStandingsPresenter.ts | 2 +- .../league/presenters/LeagueStatsPresenter.ts | 2 +- .../presenters/AwardPrizePresenter.ts | 2 +- .../presenters/CreatePrizePresenter.ts | 2 +- .../presenters/DeletePrizePresenter.ts | 2 +- .../presenters/GetMembershipFeesPresenter.ts | 2 +- .../payments/presenters/GetPrizesPresenter.ts | 2 +- .../payments/presenters/GetWalletPresenter.ts | 2 +- .../ProcessWalletTransactionPresenter.ts | 2 +- .../UpdateMemberPaymentPresenter.ts | 2 +- .../UpsertMembershipFeePresenter.ts | 2 +- apps/api/src/shared/presentation/Presenter.ts | 5 ++ core/analytics/domain/ports/ILogger.ts | 6 --- .../GetCurrentUserSessionUseCase.test.ts | 7 ++- .../HandleAuthCallbackUseCase.test.ts | 13 +++-- .../use-cases/SignupWithEmailUseCase.test.ts | 5 +- .../use-cases/SignupWithEmailUseCase.ts | 4 +- core/notifications/infrastructure/index.ts | 6 --- core/shared/index.ts | 1 - core/shared/presentation/Presenter.ts | 6 --- core/shared/presentation/index.ts | 1 - core/social/application/dto/FeedItemDTO.ts | 22 --------- .../SocialUser.ts} | 9 +++- .../use-cases/GetCurrentUserSocialUseCase.ts | 12 ++--- .../IracingDemoIdentityProviderAdapter.ts | 20 ++++---- testing/fixtures/racing/RacingFeedSeed.ts | 6 +-- testing/fixtures/racing/RacingStaticSeed.ts | 4 +- .../dto => testing/types}/FriendDTO.ts | 0 34 files changed, 116 insertions(+), 103 deletions(-) rename {core/social/infrastructure => adapters/social/persistence}/inmemory/InMemorySocialAndFeed.ts (100%) create mode 100644 apps/api/src/shared/presentation/Presenter.ts delete mode 100644 core/analytics/domain/ports/ILogger.ts delete mode 100644 core/notifications/infrastructure/index.ts delete mode 100644 core/shared/presentation/Presenter.ts delete mode 100644 core/shared/presentation/index.ts delete mode 100644 core/social/application/dto/FeedItemDTO.ts rename core/social/application/{dto/CurrentUserSocialDTO.ts => types/SocialUser.ts} (51%) rename {core/social/application/dto => testing/types}/FriendDTO.ts (100%) diff --git a/.eslintrc.json b/.eslintrc.json index bd08576be..22cd5914d 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -7,6 +7,7 @@ "sourceType": "module", "ecmaVersion": 2022 }, + "ignorePatterns": ["**/dist/**", "**/*.d.ts"], "settings": { "import/resolver": { "typescript": {} @@ -83,6 +84,54 @@ ] } }, + { + "files": ["core/**/application/dto/**/*.ts", "core/**/application/dtos/**/*.ts"], + "rules": { + "no-restricted-syntax": [ + "error", + { + "selector": "Program", + "message": "core/*/application/dto is forbidden. Use application result models + output ports; DTOs belong in API/website layers." + } + ] + } + }, + { + "files": ["core/**/infrastructure/**/*.ts"], + "rules": { + "no-restricted-syntax": [ + "error", + { + "selector": "Program", + "message": "core/*/infrastructure is forbidden. Implementations must live in adapters/ and be wired in apps/." + } + ] + } + }, + { + "files": ["core/**/domain/ports/**/*.ts"], + "rules": { + "no-restricted-syntax": [ + "error", + { + "selector": "Program", + "message": "core/*/domain/ports is forbidden. Ports belong in application/ports (or shared application layer), not domain." + } + ] + } + }, + { + "files": ["core/**/shared/presentation/**/*.ts"], + "rules": { + "no-restricted-syntax": [ + "error", + { + "selector": "Program", + "message": "core/shared/presentation is forbidden. Presentation belongs in API or website layers." + } + ] + } + }, { "files": ["apps/website/**/*.ts"], "rules": { diff --git a/adapters/identity/session/CookieIdentitySessionAdapter.ts b/adapters/identity/session/CookieIdentitySessionAdapter.ts index 085c006ae..d00fd8516 100644 --- a/adapters/identity/session/CookieIdentitySessionAdapter.ts +++ b/adapters/identity/session/CookieIdentitySessionAdapter.ts @@ -4,13 +4,12 @@ * Manages user session using cookies. This is a placeholder implementation. */ -import type { AuthenticatedUserDTO } from '@core/identity/application/dto/AuthenticatedUserDTO'; -import type { AuthSessionDTO } from '@core/identity/application/dto/AuthSessionDTO'; -import type { IdentitySessionPort } from '@core/identity/application/ports/IdentitySessionPort'; -import { Logger } from '@core/shared/application'; +import type { AuthenticatedUser } from '@core/identity/application/ports/IdentityProviderPort'; +import type { AuthSession, IdentitySessionPort } from '@core/identity/application/ports/IdentitySessionPort'; +import type { Logger } from '@core/shared/application'; export class CookieIdentitySessionAdapter implements IdentitySessionPort { - private currentSession: AuthSessionDTO | null = null; + private currentSession: AuthSession | null = null; constructor(private readonly logger: Logger) { this.logger.info('CookieIdentitySessionAdapter initialized.'); @@ -18,14 +17,14 @@ export class CookieIdentitySessionAdapter implements IdentitySessionPort { // For demo, we'll start with no session. } - async getCurrentSession(): Promise { + async getCurrentSession(): Promise { this.logger.debug('[CookieIdentitySessionAdapter] Getting current session.'); return Promise.resolve(this.currentSession); } - async createSession(user: AuthenticatedUserDTO): Promise { + async createSession(user: AuthenticatedUser): Promise { this.logger.debug(`[CookieIdentitySessionAdapter] Creating session for user: ${user.id}`); - const newSession: AuthSessionDTO = { + const newSession: AuthSession = { user: user, issuedAt: Date.now(), expiresAt: Date.now() + 3600 * 1000, // 1 hour expiration diff --git a/core/social/infrastructure/inmemory/InMemorySocialAndFeed.ts b/adapters/social/persistence/inmemory/InMemorySocialAndFeed.ts similarity index 100% rename from core/social/infrastructure/inmemory/InMemorySocialAndFeed.ts rename to adapters/social/persistence/inmemory/InMemorySocialAndFeed.ts diff --git a/apps/api/src/domain/driver/DriverProviders.ts b/apps/api/src/domain/driver/DriverProviders.ts index 15df43f01..98699b759 100644 --- a/apps/api/src/domain/driver/DriverProviders.ts +++ b/apps/api/src/domain/driver/DriverProviders.ts @@ -33,7 +33,7 @@ import { InMemoryDriverRatingProvider } from '@adapters/racing/ports/InMemoryDri import { InMemoryDriverStatsService } from '@adapters/racing/services/InMemoryDriverStatsService'; import { InMemoryRankingService } from '@adapters/racing/services/InMemoryRankingService'; import { IImageServicePort } from '@core/racing/application/ports/IImageServicePort'; -import { InMemorySocialGraphRepository } from '@core/social/infrastructure/inmemory/InMemorySocialAndFeed'; +import { InMemorySocialGraphRepository } from '@adapters/social/persistence/inmemory/InMemorySocialAndFeed'; // Import presenters import { CompleteOnboardingPresenter } from './presenters/CompleteOnboardingPresenter'; diff --git a/apps/api/src/domain/league/presenters/GetLeagueProtestsPresenter.ts b/apps/api/src/domain/league/presenters/GetLeagueProtestsPresenter.ts index 8626f77d2..2743ab41e 100644 --- a/apps/api/src/domain/league/presenters/GetLeagueProtestsPresenter.ts +++ b/apps/api/src/domain/league/presenters/GetLeagueProtestsPresenter.ts @@ -1,4 +1,4 @@ -import { Presenter } from '@core/shared/presentation'; +import type { Presenter } from '../../../shared/presentation/Presenter'; import type { GetLeagueProtestsResult } from '@core/racing/application/use-cases/GetLeagueProtestsUseCase'; import { LeagueAdminProtestsDTO } from '../dtos/LeagueAdminProtestsDTO'; import { ProtestDTO } from '../dtos/ProtestDTO'; diff --git a/apps/api/src/domain/league/presenters/GetLeagueSeasonsPresenter.ts b/apps/api/src/domain/league/presenters/GetLeagueSeasonsPresenter.ts index 512923eb1..96ae1e0c6 100644 --- a/apps/api/src/domain/league/presenters/GetLeagueSeasonsPresenter.ts +++ b/apps/api/src/domain/league/presenters/GetLeagueSeasonsPresenter.ts @@ -1,4 +1,4 @@ -import { Presenter } from '@core/shared/presentation'; +import type { Presenter } from '../../../shared/presentation/Presenter'; import type { GetLeagueSeasonsResult } from '@core/racing/application/use-cases/GetLeagueSeasonsUseCase'; import { LeagueSeasonSummaryDTO } from '../dtos/LeagueSeasonSummaryDTO'; diff --git a/apps/api/src/domain/league/presenters/LeagueStandingsPresenter.ts b/apps/api/src/domain/league/presenters/LeagueStandingsPresenter.ts index 129e15cc4..1dd5d2f01 100644 --- a/apps/api/src/domain/league/presenters/LeagueStandingsPresenter.ts +++ b/apps/api/src/domain/league/presenters/LeagueStandingsPresenter.ts @@ -1,6 +1,6 @@ import type { GetLeagueStandingsResult } from '@core/racing/application/use-cases/GetLeagueStandingsUseCase'; import { LeagueStandingsDTO } from '../dtos/LeagueStandingsDTO'; -import type { Presenter } from '@core/shared/presentation'; +import type { Presenter } from '../../../shared/presentation/Presenter'; export class LeagueStandingsPresenter implements Presenter { private result: LeagueStandingsDTO | null = null; diff --git a/apps/api/src/domain/league/presenters/LeagueStatsPresenter.ts b/apps/api/src/domain/league/presenters/LeagueStatsPresenter.ts index 17ca887a7..c6972a2b4 100644 --- a/apps/api/src/domain/league/presenters/LeagueStatsPresenter.ts +++ b/apps/api/src/domain/league/presenters/LeagueStatsPresenter.ts @@ -1,6 +1,6 @@ import type { GetLeagueStatsResult } from '@core/racing/application/use-cases/GetLeagueStatsUseCase'; import { LeagueStatsDTO } from '../dtos/LeagueStatsDTO'; -import type { Presenter } from '@core/shared/presentation'; +import type { Presenter } from '../../../shared/presentation/Presenter'; export class LeagueStatsPresenter implements Presenter { private result: LeagueStatsDTO | null = null; diff --git a/apps/api/src/domain/payments/presenters/AwardPrizePresenter.ts b/apps/api/src/domain/payments/presenters/AwardPrizePresenter.ts index 882c472d7..5b4a484f5 100644 --- a/apps/api/src/domain/payments/presenters/AwardPrizePresenter.ts +++ b/apps/api/src/domain/payments/presenters/AwardPrizePresenter.ts @@ -1,4 +1,4 @@ -import type { Presenter } from '@core/shared/presentation/Presenter'; +import type { Presenter } from '../../../shared/presentation/Presenter'; import { AwardPrizeResultDTO } from '../dtos/AwardPrizeDTO'; export interface IAwardPrizePresenter extends Presenter {} diff --git a/apps/api/src/domain/payments/presenters/CreatePrizePresenter.ts b/apps/api/src/domain/payments/presenters/CreatePrizePresenter.ts index fa3226f71..e577aea7d 100644 --- a/apps/api/src/domain/payments/presenters/CreatePrizePresenter.ts +++ b/apps/api/src/domain/payments/presenters/CreatePrizePresenter.ts @@ -1,4 +1,4 @@ -import type { Presenter } from '@core/shared/presentation/Presenter'; +import type { Presenter } from '../../../shared/presentation/Presenter'; import { CreatePrizeResultDTO } from '../dtos/CreatePrizeDTO'; export interface ICreatePrizePresenter extends Presenter {} diff --git a/apps/api/src/domain/payments/presenters/DeletePrizePresenter.ts b/apps/api/src/domain/payments/presenters/DeletePrizePresenter.ts index 50dbf02ee..1cc959fa5 100644 --- a/apps/api/src/domain/payments/presenters/DeletePrizePresenter.ts +++ b/apps/api/src/domain/payments/presenters/DeletePrizePresenter.ts @@ -1,4 +1,4 @@ -import type { Presenter } from '@core/shared/presentation/Presenter'; +import type { Presenter } from '../../../shared/presentation/Presenter'; import { DeletePrizeResultDTO } from '../dtos/DeletePrizeDTO'; export interface IDeletePrizePresenter extends Presenter {} diff --git a/apps/api/src/domain/payments/presenters/GetMembershipFeesPresenter.ts b/apps/api/src/domain/payments/presenters/GetMembershipFeesPresenter.ts index 477aba952..81b351945 100644 --- a/apps/api/src/domain/payments/presenters/GetMembershipFeesPresenter.ts +++ b/apps/api/src/domain/payments/presenters/GetMembershipFeesPresenter.ts @@ -1,4 +1,4 @@ -import type { Presenter } from '@core/shared/presentation/Presenter'; +import type { Presenter } from '../../../shared/presentation/Presenter'; import { GetMembershipFeesResultDTO } from '../dtos/GetMembershipFeesDTO'; export interface IGetMembershipFeesPresenter extends Presenter {} diff --git a/apps/api/src/domain/payments/presenters/GetPrizesPresenter.ts b/apps/api/src/domain/payments/presenters/GetPrizesPresenter.ts index 0c6e2c4db..5a7b04f53 100644 --- a/apps/api/src/domain/payments/presenters/GetPrizesPresenter.ts +++ b/apps/api/src/domain/payments/presenters/GetPrizesPresenter.ts @@ -1,4 +1,4 @@ -import type { Presenter } from '@core/shared/presentation/Presenter'; +import type { Presenter } from '../../../shared/presentation/Presenter'; import { GetPrizesResultDTO } from '../dtos/GetPrizesDTO'; export interface IGetPrizesPresenter extends Presenter {} diff --git a/apps/api/src/domain/payments/presenters/GetWalletPresenter.ts b/apps/api/src/domain/payments/presenters/GetWalletPresenter.ts index 380321ba4..2c19fca13 100644 --- a/apps/api/src/domain/payments/presenters/GetWalletPresenter.ts +++ b/apps/api/src/domain/payments/presenters/GetWalletPresenter.ts @@ -1,4 +1,4 @@ -import type { Presenter } from '@core/shared/presentation/Presenter'; +import type { Presenter } from '../../../shared/presentation/Presenter'; import { GetWalletResultDTO } from '../dtos/GetWalletDTO'; export interface IGetWalletPresenter extends Presenter {} diff --git a/apps/api/src/domain/payments/presenters/ProcessWalletTransactionPresenter.ts b/apps/api/src/domain/payments/presenters/ProcessWalletTransactionPresenter.ts index 0692dac20..2f2c4487d 100644 --- a/apps/api/src/domain/payments/presenters/ProcessWalletTransactionPresenter.ts +++ b/apps/api/src/domain/payments/presenters/ProcessWalletTransactionPresenter.ts @@ -1,4 +1,4 @@ -import type { Presenter } from '@core/shared/presentation/Presenter'; +import type { Presenter } from '../../../shared/presentation/Presenter'; import { ProcessWalletTransactionResultDTO } from '../dtos/ProcessWalletTransactionDTO'; export interface IProcessWalletTransactionPresenter extends Presenter {} diff --git a/apps/api/src/domain/payments/presenters/UpdateMemberPaymentPresenter.ts b/apps/api/src/domain/payments/presenters/UpdateMemberPaymentPresenter.ts index c0c0f691c..9362c05e4 100644 --- a/apps/api/src/domain/payments/presenters/UpdateMemberPaymentPresenter.ts +++ b/apps/api/src/domain/payments/presenters/UpdateMemberPaymentPresenter.ts @@ -1,4 +1,4 @@ -import type { Presenter } from '@core/shared/presentation/Presenter'; +import type { Presenter } from '../../../shared/presentation/Presenter'; import { UpdateMemberPaymentResultDTO } from '../dtos/UpdateMemberPaymentDTO'; export interface IUpdateMemberPaymentPresenter extends Presenter {} diff --git a/apps/api/src/domain/payments/presenters/UpsertMembershipFeePresenter.ts b/apps/api/src/domain/payments/presenters/UpsertMembershipFeePresenter.ts index f44b83f90..c83a52fea 100644 --- a/apps/api/src/domain/payments/presenters/UpsertMembershipFeePresenter.ts +++ b/apps/api/src/domain/payments/presenters/UpsertMembershipFeePresenter.ts @@ -1,4 +1,4 @@ -import type { Presenter } from '@core/shared/presentation/Presenter'; +import type { Presenter } from '../../../shared/presentation/Presenter'; import { UpsertMembershipFeeResultDTO } from '../dtos/UpsertMembershipFeeDTO'; export interface IUpsertMembershipFeePresenter extends Presenter {} diff --git a/apps/api/src/shared/presentation/Presenter.ts b/apps/api/src/shared/presentation/Presenter.ts new file mode 100644 index 000000000..ea2533fa1 --- /dev/null +++ b/apps/api/src/shared/presentation/Presenter.ts @@ -0,0 +1,5 @@ +export interface Presenter { + present(input: Input): void; + getResponseModel(): ResponseModel | null; + reset(): void; +} \ No newline at end of file diff --git a/core/analytics/domain/ports/ILogger.ts b/core/analytics/domain/ports/ILogger.ts deleted file mode 100644 index 0b4d1e8a2..000000000 --- a/core/analytics/domain/ports/ILogger.ts +++ /dev/null @@ -1,6 +0,0 @@ -export interface Logger { - debug(message: string, ...args: unknown[]): void; - info(message: string, ...args: unknown[]): void; - warn(message: string, ...args: unknown[]): void; - error(message: string, ...args: unknown[]): void; -} diff --git a/core/identity/application/use-cases/GetCurrentUserSessionUseCase.test.ts b/core/identity/application/use-cases/GetCurrentUserSessionUseCase.test.ts index c70356628..f3cee35fe 100644 --- a/core/identity/application/use-cases/GetCurrentUserSessionUseCase.test.ts +++ b/core/identity/application/use-cases/GetCurrentUserSessionUseCase.test.ts @@ -1,7 +1,6 @@ import { describe, it, expect, vi, type Mock } from 'vitest'; import { GetCurrentUserSessionUseCase } from './GetCurrentUserSessionUseCase'; -import type { IdentitySessionPort } from '../ports/IdentitySessionPort'; -import type { AuthSessionDTO } from '../dto/AuthSessionDTO'; +import type { AuthSession, IdentitySessionPort } from '../ports/IdentitySessionPort'; import type { Logger, UseCaseOutputPort } from '@core/shared/application'; describe('GetCurrentUserSessionUseCase', () => { @@ -11,7 +10,7 @@ describe('GetCurrentUserSessionUseCase', () => { clearSession: Mock; }; let logger: Logger; - let output: UseCaseOutputPort & { present: Mock }; + let output: UseCaseOutputPort & { present: Mock }; let useCase: GetCurrentUserSessionUseCase; beforeEach(() => { @@ -40,7 +39,7 @@ describe('GetCurrentUserSessionUseCase', () => { }); it('returns the current auth session when one exists', async () => { - const session: AuthSessionDTO = { + const session: AuthSession = { user: { id: 'user-1', email: 'test@example.com', diff --git a/core/identity/application/use-cases/HandleAuthCallbackUseCase.test.ts b/core/identity/application/use-cases/HandleAuthCallbackUseCase.test.ts index b71e5065f..2353464cc 100644 --- a/core/identity/application/use-cases/HandleAuthCallbackUseCase.test.ts +++ b/core/identity/application/use-cases/HandleAuthCallbackUseCase.test.ts @@ -2,9 +2,8 @@ import { describe, it, expect, vi, type Mock } from 'vitest'; import { HandleAuthCallbackUseCase } from './HandleAuthCallbackUseCase'; import type { IdentityProviderPort } from '../ports/IdentityProviderPort'; import type { IdentitySessionPort } from '../ports/IdentitySessionPort'; -import type { AuthCallbackCommandDTO } from '../dto/AuthCallbackCommandDTO'; -import type { AuthenticatedUserDTO } from '../dto/AuthenticatedUserDTO'; -import type { AuthSessionDTO } from '../dto/AuthSessionDTO'; +import type { AuthCallbackCommand, AuthenticatedUser } from '../ports/IdentityProviderPort'; +import type { AuthSession } from '../ports/IdentitySessionPort'; import type { Logger, UseCaseOutputPort } from '@core/shared/application'; describe('HandleAuthCallbackUseCase', () => { @@ -17,7 +16,7 @@ describe('HandleAuthCallbackUseCase', () => { clearSession: Mock; }; let logger: Logger; - let output: UseCaseOutputPort & { present: Mock }; + let output: UseCaseOutputPort & { present: Mock }; let useCase: HandleAuthCallbackUseCase; beforeEach(() => { @@ -48,20 +47,20 @@ describe('HandleAuthCallbackUseCase', () => { }); it('completes auth and creates a session', async () => { - const command: AuthCallbackCommandDTO = { + const command: AuthCallbackCommand = { provider: 'IRACING_DEMO', code: 'auth-code', state: 'state-123', returnTo: 'https://app/callback', }; - const user: AuthenticatedUserDTO = { + const user: AuthenticatedUser = { id: 'user-1', email: 'test@example.com', displayName: 'Test User', }; - const session: AuthSessionDTO = { + const session: AuthSession = { user, issuedAt: Date.now(), expiresAt: Date.now() + 1000, diff --git a/core/identity/application/use-cases/SignupWithEmailUseCase.test.ts b/core/identity/application/use-cases/SignupWithEmailUseCase.test.ts index 0b0610423..2040bfde6 100644 --- a/core/identity/application/use-cases/SignupWithEmailUseCase.test.ts +++ b/core/identity/application/use-cases/SignupWithEmailUseCase.test.ts @@ -2,8 +2,7 @@ import { describe, it, expect, vi, type Mock } from 'vitest'; import { SignupWithEmailUseCase } from './SignupWithEmailUseCase'; import type { SignupWithEmailInput } from './SignupWithEmailUseCase'; import type { IUserRepository, StoredUser } from '../../domain/repositories/IUserRepository'; -import type { IdentitySessionPort } from '../ports/IdentitySessionPort'; -import type { AuthSessionDTO } from '../dto/AuthSessionDTO'; +import type { AuthSession, IdentitySessionPort } from '../ports/IdentitySessionPort'; import type { Logger, UseCaseOutputPort } from '@core/shared/application'; type SignupWithEmailOutput = unknown; @@ -58,7 +57,7 @@ describe('SignupWithEmailUseCase', () => { userRepository.findByEmail.mockResolvedValue(null); - const session: AuthSessionDTO = { + const session: AuthSession = { user: { id: 'user-1', email: command.email.toLowerCase(), diff --git a/core/identity/application/use-cases/SignupWithEmailUseCase.ts b/core/identity/application/use-cases/SignupWithEmailUseCase.ts index f299e6ea3..4dac73a4f 100644 --- a/core/identity/application/use-cases/SignupWithEmailUseCase.ts +++ b/core/identity/application/use-cases/SignupWithEmailUseCase.ts @@ -5,7 +5,7 @@ */ import type { IUserRepository, StoredUser } from '../../domain/repositories/IUserRepository'; -import type { AuthenticatedUserDTO } from '../dto/AuthenticatedUserDTO'; +import type { AuthenticatedUser } from '../ports/IdentityProviderPort'; import type { IdentitySessionPort } from '../ports/IdentitySessionPort'; import { Result } from '@core/shared/application/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; @@ -103,7 +103,7 @@ export class SignupWithEmailUseCase { await this.userRepository.create(newUser); // Create session - const authenticatedUser: AuthenticatedUserDTO = { + const authenticatedUser: AuthenticatedUser = { id: newUser.id, displayName: newUser.displayName, email: newUser.email, diff --git a/core/notifications/infrastructure/index.ts b/core/notifications/infrastructure/index.ts deleted file mode 100644 index 5c6d6b42c..000000000 --- a/core/notifications/infrastructure/index.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * Infrastructure layer exports for notifications package - */ - -// This infrastructure layer is empty as the actual implementations -// are in the adapters directory \ No newline at end of file diff --git a/core/shared/index.ts b/core/shared/index.ts index f0dc72742..6d2e46952 100644 --- a/core/shared/index.ts +++ b/core/shared/index.ts @@ -2,5 +2,4 @@ export * from './application/Result'; export * as application from './application'; export * as domain from './domain'; export * as errors from './errors'; -export * from './presentation'; export * from './application/AsyncUseCase'; \ No newline at end of file diff --git a/core/shared/presentation/Presenter.ts b/core/shared/presentation/Presenter.ts deleted file mode 100644 index 37877dac2..000000000 --- a/core/shared/presentation/Presenter.ts +++ /dev/null @@ -1,6 +0,0 @@ -// This must not be used within core. It's in presentation layer, e.g. to be used in an API. -export interface Presenter { - present(input: InputDTO): void; - getResponseModel(): ResponseModel | null; - reset(): void; -} \ No newline at end of file diff --git a/core/shared/presentation/index.ts b/core/shared/presentation/index.ts deleted file mode 100644 index 3aca414b9..000000000 --- a/core/shared/presentation/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './Presenter'; \ No newline at end of file diff --git a/core/social/application/dto/FeedItemDTO.ts b/core/social/application/dto/FeedItemDTO.ts deleted file mode 100644 index 8ec560ee2..000000000 --- a/core/social/application/dto/FeedItemDTO.ts +++ /dev/null @@ -1,22 +0,0 @@ -export type FeedItemType = - | 'race_result' - | 'championship_standing' - | 'league_announcement' - | 'friend_joined_league' - | 'friend_won_race'; - -export interface FeedItemDTO { - id: string; - timestamp: string; - type: FeedItemType; - actorFriendId?: string; - actorDriverId?: string; - leagueId?: string; - raceId?: string; - teamId?: string; - position?: number; - headline: string; - body?: string; - ctaLabel?: string; - ctaHref?: string; -} \ No newline at end of file diff --git a/core/social/application/dto/CurrentUserSocialDTO.ts b/core/social/application/types/SocialUser.ts similarity index 51% rename from core/social/application/dto/CurrentUserSocialDTO.ts rename to core/social/application/types/SocialUser.ts index b897d4ae5..e1fd1ff2c 100644 --- a/core/social/application/dto/CurrentUserSocialDTO.ts +++ b/core/social/application/types/SocialUser.ts @@ -1,8 +1,13 @@ -export interface CurrentUserSocialDTO { +export type SocialUserSummary = { driverId: string; displayName: string; avatarUrl: string; countryCode: string; primaryTeamId?: string; primaryLeagueId?: string; -} \ No newline at end of file +}; + +export type SocialFriendSummary = SocialUserSummary & { + isOnline: boolean; + lastSeen: Date; +}; \ No newline at end of file diff --git a/core/social/application/use-cases/GetCurrentUserSocialUseCase.ts b/core/social/application/use-cases/GetCurrentUserSocialUseCase.ts index 2800dde3f..64f20ee32 100644 --- a/core/social/application/use-cases/GetCurrentUserSocialUseCase.ts +++ b/core/social/application/use-cases/GetCurrentUserSocialUseCase.ts @@ -2,8 +2,7 @@ import type { Logger, UseCaseOutputPort } from '@core/shared/application'; import { Result } from '@core/shared/application/Result'; import type { ApplicationErrorCode } from '@core/shared/errors/ApplicationErrorCode'; import type { ISocialGraphRepository } from '../../domain/repositories/ISocialGraphRepository'; -import type { CurrentUserSocialDTO } from '../dto/CurrentUserSocialDTO'; -import type { FriendDTO } from '../dto/FriendDTO'; +import type { SocialFriendSummary, SocialUserSummary } from '../types/SocialUser'; export interface GetCurrentUserSocialParams { driverId: string; @@ -12,8 +11,8 @@ export interface GetCurrentUserSocialParams { export type GetCurrentUserSocialInput = GetCurrentUserSocialParams; export interface GetCurrentUserSocialResult { - currentUser: CurrentUserSocialDTO; - friends: FriendDTO[]; + currentUser: SocialUserSummary; + friends: SocialFriendSummary[]; } export type GetCurrentUserSocialErrorCode = 'REPOSITORY_ERROR'; @@ -61,15 +60,16 @@ export class GetCurrentUserSocialUseCase { // The social graph context currently only knows about relationships. // Profile fields for the current user are expected to be enriched by identity/profile contexts. - const friends: FriendDTO[] = friendsDomain.map((friend) => ({ + const friends: SocialFriendSummary[] = friendsDomain.map((friend) => ({ driverId: friend.id, displayName: friend.name.toString(), avatarUrl: '', + countryCode: '', isOnline: false, lastSeen: new Date(), })); - const currentUser: CurrentUserSocialDTO = { + const currentUser: SocialUserSummary = { driverId, displayName: '', avatarUrl: '', diff --git a/testing/fakes/identity/IracingDemoIdentityProviderAdapter.ts b/testing/fakes/identity/IracingDemoIdentityProviderAdapter.ts index af64fbde0..0fb3bbe73 100644 --- a/testing/fakes/identity/IracingDemoIdentityProviderAdapter.ts +++ b/testing/fakes/identity/IracingDemoIdentityProviderAdapter.ts @@ -1,19 +1,19 @@ import { randomUUID } from 'crypto'; -import { createStaticRacingSeed } from '@core/testing-support'; -import type { IdentityProviderPort } from '../../application/ports/IdentityProviderPort'; -import type { StartAuthCommandDTO } from '../../application/dto/StartAuthCommandDTO'; -import type { AuthCallbackCommandDTO } from '../../application/dto/AuthCallbackCommandDTO'; -import type { AuthenticatedUserDTO } from '../../application/dto/AuthenticatedUserDTO'; +import type { + AuthCallbackCommand, + AuthenticatedUser, + IdentityProviderPort, + StartAuthCommand, +} from '@core/identity/application/ports/IdentityProviderPort'; export class IracingDemoIdentityProviderAdapter implements IdentityProviderPort { private readonly seedDriverId: string; constructor() { - const seed = createStaticRacingSeed(42); - this.seedDriverId = seed.drivers[0]?.id ?? 'driver-1'; + this.seedDriverId = 'driver-1'; } - async startAuth(command: StartAuthCommandDTO): Promise<{ redirectUrl: string; state: string }> { + async startAuth(command: StartAuthCommand): Promise<{ redirectUrl: string; state: string }> { const state = randomUUID(); const params = new URLSearchParams(); @@ -29,7 +29,7 @@ export class IracingDemoIdentityProviderAdapter implements IdentityProviderPort }; } - async completeAuth(command: AuthCallbackCommandDTO): Promise { + async completeAuth(command: AuthCallbackCommand): Promise { if (!command.code) { throw new Error('Missing auth code'); } @@ -37,7 +37,7 @@ export class IracingDemoIdentityProviderAdapter implements IdentityProviderPort throw new Error('Missing auth state'); } - const user: AuthenticatedUserDTO = { + const user: AuthenticatedUser = { id: 'demo-user', displayName: 'GridPilot Demo Driver', iracingCustomerId: '000000', diff --git a/testing/fixtures/racing/RacingFeedSeed.ts b/testing/fixtures/racing/RacingFeedSeed.ts index 1e0ec8117..82de2ee73 100644 --- a/testing/fixtures/racing/RacingFeedSeed.ts +++ b/testing/fixtures/racing/RacingFeedSeed.ts @@ -3,7 +3,7 @@ import { League } from '@core/racing/domain/entities/League'; import { Race } from '@core/racing/domain/entities/Race'; import type { Result } from '@core/racing/domain/entities/Result'; import type { FeedItem } from '@core/social/domain/types/FeedItem'; -import type { FriendDTO } from '@core/social/application/dto/FriendDTO'; +import type { SocialFriendSummary } from '@core/social/application/types/SocialUser'; import { faker } from '../../helpers/faker/faker'; import { getLeagueBanner, getDriverAvatar } from '../../helpers/images/images'; import type { Friendship, RacingMembership } from './RacingSeedCore'; @@ -166,11 +166,11 @@ export function createFeedEvents( export function buildFriends( drivers: Driver[], memberships: RacingMembership[], -): FriendDTO[] { +): SocialFriendSummary[] { return drivers.map((driver) => { const membership = memberships.find((m) => m.driverId === driver.id); - const base: FriendDTO = { + const base: SocialFriendSummary = { driverId: driver.id, displayName: driver.name, avatarUrl: getDriverAvatar(driver.id), diff --git a/testing/fixtures/racing/RacingStaticSeed.ts b/testing/fixtures/racing/RacingStaticSeed.ts index 5b66cc071..26f3e7345 100644 --- a/testing/fixtures/racing/RacingStaticSeed.ts +++ b/testing/fixtures/racing/RacingStaticSeed.ts @@ -5,7 +5,7 @@ import { Result } from '@core/racing/domain/entities/Result'; import { Standing } from '@core/racing/domain/entities/Standing'; import type { FeedItem } from '@core/social/domain/types/FeedItem'; -import type { FriendDTO } from '@core/social/application/dto/FriendDTO'; +import type { SocialFriendSummary } from '@core/social/application/types/SocialUser'; import { faker } from '../../helpers/faker/faker'; import { getTeamLogo } from '../../helpers/images/images'; @@ -128,7 +128,7 @@ export const sponsorshipPricings = staticSeed.sponsorshipPricings; * Derived friend DTOs for UI consumption. * This preserves the previous demo-data `friends` shape. */ -export const friends: FriendDTO[] = buildFriends(staticSeed.drivers, staticSeed.memberships); +export const friends: SocialFriendSummary[] = buildFriends(staticSeed.drivers, staticSeed.memberships); /** * Top leagues with banner URLs for UI. diff --git a/core/social/application/dto/FriendDTO.ts b/testing/types/FriendDTO.ts similarity index 100% rename from core/social/application/dto/FriendDTO.ts rename to testing/types/FriendDTO.ts