diff --git a/core/automation/application/dto/AutomationEngineValidationResultDTO.ts b/apps/companion/main/automation/application/dto/AutomationEngineValidationResultDTO.ts similarity index 100% rename from core/automation/application/dto/AutomationEngineValidationResultDTO.ts rename to apps/companion/main/automation/application/dto/AutomationEngineValidationResultDTO.ts diff --git a/core/automation/application/dto/AutomationResultDTO.ts b/apps/companion/main/automation/application/dto/AutomationResultDTO.ts similarity index 100% rename from core/automation/application/dto/AutomationResultDTO.ts rename to apps/companion/main/automation/application/dto/AutomationResultDTO.ts diff --git a/core/automation/application/dto/CheckoutConfirmationRequestDTO.ts b/apps/companion/main/automation/application/dto/CheckoutConfirmationRequestDTO.ts similarity index 100% rename from core/automation/application/dto/CheckoutConfirmationRequestDTO.ts rename to apps/companion/main/automation/application/dto/CheckoutConfirmationRequestDTO.ts diff --git a/core/automation/application/dto/CheckoutInfoDTO.ts b/apps/companion/main/automation/application/dto/CheckoutInfoDTO.ts similarity index 100% rename from core/automation/application/dto/CheckoutInfoDTO.ts rename to apps/companion/main/automation/application/dto/CheckoutInfoDTO.ts diff --git a/core/automation/application/dto/ClickResultDTO.ts b/apps/companion/main/automation/application/dto/ClickResultDTO.ts similarity index 100% rename from core/automation/application/dto/ClickResultDTO.ts rename to apps/companion/main/automation/application/dto/ClickResultDTO.ts diff --git a/core/automation/application/dto/FormFillResultDTO.ts b/apps/companion/main/automation/application/dto/FormFillResultDTO.ts similarity index 100% rename from core/automation/application/dto/FormFillResultDTO.ts rename to apps/companion/main/automation/application/dto/FormFillResultDTO.ts diff --git a/core/automation/application/dto/ModalResultDTO.ts b/apps/companion/main/automation/application/dto/ModalResultDTO.ts similarity index 100% rename from core/automation/application/dto/ModalResultDTO.ts rename to apps/companion/main/automation/application/dto/ModalResultDTO.ts diff --git a/core/automation/application/dto/NavigationResultDTO.ts b/apps/companion/main/automation/application/dto/NavigationResultDTO.ts similarity index 100% rename from core/automation/application/dto/NavigationResultDTO.ts rename to apps/companion/main/automation/application/dto/NavigationResultDTO.ts diff --git a/core/automation/application/dto/SessionDTO.ts b/apps/companion/main/automation/application/dto/SessionDTO.ts similarity index 100% rename from core/automation/application/dto/SessionDTO.ts rename to apps/companion/main/automation/application/dto/SessionDTO.ts diff --git a/core/automation/application/dto/WaitResultDTO.ts b/apps/companion/main/automation/application/dto/WaitResultDTO.ts similarity index 100% rename from core/automation/application/dto/WaitResultDTO.ts rename to apps/companion/main/automation/application/dto/WaitResultDTO.ts diff --git a/core/automation/application/ports/AuthenticationServicePort.ts b/apps/companion/main/automation/application/ports/AuthenticationServicePort.ts similarity index 97% rename from core/automation/application/ports/AuthenticationServicePort.ts rename to apps/companion/main/automation/application/ports/AuthenticationServicePort.ts index f316442d4..e59019979 100644 --- a/core/automation/application/ports/AuthenticationServicePort.ts +++ b/apps/companion/main/automation/application/ports/AuthenticationServicePort.ts @@ -1,6 +1,6 @@ import { AuthenticationState } from '../../domain/value-objects/AuthenticationState'; import { BrowserAuthenticationState } from '../../domain/value-objects/BrowserAuthenticationState'; -import { Result } from '../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; /** * Port for authentication services implementing zero-knowledge login. diff --git a/core/automation/application/ports/AutomationEnginePort.ts b/apps/companion/main/automation/application/ports/AutomationEnginePort.ts similarity index 100% rename from core/automation/application/ports/AutomationEnginePort.ts rename to apps/companion/main/automation/application/ports/AutomationEnginePort.ts diff --git a/core/automation/application/ports/AutomationEventPublisherPort.ts b/apps/companion/main/automation/application/ports/AutomationEventPublisherPort.ts similarity index 93% rename from core/automation/application/ports/AutomationEventPublisherPort.ts rename to apps/companion/main/automation/application/ports/AutomationEventPublisherPort.ts index ac4874ca5..ca40182e7 100644 --- a/core/automation/application/ports/AutomationEventPublisherPort.ts +++ b/apps/companion/main/automation/application/ports/AutomationEventPublisherPort.ts @@ -2,7 +2,7 @@ export type AutomationEvent = { actionId?: string type: 'panel-attached'|'modal-opened'|'action-started'|'action-complete'|'action-failed'|'panel-missing' timestamp: number - payload?: any + payload?: unknown } export interface AutomationEventPublisherPort { diff --git a/core/automation/application/ports/AutomationLifecycleEmitterPort.ts b/apps/companion/main/automation/application/ports/AutomationLifecycleEmitterPort.ts similarity index 100% rename from core/automation/application/ports/AutomationLifecycleEmitterPort.ts rename to apps/companion/main/automation/application/ports/AutomationLifecycleEmitterPort.ts diff --git a/core/automation/application/ports/AutomationResults.ts b/apps/companion/main/automation/application/ports/AutomationResults.ts similarity index 100% rename from core/automation/application/ports/AutomationResults.ts rename to apps/companion/main/automation/application/ports/AutomationResults.ts diff --git a/core/automation/application/ports/CheckoutConfirmationPort.ts b/apps/companion/main/automation/application/ports/CheckoutConfirmationPort.ts similarity index 85% rename from core/automation/application/ports/CheckoutConfirmationPort.ts rename to apps/companion/main/automation/application/ports/CheckoutConfirmationPort.ts index c0c566ff4..6350a69dc 100644 --- a/core/automation/application/ports/CheckoutConfirmationPort.ts +++ b/apps/companion/main/automation/application/ports/CheckoutConfirmationPort.ts @@ -1,4 +1,4 @@ -import { Result } from '../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; import { CheckoutConfirmation } from '../../domain/value-objects/CheckoutConfirmation'; import type { CheckoutConfirmationRequestDTO } from '../dto/CheckoutConfirmationRequestDTO'; diff --git a/core/automation/application/ports/CheckoutServicePort.ts b/apps/companion/main/automation/application/ports/CheckoutServicePort.ts similarity index 78% rename from core/automation/application/ports/CheckoutServicePort.ts rename to apps/companion/main/automation/application/ports/CheckoutServicePort.ts index 902d588c5..6a93ef10a 100644 --- a/core/automation/application/ports/CheckoutServicePort.ts +++ b/apps/companion/main/automation/application/ports/CheckoutServicePort.ts @@ -1,4 +1,4 @@ -import { Result } from '../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; import type { CheckoutInfoDTO } from '../dto/CheckoutInfoDTO'; export interface CheckoutServicePort { diff --git a/core/automation/application/ports/IAutomationEventPublisher.ts b/apps/companion/main/automation/application/ports/IAutomationEventPublisher.ts similarity index 93% rename from core/automation/application/ports/IAutomationEventPublisher.ts rename to apps/companion/main/automation/application/ports/IAutomationEventPublisher.ts index 4cecf3ee9..4e24fe83c 100644 --- a/core/automation/application/ports/IAutomationEventPublisher.ts +++ b/apps/companion/main/automation/application/ports/IAutomationEventPublisher.ts @@ -2,7 +2,7 @@ export type AutomationEvent = { actionId?: string type: 'panel-attached'|'modal-opened'|'action-started'|'action-complete'|'action-failed'|'panel-missing' timestamp: number - payload?: any + payload?: unknown } export interface IAutomationEventPublisher { diff --git a/core/automation/application/ports/IOverlaySyncPort.ts b/apps/companion/main/automation/application/ports/IOverlaySyncPort.ts similarity index 100% rename from core/automation/application/ports/IOverlaySyncPort.ts rename to apps/companion/main/automation/application/ports/IOverlaySyncPort.ts diff --git a/core/automation/application/ports/LoggerContext.ts b/apps/companion/main/automation/application/ports/LoggerContext.ts similarity index 100% rename from core/automation/application/ports/LoggerContext.ts rename to apps/companion/main/automation/application/ports/LoggerContext.ts diff --git a/core/automation/application/ports/LoggerLogLevel.ts b/apps/companion/main/automation/application/ports/LoggerLogLevel.ts similarity index 100% rename from core/automation/application/ports/LoggerLogLevel.ts rename to apps/companion/main/automation/application/ports/LoggerLogLevel.ts diff --git a/core/automation/application/ports/LoggerPort.ts b/apps/companion/main/automation/application/ports/LoggerPort.ts similarity index 100% rename from core/automation/application/ports/LoggerPort.ts rename to apps/companion/main/automation/application/ports/LoggerPort.ts diff --git a/core/automation/application/ports/OverlaySyncPort.ts b/apps/companion/main/automation/application/ports/OverlaySyncPort.ts similarity index 100% rename from core/automation/application/ports/OverlaySyncPort.ts rename to apps/companion/main/automation/application/ports/OverlaySyncPort.ts diff --git a/core/automation/application/ports/ScreenAutomationPort.ts b/apps/companion/main/automation/application/ports/ScreenAutomationPort.ts similarity index 100% rename from core/automation/application/ports/ScreenAutomationPort.ts rename to apps/companion/main/automation/application/ports/ScreenAutomationPort.ts diff --git a/core/automation/application/ports/SessionRepositoryPort.ts b/apps/companion/main/automation/application/ports/SessionRepositoryPort.ts similarity index 83% rename from core/automation/application/ports/SessionRepositoryPort.ts rename to apps/companion/main/automation/application/ports/SessionRepositoryPort.ts index a6a42260d..d24e4331b 100644 --- a/core/automation/application/ports/SessionRepositoryPort.ts +++ b/apps/companion/main/automation/application/ports/SessionRepositoryPort.ts @@ -1,3 +1,4 @@ +import { SessionStateValue } from '@/automation/domain/value-objects/SessionState'; import { AutomationSession } from '../../domain/entities/AutomationSession'; diff --git a/core/automation/application/ports/SessionValidatorPort.ts b/apps/companion/main/automation/application/ports/SessionValidatorPort.ts similarity index 58% rename from core/automation/application/ports/SessionValidatorPort.ts rename to apps/companion/main/automation/application/ports/SessionValidatorPort.ts index 90a6cd828..bd793bf75 100644 --- a/core/automation/application/ports/SessionValidatorPort.ts +++ b/apps/companion/main/automation/application/ports/SessionValidatorPort.ts @@ -1,4 +1,4 @@ -import type { Result } from '../../../shared/result/Result'; +import type { Result } from '@gridpilot/shared/result/Result'; export interface SessionValidatorPort { validateSession(): Promise>; diff --git a/core/automation/application/ports/UserConfirmationPort.ts b/apps/companion/main/automation/application/ports/UserConfirmationPort.ts similarity index 100% rename from core/automation/application/ports/UserConfirmationPort.ts rename to apps/companion/main/automation/application/ports/UserConfirmationPort.ts diff --git a/core/automation/application/OverlaySyncService.test.ts b/apps/companion/main/automation/application/services/OverlaySyncService.test.ts similarity index 89% rename from core/automation/application/OverlaySyncService.test.ts rename to apps/companion/main/automation/application/services/OverlaySyncService.test.ts index f19d354a7..f0872b846 100644 --- a/core/automation/application/OverlaySyncService.test.ts +++ b/apps/companion/main/automation/application/services/OverlaySyncService.test.ts @@ -1,7 +1,7 @@ import { describe, expect, test } from 'vitest' -import { OverlayAction } from '@core/automation/application/ports/IOverlaySyncPort' +import { OverlayAction } from 'apps/companion/main/automation/application/ports/IOverlaySyncPort' import { IAutomationLifecycleEmitter, LifecycleCallback } from '@core/automation/infrastructure//IAutomationLifecycleEmitter' -import { OverlaySyncService } from '@core/automation/application/services/OverlaySyncService' +import { OverlaySyncService } from 'apps/companion/main/automation/application/services/OverlaySyncService' class MockLifecycleEmitter implements IAutomationLifecycleEmitter { private callbacks: Set = new Set() diff --git a/core/automation/application/services/OverlaySyncService.ts b/apps/companion/main/automation/application/services/OverlaySyncService.ts similarity index 96% rename from core/automation/application/services/OverlaySyncService.ts rename to apps/companion/main/automation/application/services/OverlaySyncService.ts index 121aabc81..5820fafbb 100644 --- a/core/automation/application/services/OverlaySyncService.ts +++ b/apps/companion/main/automation/application/services/OverlaySyncService.ts @@ -3,6 +3,8 @@ import { AutomationEventPublisherPort, AutomationEvent } from '../ports/Automati import { AutomationLifecycleEmitterPort, LifecycleCallback } from '../ports/AutomationLifecycleEmitterPort'; import { LoggerPort } from '../ports/LoggerPort'; import type { IAsyncApplicationService } from '@core/shared/application'; +import { OverlayAction, OverlaySyncPort } from '../ports/OverlaySyncPort'; +import { ActionAck } from '../ports/IOverlaySyncPort'; type ConstructorArgs = { lifecycleEmitter: AutomationLifecycleEmitterPort diff --git a/core/automation/application/CheckAuthenticationUseCase.test.ts b/apps/companion/main/automation/application/use-cases/CheckAuthenticationUseCase.test.ts similarity index 96% rename from core/automation/application/CheckAuthenticationUseCase.test.ts rename to apps/companion/main/automation/application/use-cases/CheckAuthenticationUseCase.test.ts index 36f71d3f3..e48328315 100644 --- a/core/automation/application/CheckAuthenticationUseCase.test.ts +++ b/apps/companion/main/automation/application/use-cases/CheckAuthenticationUseCase.test.ts @@ -1,9 +1,9 @@ import { describe, it, expect, beforeEach, vi, Mock } from 'vitest'; -import { CheckAuthenticationUseCase } from '@core/automation/application/use-cases/CheckAuthenticationUseCase'; -import { AuthenticationState } from '@core/automation/domain/value-objects/AuthenticationState'; -import { BrowserAuthenticationState } from '@core/automation/domain/value-objects/BrowserAuthenticationState'; +import { CheckAuthenticationUseCase } from 'apps/companion/main/automation/application/use-cases/CheckAuthenticationUseCase'; +import { AuthenticationState } from 'apps/companion/main/automation/domain/value-objects/AuthenticationState'; +import { BrowserAuthenticationState } from 'apps/companion/main/automation/domain/value-objects/BrowserAuthenticationState'; import { Result } from '@core/shared/result/Result'; -import type { AuthenticationServicePort } from '@core/automation/application/ports/AuthenticationServicePort'; +import type { AuthenticationServicePort } from 'apps/companion/main/automation/application/ports/AuthenticationServicePort'; interface ISessionValidator { validateSession(): Promise>; diff --git a/core/automation/application/use-cases/CheckAuthenticationUseCase.ts b/apps/companion/main/automation/application/use-cases/CheckAuthenticationUseCase.ts similarity index 96% rename from core/automation/application/use-cases/CheckAuthenticationUseCase.ts rename to apps/companion/main/automation/application/use-cases/CheckAuthenticationUseCase.ts index 6c414d2f8..6591023a8 100644 --- a/core/automation/application/use-cases/CheckAuthenticationUseCase.ts +++ b/apps/companion/main/automation/application/use-cases/CheckAuthenticationUseCase.ts @@ -1,6 +1,6 @@ import { AuthenticationState } from '../../domain/value-objects/AuthenticationState'; import type { Logger } from '@core/shared/application'; -import { Result } from '../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; import type { AuthenticationServicePort } from '../ports/AuthenticationServicePort'; import { SessionLifetime } from '../../domain/value-objects/SessionLifetime'; import type { SessionValidatorPort } from '../ports/SessionValidatorPort'; @@ -38,7 +38,7 @@ export class CheckAuthenticationUseCase { this.logger.debug('Performing file-based authentication check.'); const fileResult = await this.authService.checkSession(); if (fileResult.isErr()) { - this.logger.error('File-based authentication check failed.', { error: fileResult.unwrapErr() }); + this.logger.error('File-based authentication check failed.', fileResult.unwrapErr()); return fileResult; } this.logger.info('File-based authentication check succeeded.'); @@ -66,7 +66,7 @@ export class CheckAuthenticationUseCase { } this.logger.debug('Session is not expired.'); } catch (error) { - this.logger.error('Invalid expiry date encountered, treating session as expired.', { expiry, error }); + this.logger.error('Invalid expiry date encountered, treating session as expired.', error as Error, { expiry }); // Invalid expiry date, treat as expired for safety return Result.ok(AuthenticationState.EXPIRED); } @@ -112,7 +112,7 @@ export class CheckAuthenticationUseCase { this.logger.info(`CheckAuthenticationUseCase completed successfully with state: ${fileState}`); return Result.ok(fileState); } catch (error) { - this.logger.error('An unexpected error occurred during authentication check.', { error }); + this.logger.error('An unexpected error occurred during authentication check.', error as Error); throw error; } } diff --git a/apps/companion/main/automation/application/use-cases/ClearSessionUseCase.test.ts b/apps/companion/main/automation/application/use-cases/ClearSessionUseCase.test.ts new file mode 100644 index 000000000..c7f424081 --- /dev/null +++ b/apps/companion/main/automation/application/use-cases/ClearSessionUseCase.test.ts @@ -0,0 +1,106 @@ +import { vi, Mock } from 'vitest'; +import { ClearSessionUseCase } from './ClearSessionUseCase'; +import type { AuthenticationServicePort } from '../ports/AuthenticationServicePort'; +import type { Logger } from '@core/shared/application'; +import { Result } from '@gridpilot/shared/result/Result'; + +describe('ClearSessionUseCase', () => { + let useCase: ClearSessionUseCase; + let authService: AuthenticationServicePort; + let logger: Logger; + + beforeEach(() => { + const mockAuthService = { + clearSession: vi.fn(), + checkSession: vi.fn(), + initiateLogin: vi.fn(), + getState: vi.fn(), + validateServerSide: vi.fn(), + refreshSession: vi.fn(), + getSessionExpiry: vi.fn(), + verifyPageAuthentication: vi.fn(), + }; + + const mockLogger = { + debug: vi.fn(), + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + }; + + authService = mockAuthService as unknown as AuthenticationServicePort; + logger = mockLogger as Logger; + + useCase = new ClearSessionUseCase(authService, logger); + }); + + describe('execute', () => { + it('should clear session successfully and return ok result', async () => { + const successResult = Result.ok(undefined); + (authService.clearSession as Mock).mockResolvedValue(successResult); + + const result = await useCase.execute(); + + expect(authService.clearSession).toHaveBeenCalledTimes(1); + expect(logger.debug).toHaveBeenCalledWith('Attempting to clear user session.', { + useCase: 'ClearSessionUseCase' + }); + expect(logger.info).toHaveBeenCalledWith('User session cleared successfully.', { + useCase: 'ClearSessionUseCase' + }); + expect(result.isOk()).toBe(true); + }); + + it('should handle clearSession failure and return err result', async () => { + const error = new Error('Clear session failed'); + const failureResult = Result.err(error); + (authService.clearSession as Mock).mockResolvedValue(failureResult); + + const result = await useCase.execute(); + + expect(authService.clearSession).toHaveBeenCalledTimes(1); + expect(logger.debug).toHaveBeenCalledWith('Attempting to clear user session.', { + useCase: 'ClearSessionUseCase' + }); + expect(logger.warn).toHaveBeenCalledWith('Failed to clear user session.', { + useCase: 'ClearSessionUseCase', + error: error, + }); + expect(result.isErr()).toBe(true); + expect(result.error).toBe(error); + }); + + it('should handle unexpected errors and return err result with Error', async () => { + const thrownError = new Error('Unexpected error'); + (authService.clearSession as Mock).mockRejectedValue(thrownError); + + const result = await useCase.execute(); + + expect(authService.clearSession).toHaveBeenCalledTimes(1); + expect(logger.debug).toHaveBeenCalledWith('Attempting to clear user session.', { + useCase: 'ClearSessionUseCase' + }); + expect(logger.error).toHaveBeenCalledWith('Error clearing user session.', thrownError, { + useCase: 'ClearSessionUseCase' + }); + expect(result.isErr()).toBe(true); + expect(result.error).toBeInstanceOf(Error); + expect(result.error?.message).toBe('Unexpected error'); + }); + + it('should handle non-Error thrown values and convert to Error', async () => { + const thrownValue = 'String error'; + (authService.clearSession as Mock).mockRejectedValue(thrownValue); + + const result = await useCase.execute(); + + expect(authService.clearSession).toHaveBeenCalledTimes(1); + expect(logger.error).toHaveBeenCalledWith('Error clearing user session.', expect.any(Error), { + useCase: 'ClearSessionUseCase' + }); + expect(result.isErr()).toBe(true); + expect(result.error).toBeInstanceOf(Error); + expect(result.error?.message).toBe('String error'); + }); + }); +}); \ No newline at end of file diff --git a/core/automation/application/use-cases/ClearSessionUseCase.ts b/apps/companion/main/automation/application/use-cases/ClearSessionUseCase.ts similarity index 82% rename from core/automation/application/use-cases/ClearSessionUseCase.ts rename to apps/companion/main/automation/application/use-cases/ClearSessionUseCase.ts index b779b62fb..29b1ad7b6 100644 --- a/core/automation/application/use-cases/ClearSessionUseCase.ts +++ b/apps/companion/main/automation/application/use-cases/ClearSessionUseCase.ts @@ -1,4 +1,4 @@ -import { Result } from '../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; import type { AuthenticationServicePort } from '../ports/AuthenticationServicePort'; import type { Logger } from '@core/shared/application'; @@ -26,7 +26,7 @@ export class ClearSessionUseCase { try { const result = await this.authService.clearSession(); - if (result.isSuccess) { + if (result.isOk()) { this.logger.info('User session cleared successfully.', { useCase: 'ClearSessionUseCase' }); @@ -38,10 +38,11 @@ export class ClearSessionUseCase { } return result; } catch (error) { - this.logger.error('Error clearing user session.', error, { + const err = error instanceof Error ? error : new Error(String(error)); + this.logger.error('Error clearing user session.', err, { useCase: 'ClearSessionUseCase' }); - return Result.fail(error.message); + return Result.err(err); } } } diff --git a/core/automation/application/CompleteRaceCreationUseCase.test.ts b/apps/companion/main/automation/application/use-cases/CompleteRaceCreationUseCase.test.ts similarity index 88% rename from core/automation/application/CompleteRaceCreationUseCase.test.ts rename to apps/companion/main/automation/application/use-cases/CompleteRaceCreationUseCase.test.ts index 34c68ce5a..a9cb9ada4 100644 --- a/core/automation/application/CompleteRaceCreationUseCase.test.ts +++ b/apps/companion/main/automation/application/use-cases/CompleteRaceCreationUseCase.test.ts @@ -1,10 +1,10 @@ import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { CompleteRaceCreationUseCase } from '@core/automation/application/use-cases/CompleteRaceCreationUseCase'; +import { CompleteRaceCreationUseCase } from 'apps/companion/main/automation/application/use-cases/CompleteRaceCreationUseCase'; import { Result } from '@core/shared/result/Result'; -import { RaceCreationResult } from '@core/automation/domain/value-objects/RaceCreationResult'; -import { CheckoutPrice } from '@core/automation/domain/value-objects/CheckoutPrice'; -import type { CheckoutServicePort } from '@core/automation/application/ports/CheckoutServicePort'; -import { CheckoutState } from '@core/automation/domain/value-objects/CheckoutState'; +import { RaceCreationResult } from 'apps/companion/main/automation/domain/value-objects/RaceCreationResult'; +import { CheckoutPrice } from 'apps/companion/main/automation/domain/value-objects/CheckoutPrice'; +import type { CheckoutServicePort } from 'apps/companion/main/automation/application/ports/CheckoutServicePort'; +import { CheckoutState } from 'apps/companion/main/automation/domain/value-objects/CheckoutState'; describe('CompleteRaceCreationUseCase', () => { let mockCheckoutService: CheckoutServicePort; diff --git a/core/automation/application/use-cases/CompleteRaceCreationUseCase.ts b/apps/companion/main/automation/application/use-cases/CompleteRaceCreationUseCase.ts similarity index 96% rename from core/automation/application/use-cases/CompleteRaceCreationUseCase.ts rename to apps/companion/main/automation/application/use-cases/CompleteRaceCreationUseCase.ts index 44cdd14d6..c05f6f5be 100644 --- a/core/automation/application/use-cases/CompleteRaceCreationUseCase.ts +++ b/apps/companion/main/automation/application/use-cases/CompleteRaceCreationUseCase.ts @@ -1,4 +1,4 @@ -import { Result } from '../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; import { RaceCreationResult } from '../../domain/value-objects/RaceCreationResult'; import type { CheckoutServicePort } from '../ports/CheckoutServicePort'; import type { Logger } from '@core/shared/application'; diff --git a/core/automation/application/ConfirmCheckoutUseCase.test.ts b/apps/companion/main/automation/application/use-cases/ConfirmCheckoutUseCase.test.ts similarity index 91% rename from core/automation/application/ConfirmCheckoutUseCase.test.ts rename to apps/companion/main/automation/application/use-cases/ConfirmCheckoutUseCase.test.ts index 26eb5575c..81a24848b 100644 --- a/core/automation/application/ConfirmCheckoutUseCase.test.ts +++ b/apps/companion/main/automation/application/use-cases/ConfirmCheckoutUseCase.test.ts @@ -1,12 +1,12 @@ import { describe, it, expect, beforeEach, vi, Mock } from 'vitest'; import { Result } from '@core/shared/result/Result'; -import { ConfirmCheckoutUseCase } from '@core/automation/application/use-cases/ConfirmCheckoutUseCase'; -import type { CheckoutServicePort } from '@core/automation/application/ports/CheckoutServicePort'; -import type { CheckoutConfirmationPort } from '@core/automation/application/ports/CheckoutConfirmationPort'; -import type { CheckoutInfoDTO } from '@core/automation/application/dto/CheckoutInfoDTO'; -import { CheckoutPrice } from '@core/automation/domain/value-objects/CheckoutPrice'; - -import { CheckoutConfirmation } from '@core/automation/domain/value-objects/CheckoutConfirmation'; +import { ConfirmCheckoutUseCase } from 'apps/companion/main/automation/application/use-cases/ConfirmCheckoutUseCase'; +import type { CheckoutServicePort } from 'apps/companion/main/automation/application/ports/CheckoutServicePort'; +import type { CheckoutConfirmationPort } from 'apps/companion/main/automation/application/ports/CheckoutConfirmationPort'; +import { CheckoutPrice } from 'apps/companion/main/automation/domain/value-objects/CheckoutPrice'; +import { CheckoutState } from 'apps/companion/main/automation/domain/value-objects/CheckoutState'; +import { CheckoutConfirmation } from 'apps/companion/main/automation/domain/value-objects/CheckoutConfirmation'; +import type { Logger } from '@core/shared/application'; /** * ConfirmCheckoutUseCase - GREEN PHASE @@ -23,6 +23,7 @@ describe('ConfirmCheckoutUseCase', () => { let mockConfirmationPort: { requestCheckoutConfirmation: Mock; }; + let mockLogger: Logger; let mockPrice: CheckoutPrice; beforeEach(() => { @@ -30,11 +31,21 @@ describe('ConfirmCheckoutUseCase', () => { extractCheckoutInfo: vi.fn(), proceedWithCheckout: vi.fn(), }; - + mockConfirmationPort = { requestCheckoutConfirmation: vi.fn(), }; - + + mockLogger = { + debug: vi.fn(), + info: vi.fn(), + error: vi.fn(), + warn: vi.fn(), + fatal: vi.fn(), + child: vi.fn(() => mockLogger), + flush: vi.fn(), + } as Logger; + mockPrice = { getAmount: vi.fn(() => 0.50), toDisplayString: vi.fn(() => '$0.50'), @@ -46,7 +57,8 @@ describe('ConfirmCheckoutUseCase', () => { it('should extract price, get user confirmation, and proceed with checkout', async () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( @@ -75,7 +87,8 @@ describe('ConfirmCheckoutUseCase', () => { it('should include price in confirmation message', async () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( @@ -102,7 +115,8 @@ describe('ConfirmCheckoutUseCase', () => { it('should abort checkout when user cancels confirmation', async () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( @@ -126,7 +140,8 @@ describe('ConfirmCheckoutUseCase', () => { it('should not proceed with checkout after cancellation', async () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( @@ -150,7 +165,8 @@ describe('ConfirmCheckoutUseCase', () => { it('should return error when checkout state is INSUFFICIENT_FUNDS', async () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( @@ -172,7 +188,8 @@ describe('ConfirmCheckoutUseCase', () => { it('should not ask for confirmation when funds are insufficient', async () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( @@ -193,7 +210,8 @@ describe('ConfirmCheckoutUseCase', () => { it('should return error when price cannot be extracted', async () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( @@ -215,7 +233,8 @@ describe('ConfirmCheckoutUseCase', () => { it('should return error when extraction service fails', async () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( @@ -239,7 +258,8 @@ describe('ConfirmCheckoutUseCase', () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( @@ -272,7 +292,8 @@ describe('ConfirmCheckoutUseCase', () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( @@ -297,7 +318,8 @@ describe('ConfirmCheckoutUseCase', () => { it('should return error when proceedWithCheckout fails', async () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( @@ -325,7 +347,8 @@ describe('ConfirmCheckoutUseCase', () => { it('Given checkout price $0.50 and READY state, When user confirms, Then checkout proceeds', async () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( @@ -348,7 +371,8 @@ describe('ConfirmCheckoutUseCase', () => { it('Given checkout price $0.50, When user cancels, Then checkout is aborted', async () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( @@ -371,7 +395,8 @@ describe('ConfirmCheckoutUseCase', () => { it('Given INSUFFICIENT_FUNDS state, When executing, Then error is returned', async () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( @@ -390,7 +415,8 @@ describe('ConfirmCheckoutUseCase', () => { it('Given price extraction failure, When executing, Then error is returned', async () => { const useCase = new ConfirmCheckoutUseCase( mockCheckoutService as unknown as CheckoutServicePort, - mockConfirmationPort as unknown as CheckoutConfirmationPort + mockConfirmationPort as unknown as CheckoutConfirmationPort, + mockLogger ); mockCheckoutService.extractCheckoutInfo.mockResolvedValue( diff --git a/core/automation/application/use-cases/ConfirmCheckoutUseCase.ts b/apps/companion/main/automation/application/use-cases/ConfirmCheckoutUseCase.ts similarity index 87% rename from core/automation/application/use-cases/ConfirmCheckoutUseCase.ts rename to apps/companion/main/automation/application/use-cases/ConfirmCheckoutUseCase.ts index 033f7c866..362f8d820 100644 --- a/core/automation/application/use-cases/ConfirmCheckoutUseCase.ts +++ b/apps/companion/main/automation/application/use-cases/ConfirmCheckoutUseCase.ts @@ -1,7 +1,8 @@ -import { Result } from '../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; import type { Logger } from '@core/shared/application'; import type { CheckoutServicePort } from '../ports/CheckoutServicePort'; import type { CheckoutConfirmationPort } from '../ports/CheckoutConfirmationPort'; +import { CheckoutStateEnum } from '../../domain/value-objects/CheckoutState'; interface SessionMetadata { @@ -25,7 +26,7 @@ export class ConfirmCheckoutUseCase { const infoResult = await this.checkoutService.extractCheckoutInfo(); if (infoResult.isErr()) { - this.logger.error('Failed to extract checkout info', { error: infoResult.unwrapErr() }); + this.logger.error('Failed to extract checkout info', infoResult.unwrapErr()); return Result.err(infoResult.unwrapErr()); } @@ -58,7 +59,7 @@ export class ConfirmCheckoutUseCase { }); if (confirmationResult.isErr()) { - this.logger.error('Checkout confirmation failed', { error: confirmationResult.unwrapErr() }); + this.logger.error('Checkout confirmation failed', confirmationResult.unwrapErr()); return Result.err(confirmationResult.unwrapErr()); } @@ -81,7 +82,7 @@ export class ConfirmCheckoutUseCase { if (checkoutResult.isOk()) { this.logger.info('Checkout process completed successfully.'); } else { - this.logger.error('Checkout process failed', { error: checkoutResult.unwrapErr() }); + this.logger.error('Checkout process failed', checkoutResult.unwrapErr()); } return checkoutResult; } diff --git a/core/automation/application/use-cases/InitiateLoginUseCase.ts b/apps/companion/main/automation/application/use-cases/InitiateLoginUseCase.ts similarity index 83% rename from core/automation/application/use-cases/InitiateLoginUseCase.ts rename to apps/companion/main/automation/application/use-cases/InitiateLoginUseCase.ts index e2fab0a85..8ca94ec35 100644 --- a/core/automation/application/use-cases/InitiateLoginUseCase.ts +++ b/apps/companion/main/automation/application/use-cases/InitiateLoginUseCase.ts @@ -1,4 +1,4 @@ -import { Result } from '../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; import type { AuthenticationServicePort } from '../ports/AuthenticationServicePort'; import type { Logger } from '@core/shared/application/Logger'; @@ -32,8 +32,9 @@ export class InitiateLoginUseCase { } return result; } catch (error) { - this.logger.error('Error initiating login flow.', error); - return Result.fail(error.message || 'Unknown error during login initiation.'); + const err = error instanceof Error ? error : new Error(String(error)); + this.logger.error('Error initiating login flow.', err); + return Result.err(err); } } } \ No newline at end of file diff --git a/core/automation/application/StartAutomationSession.test.ts b/apps/companion/main/automation/application/use-cases/StartAutomationSession.test.ts similarity index 89% rename from core/automation/application/StartAutomationSession.test.ts rename to apps/companion/main/automation/application/use-cases/StartAutomationSession.test.ts index b57a95c8d..828551a58 100644 --- a/core/automation/application/StartAutomationSession.test.ts +++ b/apps/companion/main/automation/application/use-cases/StartAutomationSession.test.ts @@ -1,9 +1,10 @@ import { describe, it, expect, vi, beforeEach, Mock } from 'vitest'; -import { StartAutomationSessionUseCase } from '@core/automation/application/use-cases/StartAutomationSessionUseCase'; -import { AutomationEnginePort as IAutomationEngine } from '@core/automation/application/ports/AutomationEnginePort'; -import { IBrowserAutomation as IScreenAutomation } from '@core/automation/application/ports/ScreenAutomationPort'; -import { SessionRepositoryPort as ISessionRepository } from '@core/automation/application/ports/SessionRepositoryPort'; -import { AutomationSession } from '@core/automation/domain/entities/AutomationSession'; +import { StartAutomationSessionUseCase } from 'apps/companion/main/automation/application/use-cases/StartAutomationSessionUseCase'; +import { AutomationEnginePort as IAutomationEngine } from 'apps/companion/main/automation/application/ports/AutomationEnginePort'; +import { IBrowserAutomation as IScreenAutomation } from 'apps/companion/main/automation/application/ports/ScreenAutomationPort'; +import { SessionRepositoryPort as ISessionRepository } from 'apps/companion/main/automation/application/ports/SessionRepositoryPort'; +import type { Logger } from '@core/shared/application'; +import { AutomationSession } from 'apps/companion/main/automation/domain/entities/AutomationSession'; describe('StartAutomationSessionUseCase', () => { let mockAutomationEngine: { @@ -23,6 +24,12 @@ describe('StartAutomationSessionUseCase', () => { update: Mock; delete: Mock; }; + let mockLogger: { + debug: Mock; + info: Mock; + warn: Mock; + error: Mock; + }; let useCase: StartAutomationSessionUseCase; beforeEach(() => { @@ -46,10 +53,18 @@ describe('StartAutomationSessionUseCase', () => { delete: vi.fn(), }; + mockLogger = { + debug: vi.fn(), + info: vi.fn(), + warn: vi.fn(), + error: vi.fn(), + }; + useCase = new StartAutomationSessionUseCase( mockAutomationEngine as unknown as IAutomationEngine, mockBrowserAutomation as unknown as IScreenAutomation, - mockSessionRepository as unknown as ISessionRepository + mockSessionRepository as unknown as ISessionRepository, + mockLogger as unknown as Logger ); }); diff --git a/core/automation/application/use-cases/StartAutomationSessionUseCase.ts b/apps/companion/main/automation/application/use-cases/StartAutomationSessionUseCase.ts similarity index 94% rename from core/automation/application/use-cases/StartAutomationSessionUseCase.ts rename to apps/companion/main/automation/application/use-cases/StartAutomationSessionUseCase.ts index 1a06bb25f..03dc38119 100644 --- a/core/automation/application/use-cases/StartAutomationSessionUseCase.ts +++ b/apps/companion/main/automation/application/use-cases/StartAutomationSessionUseCase.ts @@ -25,7 +25,6 @@ export class StartAutomationSessionUseCase const validationResult = await this.automationEngine.validateConfiguration(config); if (!validationResult.isValid) { this.logger.warn('Automation session configuration validation failed', { config, error: validationResult.error }); - this.logger.error('Automation session configuration validation failed', { config, error: validationResult.error }); throw new Error(validationResult.error); } this.logger.debug('Automation session configuration validated successfully.'); diff --git a/core/automation/application/VerifyAuthenticatedPageUseCase.test.ts b/apps/companion/main/automation/application/use-cases/VerifyAuthenticatedPageUseCase.test.ts similarity index 88% rename from core/automation/application/VerifyAuthenticatedPageUseCase.test.ts rename to apps/companion/main/automation/application/use-cases/VerifyAuthenticatedPageUseCase.test.ts index edfe3af29..24349fd3d 100644 --- a/core/automation/application/VerifyAuthenticatedPageUseCase.test.ts +++ b/apps/companion/main/automation/application/use-cases/VerifyAuthenticatedPageUseCase.test.ts @@ -1,9 +1,9 @@ import { describe, it, expect, beforeEach, vi } from 'vitest'; -import { VerifyAuthenticatedPageUseCase } from '@core/automation/application/use-cases/VerifyAuthenticatedPageUseCase'; -import { AuthenticationServicePort as IAuthenticationService } from '@core/automation/application/ports/AuthenticationServicePort'; +import { VerifyAuthenticatedPageUseCase } from 'apps/companion/main/automation/application/use-cases/VerifyAuthenticatedPageUseCase'; +import { AuthenticationServicePort as IAuthenticationService } from 'apps/companion/main/automation/application/ports/AuthenticationServicePort'; import { Result } from '@core/shared/result/Result'; -import { BrowserAuthenticationState } from '@core/automation/domain/value-objects/BrowserAuthenticationState'; -import { AuthenticationState } from '@core/automation/domain/value-objects/AuthenticationState'; +import { BrowserAuthenticationState } from 'apps/companion/main/automation/domain/value-objects/BrowserAuthenticationState'; +import { AuthenticationState } from 'apps/companion/main/automation/domain/value-objects/AuthenticationState'; describe('VerifyAuthenticatedPageUseCase', () => { let useCase: VerifyAuthenticatedPageUseCase; diff --git a/core/automation/application/use-cases/VerifyAuthenticatedPageUseCase.ts b/apps/companion/main/automation/application/use-cases/VerifyAuthenticatedPageUseCase.ts similarity index 92% rename from core/automation/application/use-cases/VerifyAuthenticatedPageUseCase.ts rename to apps/companion/main/automation/application/use-cases/VerifyAuthenticatedPageUseCase.ts index 5d5ce135f..17e0aa353 100644 --- a/core/automation/application/use-cases/VerifyAuthenticatedPageUseCase.ts +++ b/apps/companion/main/automation/application/use-cases/VerifyAuthenticatedPageUseCase.ts @@ -1,5 +1,5 @@ import type { AuthenticationServicePort } from '../ports/AuthenticationServicePort'; -import { Result } from '../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; import { BrowserAuthenticationState } from '../../domain/value-objects/BrowserAuthenticationState'; import type { Logger } from '@core/shared/application'; @@ -29,7 +29,7 @@ export class VerifyAuthenticatedPageUseCase { return Result.ok(browserState); } catch (error) { const message = error instanceof Error ? error.message : String(error); - this.logger.error(`Page verification failed unexpectedly: ${message}`, error); + this.logger.error(`Page verification failed unexpectedly: ${message}`, error instanceof Error ? error : undefined); return Result.err(new Error(`Page verification failed: ${message}`)); } } diff --git a/core/automation/domain/entities/AutomationSession.test.ts b/apps/companion/main/automation/domain/entities/AutomationSession.test.ts similarity index 98% rename from core/automation/domain/entities/AutomationSession.test.ts rename to apps/companion/main/automation/domain/entities/AutomationSession.test.ts index 85bcdb606..5e51fa2f8 100644 --- a/core/automation/domain/entities/AutomationSession.test.ts +++ b/apps/companion/main/automation/domain/entities/AutomationSession.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; -import { AutomationSession } from '@core/automation/domain/entities/AutomationSession'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import { AutomationSession } from 'apps/companion/main/automation/domain/entities/AutomationSession'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; describe('AutomationSession Entity', () => { describe('create', () => { diff --git a/core/automation/domain/entities/AutomationSession.ts b/apps/companion/main/automation/domain/entities/AutomationSession.ts similarity index 98% rename from core/automation/domain/entities/AutomationSession.ts rename to apps/companion/main/automation/domain/entities/AutomationSession.ts index 903aed325..02470945f 100644 --- a/core/automation/domain/entities/AutomationSession.ts +++ b/apps/companion/main/automation/domain/entities/AutomationSession.ts @@ -4,6 +4,7 @@ import { StepId } from '../value-objects/StepId'; import type { HostedSessionConfig } from '../types/HostedSessionConfig'; import { AutomationDomainError } from '../errors/AutomationDomainError'; +import { SessionState } from '../value-objects/SessionState'; export class AutomationSession implements IEntity { private readonly _id: string; diff --git a/core/automation/domain/entities/StepExecution.ts b/apps/companion/main/automation/domain/entities/StepExecution.ts similarity index 100% rename from core/automation/domain/entities/StepExecution.ts rename to apps/companion/main/automation/domain/entities/StepExecution.ts diff --git a/core/automation/domain/errors/AutomationDomainError.ts b/apps/companion/main/automation/domain/errors/AutomationDomainError.ts similarity index 100% rename from core/automation/domain/errors/AutomationDomainError.ts rename to apps/companion/main/automation/domain/errors/AutomationDomainError.ts diff --git a/core/automation/domain/services/PageStateValidator.test.ts b/apps/companion/main/automation/domain/services/PageStateValidator.test.ts similarity index 92% rename from core/automation/domain/services/PageStateValidator.test.ts rename to apps/companion/main/automation/domain/services/PageStateValidator.test.ts index 5dc695898..712480505 100644 --- a/core/automation/domain/services/PageStateValidator.test.ts +++ b/apps/companion/main/automation/domain/services/PageStateValidator.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { PageStateValidator } from '@core/automation/domain/services/PageStateValidator'; +import { PageStateValidator } from 'apps/companion/main/automation/domain/services/PageStateValidator'; describe('PageStateValidator', () => { const validator = new PageStateValidator(); @@ -7,7 +7,7 @@ describe('PageStateValidator', () => { describe('validateState', () => { it('should return valid when all required selectors are present', () => { // Arrange - const actualState = (_selector: string) => { + const actualState = (selector: string) => { return ['#add-car-button', '#cars-list'].includes(selector); }; @@ -27,7 +27,7 @@ describe('PageStateValidator', () => { it('should return invalid when required selectors are missing', () => { // Arrange - const actualState = (_selector: string) => { + const actualState = (selector: string) => { return selector === '#add-car-button'; // Only one of two selectors present }; @@ -48,7 +48,7 @@ describe('PageStateValidator', () => { it('should return invalid when forbidden selectors are present', () => { // Arrange - const actualState = (_selector: string) => { + const actualState = (selector: string) => { return ['#add-car-button', '#set-track'].includes(selector); }; @@ -70,7 +70,7 @@ describe('PageStateValidator', () => { it('should handle empty forbidden selectors array', () => { // Arrange - const actualState = (_selector: string) => { + const actualState = (selector: string) => { return selector === '#add-car-button'; }; @@ -89,7 +89,7 @@ describe('PageStateValidator', () => { it('should handle undefined forbidden selectors', () => { // Arrange - const actualState = (_selector: string) => { + const actualState = (selector: string) => { return selector === '#add-car-button'; }; @@ -108,7 +108,7 @@ describe('PageStateValidator', () => { it('should return error result when actualState function throws', () => { // Arrange - const actualState = (_selector: string) => { + const actualState = () => { throw new Error('Selector evaluation failed'); }; @@ -144,7 +144,7 @@ describe('PageStateValidator', () => { it('should validate complex state with both required and forbidden selectors', () => { // Arrange - Simulate being on Cars page but Track page elements leaked through - const actualState = (_selector: string) => { + const actualState = (selector: string) => { const presentSelectors = ['#add-car-button', '#cars-list', '#set-track']; return presentSelectors.includes(selector); }; diff --git a/core/automation/domain/services/PageStateValidator.ts b/apps/companion/main/automation/domain/services/PageStateValidator.ts similarity index 98% rename from core/automation/domain/services/PageStateValidator.ts rename to apps/companion/main/automation/domain/services/PageStateValidator.ts index 58ae1f491..a4f6c0417 100644 --- a/core/automation/domain/services/PageStateValidator.ts +++ b/apps/companion/main/automation/domain/services/PageStateValidator.ts @@ -1,5 +1,5 @@ import type { IDomainValidationService } from '@core/shared/domain'; -import { Result } from '../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; /** * Configuration for page state validation. @@ -183,7 +183,7 @@ export class PageStateValidator } // Check required selectors are present (with fallbacks for real mode) - const missingSelectors = requiredSelectors.filter(_selector => { + const missingSelectors = requiredSelectors.filter(selector => { if (realMode) { const relatedSelectors = selectorsToCheck.filter(s => s.includes(expectedStep) || diff --git a/core/automation/domain/services/StepTransitionValidator.ts b/apps/companion/main/automation/domain/services/StepTransitionValidator.ts similarity index 93% rename from core/automation/domain/services/StepTransitionValidator.ts rename to apps/companion/main/automation/domain/services/StepTransitionValidator.ts index 3a6738ccb..ea46240c7 100644 --- a/core/automation/domain/services/StepTransitionValidator.ts +++ b/apps/companion/main/automation/domain/services/StepTransitionValidator.ts @@ -1,7 +1,8 @@ import { StepId } from '../value-objects/StepId'; import type { IDomainValidationService } from '@core/shared/domain'; -import { Result } from '../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; +import { SessionState } from '../value-objects/SessionState'; export interface ValidationResult { isValid: boolean; @@ -90,13 +91,11 @@ export class StepTransitionValidator } static validateModalStepTransition( - currentStep: StepId, - nextStep: StepId ): ValidationResult { return { isValid: true }; } - static shouldStopAtStep18(_nextStep: StepId): boolean { + static shouldStopAtStep18(nextStep: StepId): boolean { return nextStep.isFinalStep(); } diff --git a/core/automation/domain/types/HostedSessionConfig.ts b/apps/companion/main/automation/domain/types/HostedSessionConfig.ts similarity index 100% rename from core/automation/domain/types/HostedSessionConfig.ts rename to apps/companion/main/automation/domain/types/HostedSessionConfig.ts diff --git a/core/automation/domain/types/ScreenRegion.ts b/apps/companion/main/automation/domain/types/ScreenRegion.ts similarity index 100% rename from core/automation/domain/types/ScreenRegion.ts rename to apps/companion/main/automation/domain/types/ScreenRegion.ts diff --git a/core/automation/domain/value-objects/AuthenticationState.ts b/apps/companion/main/automation/domain/value-objects/AuthenticationState.ts similarity index 100% rename from core/automation/domain/value-objects/AuthenticationState.ts rename to apps/companion/main/automation/domain/value-objects/AuthenticationState.ts diff --git a/core/automation/domain/value-objects/BrowserAuthenticationState.test.ts b/apps/companion/main/automation/domain/value-objects/BrowserAuthenticationState.test.ts similarity index 94% rename from core/automation/domain/value-objects/BrowserAuthenticationState.test.ts rename to apps/companion/main/automation/domain/value-objects/BrowserAuthenticationState.test.ts index 2f42a106e..c172d640e 100644 --- a/core/automation/domain/value-objects/BrowserAuthenticationState.test.ts +++ b/apps/companion/main/automation/domain/value-objects/BrowserAuthenticationState.test.ts @@ -1,6 +1,6 @@ import { describe, test, expect } from 'vitest'; -import { BrowserAuthenticationState } from '@core/automation/domain/value-objects/BrowserAuthenticationState'; -import { AuthenticationState } from '@core/automation/domain/value-objects/AuthenticationState'; +import { BrowserAuthenticationState } from 'apps/companion/main/automation/domain/value-objects/BrowserAuthenticationState'; +import { AuthenticationState } from 'apps/companion/main/automation/domain/value-objects/AuthenticationState'; describe('BrowserAuthenticationState', () => { describe('isFullyAuthenticated()', () => { diff --git a/core/automation/domain/value-objects/BrowserAuthenticationState.ts b/apps/companion/main/automation/domain/value-objects/BrowserAuthenticationState.ts similarity index 100% rename from core/automation/domain/value-objects/BrowserAuthenticationState.ts rename to apps/companion/main/automation/domain/value-objects/BrowserAuthenticationState.ts diff --git a/core/automation/domain/value-objects/CheckoutConfirmation.test.ts b/apps/companion/main/automation/domain/value-objects/CheckoutConfirmation.test.ts similarity index 93% rename from core/automation/domain/value-objects/CheckoutConfirmation.test.ts rename to apps/companion/main/automation/domain/value-objects/CheckoutConfirmation.test.ts index e5cd20ab8..534dfcbc4 100644 --- a/core/automation/domain/value-objects/CheckoutConfirmation.test.ts +++ b/apps/companion/main/automation/domain/value-objects/CheckoutConfirmation.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { CheckoutConfirmation } from '@core/automation/domain/value-objects/CheckoutConfirmation'; +import { CheckoutConfirmation } from 'apps/companion/main/automation/domain/value-objects/CheckoutConfirmation'; describe('CheckoutConfirmation Value Object', () => { describe('create', () => { @@ -19,7 +19,8 @@ describe('CheckoutConfirmation Value Object', () => { }); it('should throw error for invalid decision', () => { - expect(() => CheckoutConfirmation.create('invalid' as unknown)).toThrow( + // @ts-expect-error Testing invalid input + expect(() => CheckoutConfirmation.create('invalid')).toThrow( 'Invalid checkout confirmation decision', ); }); diff --git a/core/automation/domain/value-objects/CheckoutConfirmation.ts b/apps/companion/main/automation/domain/value-objects/CheckoutConfirmation.ts similarity index 95% rename from core/automation/domain/value-objects/CheckoutConfirmation.ts rename to apps/companion/main/automation/domain/value-objects/CheckoutConfirmation.ts index 57d6f1e71..7d1c1616d 100644 --- a/core/automation/domain/value-objects/CheckoutConfirmation.ts +++ b/apps/companion/main/automation/domain/value-objects/CheckoutConfirmation.ts @@ -24,7 +24,7 @@ export class CheckoutConfirmation { return CheckoutConfirmation.create('confirmed'); } - static cancelled(__reason?: string): CheckoutConfirmation { + static cancelled(): CheckoutConfirmation { return CheckoutConfirmation.create('cancelled'); } diff --git a/core/automation/domain/value-objects/CheckoutPrice.test.ts b/apps/companion/main/automation/domain/value-objects/CheckoutPrice.test.ts similarity index 98% rename from core/automation/domain/value-objects/CheckoutPrice.test.ts rename to apps/companion/main/automation/domain/value-objects/CheckoutPrice.test.ts index 561c8a730..f0be5c590 100644 --- a/core/automation/domain/value-objects/CheckoutPrice.test.ts +++ b/apps/companion/main/automation/domain/value-objects/CheckoutPrice.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { CheckoutPrice } from '@core/automation/domain/value-objects/CheckoutPrice'; +import { CheckoutPrice } from 'apps/companion/main/automation/domain/value-objects/CheckoutPrice'; /** * CheckoutPrice Value Object - GREEN PHASE diff --git a/core/automation/domain/value-objects/CheckoutPrice.ts b/apps/companion/main/automation/domain/value-objects/CheckoutPrice.ts similarity index 100% rename from core/automation/domain/value-objects/CheckoutPrice.ts rename to apps/companion/main/automation/domain/value-objects/CheckoutPrice.ts diff --git a/core/automation/domain/value-objects/CheckoutState.test.ts b/apps/companion/main/automation/domain/value-objects/CheckoutState.test.ts similarity index 98% rename from core/automation/domain/value-objects/CheckoutState.test.ts rename to apps/companion/main/automation/domain/value-objects/CheckoutState.test.ts index 68573a303..c6052139f 100644 --- a/core/automation/domain/value-objects/CheckoutState.test.ts +++ b/apps/companion/main/automation/domain/value-objects/CheckoutState.test.ts @@ -1,4 +1,5 @@ import { describe, it, expect } from 'vitest'; +import { CheckoutState, CheckoutStateEnum } from './CheckoutState'; /** diff --git a/core/automation/domain/value-objects/CheckoutState.ts b/apps/companion/main/automation/domain/value-objects/CheckoutState.ts similarity index 100% rename from core/automation/domain/value-objects/CheckoutState.ts rename to apps/companion/main/automation/domain/value-objects/CheckoutState.ts diff --git a/core/automation/domain/value-objects/CookieConfiguration.test.ts b/apps/companion/main/automation/domain/value-objects/CookieConfiguration.test.ts similarity index 98% rename from core/automation/domain/value-objects/CookieConfiguration.test.ts rename to apps/companion/main/automation/domain/value-objects/CookieConfiguration.test.ts index cf06ba81c..8adc9268f 100644 --- a/core/automation/domain/value-objects/CookieConfiguration.test.ts +++ b/apps/companion/main/automation/domain/value-objects/CookieConfiguration.test.ts @@ -1,5 +1,5 @@ import { describe, test, expect } from 'vitest'; -import { CookieConfiguration } from '@core/automation/domain/value-objects/CookieConfiguration'; +import { CookieConfiguration } from 'apps/companion/main/automation/domain/value-objects/CookieConfiguration'; describe('CookieConfiguration', () => { const validTargetUrl = 'https://members-ng.iracing.com/jjwtauth/success'; diff --git a/core/automation/domain/value-objects/CookieConfiguration.ts b/apps/companion/main/automation/domain/value-objects/CookieConfiguration.ts similarity index 99% rename from core/automation/domain/value-objects/CookieConfiguration.ts rename to apps/companion/main/automation/domain/value-objects/CookieConfiguration.ts index a93e4caaf..d3e4c407d 100644 --- a/core/automation/domain/value-objects/CookieConfiguration.ts +++ b/apps/companion/main/automation/domain/value-objects/CookieConfiguration.ts @@ -16,7 +16,7 @@ export class CookieConfiguration { this.cookie = cookie; try { this.targetUrl = new URL(targetUrl); - } catch (error) { + } catch { throw new Error(`Invalid target URL: ${targetUrl}`); } diff --git a/core/automation/domain/value-objects/RaceCreationResult.test.ts b/apps/companion/main/automation/domain/value-objects/RaceCreationResult.test.ts similarity index 96% rename from core/automation/domain/value-objects/RaceCreationResult.test.ts rename to apps/companion/main/automation/domain/value-objects/RaceCreationResult.test.ts index 24fc040f4..df81dbece 100644 --- a/core/automation/domain/value-objects/RaceCreationResult.test.ts +++ b/apps/companion/main/automation/domain/value-objects/RaceCreationResult.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { RaceCreationResult } from '@core/automation/domain/value-objects/RaceCreationResult'; +import { RaceCreationResult } from 'apps/companion/main/automation/domain/value-objects/RaceCreationResult'; describe('RaceCreationResult Value Object', () => { describe('create', () => { diff --git a/core/automation/domain/value-objects/RaceCreationResult.ts b/apps/companion/main/automation/domain/value-objects/RaceCreationResult.ts similarity index 100% rename from core/automation/domain/value-objects/RaceCreationResult.ts rename to apps/companion/main/automation/domain/value-objects/RaceCreationResult.ts diff --git a/core/automation/domain/value-objects/ScreenRegion.ts b/apps/companion/main/automation/domain/value-objects/ScreenRegion.ts similarity index 100% rename from core/automation/domain/value-objects/ScreenRegion.ts rename to apps/companion/main/automation/domain/value-objects/ScreenRegion.ts diff --git a/core/automation/domain/value-objects/SessionLifetime.test.ts b/apps/companion/main/automation/domain/value-objects/SessionLifetime.test.ts similarity index 97% rename from core/automation/domain/value-objects/SessionLifetime.test.ts rename to apps/companion/main/automation/domain/value-objects/SessionLifetime.test.ts index 70d19b434..fe05ad95d 100644 --- a/core/automation/domain/value-objects/SessionLifetime.test.ts +++ b/apps/companion/main/automation/domain/value-objects/SessionLifetime.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { SessionLifetime } from '@core/automation/domain/value-objects/SessionLifetime'; +import { SessionLifetime } from 'apps/companion/main/automation/domain/value-objects/SessionLifetime'; describe('SessionLifetime Value Object', () => { describe('Construction', () => { diff --git a/core/automation/domain/value-objects/SessionLifetime.ts b/apps/companion/main/automation/domain/value-objects/SessionLifetime.ts similarity index 100% rename from core/automation/domain/value-objects/SessionLifetime.ts rename to apps/companion/main/automation/domain/value-objects/SessionLifetime.ts diff --git a/core/automation/domain/value-objects/SessionState.test.ts b/apps/companion/main/automation/domain/value-objects/SessionState.test.ts similarity index 96% rename from core/automation/domain/value-objects/SessionState.test.ts rename to apps/companion/main/automation/domain/value-objects/SessionState.test.ts index d5f3f9606..97e59b523 100644 --- a/core/automation/domain/value-objects/SessionState.test.ts +++ b/apps/companion/main/automation/domain/value-objects/SessionState.test.ts @@ -1,4 +1,6 @@ import { describe, it, expect } from 'vitest'; +import { SessionState } from './SessionState'; +import type { SessionStateValue } from './SessionState'; describe('SessionState Value Object', () => { @@ -44,11 +46,11 @@ describe('SessionState Value Object', () => { }); it('should throw error for invalid state', () => { - expect(() => SessionState.create('INVALID' as unknown)).toThrow('Invalid session state'); + expect(() => SessionState.create('INVALID' as SessionStateValue)).toThrow('Invalid session state'); }); it('should throw error for empty string', () => { - expect(() => SessionState.create('' as unknown)).toThrow('Invalid session state'); + expect(() => SessionState.create('' as SessionStateValue)).toThrow('Invalid session state'); }); }); diff --git a/core/automation/domain/value-objects/SessionState.ts b/apps/companion/main/automation/domain/value-objects/SessionState.ts similarity index 100% rename from core/automation/domain/value-objects/SessionState.ts rename to apps/companion/main/automation/domain/value-objects/SessionState.ts diff --git a/core/automation/domain/value-objects/StepId.test.ts b/apps/companion/main/automation/domain/value-objects/StepId.test.ts similarity index 97% rename from core/automation/domain/value-objects/StepId.test.ts rename to apps/companion/main/automation/domain/value-objects/StepId.test.ts index 737b9cce9..af1ab003e 100644 --- a/core/automation/domain/value-objects/StepId.test.ts +++ b/apps/companion/main/automation/domain/value-objects/StepId.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect } from 'vitest'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; describe('StepId Value Object', () => { describe('create', () => { diff --git a/core/automation/domain/value-objects/StepId.ts b/apps/companion/main/automation/domain/value-objects/StepId.ts similarity index 100% rename from core/automation/domain/value-objects/StepId.ts rename to apps/companion/main/automation/domain/value-objects/StepId.ts diff --git a/core/automation/index.ts b/apps/companion/main/automation/index.ts similarity index 100% rename from core/automation/index.ts rename to apps/companion/main/automation/index.ts diff --git a/core/automation/infrastructure/AutomationConfig.test.ts b/apps/companion/main/automation/infrastructure/AutomationConfig.test.ts similarity index 100% rename from core/automation/infrastructure/AutomationConfig.test.ts rename to apps/companion/main/automation/infrastructure/AutomationConfig.test.ts diff --git a/core/automation/infrastructure/BrowserModeConfig.test.ts b/apps/companion/main/automation/infrastructure/BrowserModeConfig.test.ts similarity index 100% rename from core/automation/infrastructure/BrowserModeConfig.test.ts rename to apps/companion/main/automation/infrastructure/BrowserModeConfig.test.ts diff --git a/core/automation/infrastructure/DemoImageServiceAdapter.test.ts b/apps/companion/main/automation/infrastructure/DemoImageServiceAdapter.test.ts similarity index 100% rename from core/automation/infrastructure/DemoImageServiceAdapter.test.ts rename to apps/companion/main/automation/infrastructure/DemoImageServiceAdapter.test.ts diff --git a/core/automation/infrastructure/ElectronCheckoutConfirmationAdapter.test.ts b/apps/companion/main/automation/infrastructure/ElectronCheckoutConfirmationAdapter.test.ts similarity index 97% rename from core/automation/infrastructure/ElectronCheckoutConfirmationAdapter.test.ts rename to apps/companion/main/automation/infrastructure/ElectronCheckoutConfirmationAdapter.test.ts index f09d4778c..03bdfc304 100644 --- a/core/automation/infrastructure/ElectronCheckoutConfirmationAdapter.test.ts +++ b/apps/companion/main/automation/infrastructure/ElectronCheckoutConfirmationAdapter.test.ts @@ -10,8 +10,8 @@ vi.mock('electron', () => ({ })); import { ElectronCheckoutConfirmationAdapter } from '@core/automation/infrastructure//ipc/ElectronCheckoutConfirmationAdapter'; -import { CheckoutPrice } from '@core/automation/domain/value-objects/CheckoutPrice'; -import { CheckoutState } from '@core/automation/domain/value-objects/CheckoutState'; +import { CheckoutPrice } from 'apps/companion/main/automation/domain/value-objects/CheckoutPrice'; +import { CheckoutState } from 'apps/companion/main/automation/domain/value-objects/CheckoutState'; import { ipcMain } from 'electron'; describe('ElectronCheckoutConfirmationAdapter', () => { diff --git a/core/automation/infrastructure/WizardDismissalDetection.test.ts b/apps/companion/main/automation/infrastructure/WizardDismissalDetection.test.ts similarity index 100% rename from core/automation/infrastructure/WizardDismissalDetection.test.ts rename to apps/companion/main/automation/infrastructure/WizardDismissalDetection.test.ts diff --git a/core/automation/infrastructure/adapters/IAutomationLifecycleEmitter.ts b/apps/companion/main/automation/infrastructure/adapters/IAutomationLifecycleEmitter.ts similarity index 66% rename from core/automation/infrastructure/adapters/IAutomationLifecycleEmitter.ts rename to apps/companion/main/automation/infrastructure/adapters/IAutomationLifecycleEmitter.ts index c7a170481..432815f53 100644 --- a/core/automation/infrastructure/adapters/IAutomationLifecycleEmitter.ts +++ b/apps/companion/main/automation/infrastructure/adapters/IAutomationLifecycleEmitter.ts @@ -1,4 +1,4 @@ -import { AutomationEvent } from '@core/automation/application/ports/AutomationEventPublisherPort'; +import { AutomationEvent } from 'apps/companion/main/automation/application/ports/AutomationEventPublisherPort'; export type LifecycleCallback = (event: AutomationEvent) => Promise | void; diff --git a/core/automation/infrastructure/adapters/automation/CheckoutPriceExtractor.ts b/apps/companion/main/automation/infrastructure/adapters/automation/CheckoutPriceExtractor.ts similarity index 98% rename from core/automation/infrastructure/adapters/automation/CheckoutPriceExtractor.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/CheckoutPriceExtractor.ts index d65e7c8b5..af0c141ba 100644 --- a/core/automation/infrastructure/adapters/automation/CheckoutPriceExtractor.ts +++ b/apps/companion/main/automation/infrastructure/adapters/automation/CheckoutPriceExtractor.ts @@ -1,4 +1,4 @@ -import { Result } from '../../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; import { CheckoutPrice } from '../../../domain/value-objects/CheckoutPrice'; import { CheckoutState } from '../../../domain/value-objects/CheckoutState'; import type { CheckoutInfoDTO } from '../../../application/dto/CheckoutInfoDTO'; diff --git a/core/automation/infrastructure/adapters/automation/auth/AuthenticationGuard.test.ts b/apps/companion/main/automation/infrastructure/adapters/automation/auth/AuthenticationGuard.test.ts similarity index 99% rename from core/automation/infrastructure/adapters/automation/auth/AuthenticationGuard.test.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/auth/AuthenticationGuard.test.ts index 690962dea..02dd4b650 100644 --- a/core/automation/infrastructure/adapters/automation/auth/AuthenticationGuard.test.ts +++ b/apps/companion/main/automation/infrastructure/adapters/automation/auth/AuthenticationGuard.test.ts @@ -1,6 +1,6 @@ import { describe, test, expect, beforeEach, vi } from 'vitest'; import type { Page } from 'playwright'; -import { AuthenticationGuard } from '@core/automation/infrastructure//automation/auth/AuthenticationGuard'; +import { AuthenticationGuard } from './AuthenticationGuard'; describe('AuthenticationGuard', () => { let mockPage: Page; diff --git a/core/automation/infrastructure/adapters/automation/auth/AuthenticationGuard.ts b/apps/companion/main/automation/infrastructure/adapters/automation/auth/AuthenticationGuard.ts similarity index 92% rename from core/automation/infrastructure/adapters/automation/auth/AuthenticationGuard.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/auth/AuthenticationGuard.ts index d11b3db68..c457b60d3 100644 --- a/core/automation/infrastructure/adapters/automation/auth/AuthenticationGuard.ts +++ b/apps/companion/main/automation/infrastructure/adapters/automation/auth/AuthenticationGuard.ts @@ -1,5 +1,5 @@ import { Page } from 'playwright'; -import { LoggerPort } from '@core/automation/application/ports/LoggerPort'; +import { LoggerPort } from 'apps/companion/main/automation/application/ports/LoggerPort'; export class AuthenticationGuard { constructor( diff --git a/core/automation/infrastructure/adapters/automation/auth/IRacingPlaywrightAuthFlow.ts b/apps/companion/main/automation/infrastructure/adapters/automation/auth/IRacingPlaywrightAuthFlow.ts similarity index 97% rename from core/automation/infrastructure/adapters/automation/auth/IRacingPlaywrightAuthFlow.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/auth/IRacingPlaywrightAuthFlow.ts index 4e620c564..00fbfda19 100644 --- a/core/automation/infrastructure/adapters/automation/auth/IRacingPlaywrightAuthFlow.ts +++ b/apps/companion/main/automation/infrastructure/adapters/automation/auth/IRacingPlaywrightAuthFlow.ts @@ -1,5 +1,5 @@ import type { Page } from 'playwright'; -import type { LoggerPort } from '@core/automation/application/ports/LoggerPort'; +import type { LoggerPort } from 'apps/companion/main/automation/application/ports/LoggerPort'; import type { IPlaywrightAuthFlow } from './PlaywrightAuthFlow'; import { IRACING_URLS, IRACING_SELECTORS, IRACING_TIMEOUTS } from '../dom/IRacingSelectors'; import { AuthenticationGuard } from './AuthenticationGuard'; diff --git a/core/automation/infrastructure/adapters/automation/auth/PlaywrightAuthFlow.ts b/apps/companion/main/automation/infrastructure/adapters/automation/auth/PlaywrightAuthFlow.ts similarity index 100% rename from core/automation/infrastructure/adapters/automation/auth/PlaywrightAuthFlow.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/auth/PlaywrightAuthFlow.ts diff --git a/core/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.initiateLogin.browserMode.test.ts b/apps/companion/main/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.initiateLogin.browserMode.test.ts similarity index 86% rename from core/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.initiateLogin.browserMode.test.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.initiateLogin.browserMode.test.ts index 3ce1d9366..9f331e25b 100644 --- a/core/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.initiateLogin.browserMode.test.ts +++ b/apps/companion/main/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.initiateLogin.browserMode.test.ts @@ -1,12 +1,11 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import type { Page, BrowserContext } from 'playwright'; -import { PlaywrightAuthSessionService } from '@core/automation/infrastructure//automation/auth/PlaywrightAuthSessionService'; -import type { PlaywrightBrowserSession } from '@core/automation/infrastructure//automation/core/PlaywrightBrowserSession'; -import type { SessionCookieStore } from '@core/automation/infrastructure//automation/auth/SessionCookieStore'; -import type { IPlaywrightAuthFlow } from '@core/automation/infrastructure//automation/auth/PlaywrightAuthFlow'; -import type { LoggerPort as Logger } from '@core/automation/application/ports/LoggerPort'; -import { AuthenticationState } from '@core/automation/domain/value-objects/AuthenticationState'; -import { Result } from '@core/shared/result/Result'; +import type { LoggerPort as Logger } from 'apps/companion/main/automation/application/ports/LoggerPort'; +import { AuthenticationState } from 'apps/companion/main/automation/domain/value-objects/AuthenticationState'; +import { PlaywrightBrowserSession } from '../core/PlaywrightBrowserSession'; +import { IPlaywrightAuthFlow } from './PlaywrightAuthFlow'; +import { PlaywrightAuthSessionService } from './PlaywrightAuthSessionService'; +import { SessionCookieStore } from './SessionCookieStore'; describe('PlaywrightAuthSessionService.initiateLogin browser mode behaviour', () => { const originalEnv = { ...process.env }; diff --git a/core/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.ts b/apps/companion/main/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.ts similarity index 99% rename from core/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.ts index 5ad3c9220..adfc9bf64 100644 --- a/core/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.ts +++ b/apps/companion/main/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.ts @@ -5,7 +5,7 @@ import type { AuthenticationServicePort } from '../../../../application/ports/Au import type { LoggerPort } from '../../../../application/ports/LoggerPort'; import { AuthenticationState } from '../../../../domain/value-objects/AuthenticationState'; import { BrowserAuthenticationState } from '../../../../domain/value-objects/BrowserAuthenticationState'; -import { Result } from '../../../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; import { PlaywrightBrowserSession } from '../core/PlaywrightBrowserSession'; import { SessionCookieStore } from './SessionCookieStore'; import type { IPlaywrightAuthFlow } from './PlaywrightAuthFlow'; diff --git a/core/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.verifyPageAuthentication.test.ts b/apps/companion/main/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.verifyPageAuthentication.test.ts similarity index 84% rename from core/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.verifyPageAuthentication.test.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.verifyPageAuthentication.test.ts index 0c5608cbb..30098b17d 100644 --- a/core/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.verifyPageAuthentication.test.ts +++ b/apps/companion/main/automation/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.verifyPageAuthentication.test.ts @@ -1,13 +1,13 @@ import { describe, it, expect, vi } from 'vitest'; import type { Page, Locator } from 'playwright'; -import { PlaywrightAuthSessionService } from '@core/automation/infrastructure//automation/auth/PlaywrightAuthSessionService'; -import { AuthenticationState } from '@core/automation/domain/value-objects/AuthenticationState'; -import { BrowserAuthenticationState } from '@core/automation/domain/value-objects/BrowserAuthenticationState'; -import type { LoggerPort as Logger } from '@core/automation/application/ports/LoggerPort'; +import { AuthenticationState } from 'apps/companion/main/automation/domain/value-objects/AuthenticationState'; +import { BrowserAuthenticationState } from 'apps/companion/main/automation/domain/value-objects/BrowserAuthenticationState'; +import type { LoggerPort as Logger } from 'apps/companion/main/automation/application/ports/LoggerPort'; import type { Result } from '@core/shared/result/Result'; -import type { PlaywrightBrowserSession } from '@core/automation/infrastructure//automation/core/PlaywrightBrowserSession'; -import type { SessionCookieStore } from '@core/automation/infrastructure//automation/auth/SessionCookieStore'; -import type { IPlaywrightAuthFlow } from '@core/automation/infrastructure//automation/auth/PlaywrightAuthFlow'; +import { PlaywrightBrowserSession } from '../core/PlaywrightBrowserSession'; +import { IPlaywrightAuthFlow } from './PlaywrightAuthFlow'; +import { PlaywrightAuthSessionService } from './PlaywrightAuthSessionService'; +import { SessionCookieStore } from './SessionCookieStore'; describe('PlaywrightAuthSessionService.verifyPageAuthentication', () => { function createService(deps: { diff --git a/core/automation/infrastructure/adapters/automation/auth/SessionCookieStore.test.ts b/apps/companion/main/automation/infrastructure/adapters/automation/auth/SessionCookieStore.test.ts similarity index 98% rename from core/automation/infrastructure/adapters/automation/auth/SessionCookieStore.test.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/auth/SessionCookieStore.test.ts index e1f7aaddc..8dfde024a 100644 --- a/core/automation/infrastructure/adapters/automation/auth/SessionCookieStore.test.ts +++ b/apps/companion/main/automation/infrastructure/adapters/automation/auth/SessionCookieStore.test.ts @@ -1,6 +1,6 @@ import { describe, test, expect, beforeEach } from 'vitest'; -import { SessionCookieStore } from '@core/automation/infrastructure//automation/auth/SessionCookieStore'; import type { Cookie } from 'playwright'; +import { SessionCookieStore } from './SessionCookieStore'; const logger = console as unknown; diff --git a/core/automation/infrastructure/adapters/automation/auth/SessionCookieStore.ts b/apps/companion/main/automation/infrastructure/adapters/automation/auth/SessionCookieStore.ts similarity index 99% rename from core/automation/infrastructure/adapters/automation/auth/SessionCookieStore.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/auth/SessionCookieStore.ts index 2ebb740eb..9d264f24a 100644 --- a/core/automation/infrastructure/adapters/automation/auth/SessionCookieStore.ts +++ b/apps/companion/main/automation/infrastructure/adapters/automation/auth/SessionCookieStore.ts @@ -2,7 +2,7 @@ import * as fs from 'fs/promises'; import * as path from 'path'; import { AuthenticationState } from '../../../../domain/value-objects/AuthenticationState'; import { CookieConfiguration } from '../../../../domain/value-objects/CookieConfiguration'; -import { Result } from '../../../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; import type { LoggerPort } from '../../../../application/ports/LoggerPort'; interface Cookie { diff --git a/core/automation/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts b/apps/companion/main/automation/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts similarity index 99% rename from core/automation/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts index 7b47d9af9..939ba0d31 100644 --- a/core/automation/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts +++ b/apps/companion/main/automation/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts @@ -16,14 +16,12 @@ import type { ModalResultDTO } from '../../../../application/dto/ModalResultDTO' import type { AutomationResultDTO } from '../../../../application/dto/AutomationResultDTO'; import type { AuthenticationServicePort } from '../../../../application/ports/AuthenticationServicePort'; import type { LoggerPort } from '../../../../application/ports/LoggerPort'; -import { Result } from '../../../../../shared/result/Result'; -import { IRACING_SELECTORS, IRACING_URLS, IRACING_TIMEOUTS, ALL_BLOCKED_SELECTORS, BLOCKED_KEYWORDS } from '../dom/IRacingSelectors'; +import { Result } from '@gridpilot/shared/result/Result'; +import { IRACING_SELECTORS, IRACING_URLS, IRACING_TIMEOUTS, BLOCKED_KEYWORDS } from '../dom/IRacingSelectors'; import { SessionCookieStore } from '../auth/SessionCookieStore'; import { PlaywrightBrowserSession } from './PlaywrightBrowserSession'; -import { BrowserModeConfigLoader, BrowserMode } from '../../../config/BrowserModeConfig'; - -import { PageStateValidator, PageStateValidation, PageStateValidationResult } from '@core/automation/domain/services/PageStateValidator'; +import { PageStateValidator, PageStateValidation, PageStateValidationResult } from 'apps/companion/main/automation/domain/services/PageStateValidator'; import { IRacingDomNavigator } from '../dom/IRacingDomNavigator'; import { SafeClickService } from '../dom/SafeClickService'; import { IRacingDomInteractor } from '../dom/IRacingDomInteractor'; diff --git a/core/automation/infrastructure/adapters/automation/core/PlaywrightBrowserSession.ts b/apps/companion/main/automation/infrastructure/adapters/automation/core/PlaywrightBrowserSession.ts similarity index 98% rename from core/automation/infrastructure/adapters/automation/core/PlaywrightBrowserSession.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/core/PlaywrightBrowserSession.ts index fc00f45a5..3e1494ccb 100644 --- a/core/automation/infrastructure/adapters/automation/core/PlaywrightBrowserSession.ts +++ b/apps/companion/main/automation/infrastructure/adapters/automation/core/PlaywrightBrowserSession.ts @@ -4,8 +4,7 @@ import StealthPlugin from 'puppeteer-extra-plugin-stealth'; import * as fs from 'fs'; import * as path from 'path'; -import type { LoggerPort } from '@core/automation/application/ports/LoggerPort'; -import { BrowserModeConfigLoader, BrowserMode } from '../../../config/BrowserModeConfig'; +import type { LoggerPort } from 'apps/companion/main/automation/application/ports/LoggerPort'; import type { PlaywrightConfig } from './PlaywrightAutomationAdapter'; import { PlaywrightAutomationAdapter } from './PlaywrightAutomationAdapter'; diff --git a/core/automation/infrastructure/adapters/automation/core/WizardStepOrchestrator.ts b/apps/companion/main/automation/infrastructure/adapters/automation/core/WizardStepOrchestrator.ts similarity index 99% rename from core/automation/infrastructure/adapters/automation/core/WizardStepOrchestrator.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/core/WizardStepOrchestrator.ts index 47b62f742..2a86094ec 100644 --- a/core/automation/infrastructure/adapters/automation/core/WizardStepOrchestrator.ts +++ b/apps/companion/main/automation/infrastructure/adapters/automation/core/WizardStepOrchestrator.ts @@ -18,7 +18,7 @@ import type { PageStateValidation, PageStateValidationResult, } from '../../../../domain/services/PageStateValidator'; -import type { Result } from '../../../../../shared/result/Result'; +import type { Result } from '@gridpilot/shared/result/Result'; interface WizardStepOrchestratorDeps { config: Required; @@ -167,7 +167,7 @@ export class WizardStepOrchestrator { await this.navigator.waitForWizardStep(stepName); } - private async checkWizardDismissed(_currentStep: number): Promise { + private async checkWizardDismissed(currentStep: number): Promise { await this.navigator.checkWizardDismissed(currentStep); } diff --git a/core/automation/infrastructure/adapters/automation/dom/IRacingDomInteractor.ts b/apps/companion/main/automation/infrastructure/adapters/automation/dom/IRacingDomInteractor.ts similarity index 100% rename from core/automation/infrastructure/adapters/automation/dom/IRacingDomInteractor.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/dom/IRacingDomInteractor.ts diff --git a/core/automation/infrastructure/adapters/automation/dom/IRacingDomNavigator.ts b/apps/companion/main/automation/infrastructure/adapters/automation/dom/IRacingDomNavigator.ts similarity index 100% rename from core/automation/infrastructure/adapters/automation/dom/IRacingDomNavigator.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/dom/IRacingDomNavigator.ts diff --git a/core/automation/infrastructure/adapters/automation/dom/IRacingSelectors.ts b/apps/companion/main/automation/infrastructure/adapters/automation/dom/IRacingSelectors.ts similarity index 100% rename from core/automation/infrastructure/adapters/automation/dom/IRacingSelectors.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/dom/IRacingSelectors.ts diff --git a/core/automation/infrastructure/adapters/automation/dom/SafeClickService.ts b/apps/companion/main/automation/infrastructure/adapters/automation/dom/SafeClickService.ts similarity index 99% rename from core/automation/infrastructure/adapters/automation/dom/SafeClickService.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/dom/SafeClickService.ts index b90a60ea0..6a33d5063 100644 --- a/core/automation/infrastructure/adapters/automation/dom/SafeClickService.ts +++ b/apps/companion/main/automation/infrastructure/adapters/automation/dom/SafeClickService.ts @@ -1,5 +1,5 @@ import type { Page } from 'playwright'; -import type { LoggerPort } from '@core/automation/application/ports/LoggerPort'; +import type { LoggerPort } from 'apps/companion/main/automation/application/ports/LoggerPort'; import { IRACING_SELECTORS, BLOCKED_KEYWORDS } from './IRacingSelectors'; import type { PlaywrightConfig } from '../core/PlaywrightAutomationAdapter'; import { PlaywrightBrowserSession } from '../core/PlaywrightBrowserSession'; diff --git a/core/automation/infrastructure/adapters/automation/engine/AutomationEngineAdapter.ts b/apps/companion/main/automation/infrastructure/adapters/automation/engine/AutomationEngineAdapter.ts similarity index 100% rename from core/automation/infrastructure/adapters/automation/engine/AutomationEngineAdapter.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/engine/AutomationEngineAdapter.ts diff --git a/core/automation/infrastructure/adapters/automation/engine/FixtureServer.ts b/apps/companion/main/automation/infrastructure/adapters/automation/engine/FixtureServer.ts similarity index 100% rename from core/automation/infrastructure/adapters/automation/engine/FixtureServer.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/engine/FixtureServer.ts diff --git a/core/automation/infrastructure/adapters/automation/engine/MockAutomationEngineAdapter.ts b/apps/companion/main/automation/infrastructure/adapters/automation/engine/MockAutomationEngineAdapter.ts similarity index 100% rename from core/automation/infrastructure/adapters/automation/engine/MockAutomationEngineAdapter.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/engine/MockAutomationEngineAdapter.ts diff --git a/core/automation/infrastructure/adapters/automation/engine/MockBrowserAutomationAdapter.ts b/apps/companion/main/automation/infrastructure/adapters/automation/engine/MockBrowserAutomationAdapter.ts similarity index 100% rename from core/automation/infrastructure/adapters/automation/engine/MockBrowserAutomationAdapter.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/engine/MockBrowserAutomationAdapter.ts diff --git a/core/automation/infrastructure/adapters/automation/index.ts b/apps/companion/main/automation/infrastructure/adapters/automation/index.ts similarity index 100% rename from core/automation/infrastructure/adapters/automation/index.ts rename to apps/companion/main/automation/infrastructure/adapters/automation/index.ts diff --git a/core/automation/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts b/apps/companion/main/automation/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts similarity index 98% rename from core/automation/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts rename to apps/companion/main/automation/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts index 151241233..7e6d95e27 100644 --- a/core/automation/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts +++ b/apps/companion/main/automation/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts @@ -5,7 +5,7 @@ import type { BrowserWindow } from 'electron'; import { ipcMain } from 'electron'; -import { Result } from '../../../../shared/result/Result'; +import { Result } from '@gridpilot/shared/result/Result'; import type { CheckoutConfirmationPort } from '../../../application/ports/CheckoutConfirmationPort'; import type { CheckoutConfirmationRequestDTO } from '../../../application/dto/CheckoutConfirmationRequestDTO'; import { CheckoutConfirmation } from '../../../domain/value-objects/CheckoutConfirmation'; diff --git a/core/automation/infrastructure/adapters/logging/ConsoleLogAdapter.ts b/apps/companion/main/automation/infrastructure/adapters/logging/ConsoleLogAdapter.ts similarity index 100% rename from core/automation/infrastructure/adapters/logging/ConsoleLogAdapter.ts rename to apps/companion/main/automation/infrastructure/adapters/logging/ConsoleLogAdapter.ts diff --git a/core/automation/infrastructure/adapters/logging/NoOpLogAdapter.ts b/apps/companion/main/automation/infrastructure/adapters/logging/NoOpLogAdapter.ts similarity index 100% rename from core/automation/infrastructure/adapters/logging/NoOpLogAdapter.ts rename to apps/companion/main/automation/infrastructure/adapters/logging/NoOpLogAdapter.ts diff --git a/core/automation/infrastructure/adapters/logging/PinoLogAdapter.ts b/apps/companion/main/automation/infrastructure/adapters/logging/PinoLogAdapter.ts similarity index 92% rename from core/automation/infrastructure/adapters/logging/PinoLogAdapter.ts rename to apps/companion/main/automation/infrastructure/adapters/logging/PinoLogAdapter.ts index f6d1c56d4..34dcac957 100644 --- a/core/automation/infrastructure/adapters/logging/PinoLogAdapter.ts +++ b/apps/companion/main/automation/infrastructure/adapters/logging/PinoLogAdapter.ts @@ -1,6 +1,6 @@ -import type { LoggerPort } from '@core/automation/application/ports/LoggerPort'; -import type { LogContext } from '@core/automation/application/ports/LoggerContext'; -import type { LogLevel } from '@core/automation/application/ports/LoggerLogLevel'; +import type { LoggerPort } from 'apps/companion/main/automation/application/ports/LoggerPort'; +import type { LogContext } from 'apps/companion/main/automation/application/ports/LoggerContext'; +import type { LogLevel } from 'apps/companion/main/automation/application/ports/LoggerLogLevel'; import { loadLoggingConfig, type LoggingEnvironmentConfig } from '../../config/LoggingConfig'; import type { Logger } from '@core/shared/application'; diff --git a/core/automation/infrastructure/adapters/logging/index.ts b/apps/companion/main/automation/infrastructure/adapters/logging/index.ts similarity index 100% rename from core/automation/infrastructure/adapters/logging/index.ts rename to apps/companion/main/automation/infrastructure/adapters/logging/index.ts diff --git a/core/automation/infrastructure/repositories/InMemorySessionRepository.ts b/apps/companion/main/automation/infrastructure/repositories/InMemorySessionRepository.ts similarity index 100% rename from core/automation/infrastructure/repositories/InMemorySessionRepository.ts rename to apps/companion/main/automation/infrastructure/repositories/InMemorySessionRepository.ts diff --git a/apps/companion/main/di-config.ts b/apps/companion/main/di-config.ts index 4962f51c5..a181a4da6 100644 --- a/apps/companion/main/di-config.ts +++ b/apps/companion/main/di-config.ts @@ -5,23 +5,23 @@ import * as path from 'path'; import * as os from 'os'; // Domain & Application -import type { SessionRepositoryPort } from '@core/automation/application/ports/SessionRepositoryPort'; -import type { IBrowserAutomation } from '@core/automation/application/ports/ScreenAutomationPort'; -import type { AutomationEnginePort } from '@core/automation/application/ports/AutomationEnginePort'; -import type { AuthenticationServicePort } from '@core/automation/application/ports/AuthenticationServicePort'; -import type { LoggerPort } from '@core/automation/application/ports/LoggerPort'; -import type { OverlaySyncPort } from '@core/automation/application/ports/OverlaySyncPort'; -import type { CheckoutServicePort } from '@core/automation/application/ports/CheckoutServicePort'; -import { StartAutomationSessionUseCase } from '@core/automation/application/use-cases/StartAutomationSessionUseCase'; -import { CheckAuthenticationUseCase } from '@core/automation/application/use-cases/CheckAuthenticationUseCase'; -import { InitiateLoginUseCase } from '@core/automation/application/use-cases/InitiateLoginUseCase'; -import { ClearSessionUseCase } from '@core/automation/application/use-cases/ClearSessionUseCase'; -import { ConfirmCheckoutUseCase } from '@core/automation/application/use-cases/ConfirmCheckoutUseCase'; -import { OverlaySyncService } from '@core/automation/application/services/OverlaySyncService'; +import type { SessionRepositoryPort } from 'apps/companion/main/automation/application/ports/SessionRepositoryPort'; +import type { IBrowserAutomation } from 'apps/companion/main/automation/application/ports/ScreenAutomationPort'; +import type { AutomationEnginePort } from 'apps/companion/main/automation/application/ports/AutomationEnginePort'; +import type { AuthenticationServicePort } from 'apps/companion/main/automation/application/ports/AuthenticationServicePort'; +import type { LoggerPort } from 'apps/companion/main/automation/application/ports/LoggerPort'; +import type { OverlaySyncPort } from 'apps/companion/main/automation/application/ports/OverlaySyncPort'; +import type { CheckoutServicePort } from 'apps/companion/main/automation/application/ports/CheckoutServicePort'; +import { StartAutomationSessionUseCase } from 'apps/companion/main/automation/application/use-cases/StartAutomationSessionUseCase'; +import { CheckAuthenticationUseCase } from 'apps/companion/main/automation/application/use-cases/CheckAuthenticationUseCase'; +import { InitiateLoginUseCase } from 'apps/companion/main/automation/application/use-cases/InitiateLoginUseCase'; +import { ClearSessionUseCase } from 'apps/companion/main/automation/application/use-cases/ClearSessionUseCase'; +import { ConfirmCheckoutUseCase } from 'apps/companion/main/automation/application/use-cases/ConfirmCheckoutUseCase'; +import { OverlaySyncService } from 'apps/companion/main/automation/application/services/OverlaySyncService'; import type { IAutomationLifecycleEmitter } from '@core/automation/infrastructure//IAutomationLifecycleEmitter'; // Infrastructure -import { InMemorySessionRepository } from '@core/automation/infrastructure/repositories/InMemorySessionRepository'; +import { InMemorySessionRepository } from 'apps/companion/main/automation/infrastructure/repositories/InMemorySessionRepository'; import { MockBrowserAutomationAdapter, PlaywrightAutomationAdapter, diff --git a/apps/companion/main/di-container.ts b/apps/companion/main/di-container.ts index 5449aa0c3..85f5b717c 100644 --- a/apps/companion/main/di-container.ts +++ b/apps/companion/main/di-container.ts @@ -2,20 +2,20 @@ import 'reflect-metadata'; import { configureDIContainer, resetDIContainer, getDIContainer, resolveSessionDataPath, resolveTemplatePath } from './di-config'; import { DI_TOKENS } from './di-tokens'; import { PlaywrightAutomationAdapter, FixtureServer } from '@core/automation/infrastructure//automation'; -import { StartAutomationSessionUseCase } from '@core/automation/application/use-cases/StartAutomationSessionUseCase'; -import { CheckAuthenticationUseCase } from '@core/automation/application/use-cases/CheckAuthenticationUseCase'; -import { InitiateLoginUseCase } from '@core/automation/application/use-cases/InitiateLoginUseCase'; -import { ClearSessionUseCase } from '@core/automation/application/use-cases/ClearSessionUseCase'; -import { ConfirmCheckoutUseCase } from '@core/automation/application/use-cases/ConfirmCheckoutUseCase'; +import { StartAutomationSessionUseCase } from 'apps/companion/main/automation/application/use-cases/StartAutomationSessionUseCase'; +import { CheckAuthenticationUseCase } from 'apps/companion/main/automation/application/use-cases/CheckAuthenticationUseCase'; +import { InitiateLoginUseCase } from 'apps/companion/main/automation/application/use-cases/InitiateLoginUseCase'; +import { ClearSessionUseCase } from 'apps/companion/main/automation/application/use-cases/ClearSessionUseCase'; +import { ConfirmCheckoutUseCase } from 'apps/companion/main/automation/application/use-cases/ConfirmCheckoutUseCase'; import { getAutomationMode, AutomationMode, BrowserModeConfigLoader } from '@core/automation/infrastructure/config'; -import type { SessionRepositoryPort } from '@core/automation/application/ports/SessionRepositoryPort'; -import type { IBrowserAutomation } from '@core/automation/application/ports/ScreenAutomationPort'; -import type { AutomationEnginePort } from '@core/automation/application/ports/AutomationEnginePort'; -import type { AuthenticationServicePort } from '@core/automation/application/ports/AuthenticationServicePort'; -import type { CheckoutConfirmationPort } from '@core/automation/application/ports/CheckoutConfirmationPort'; -import type { CheckoutServicePort } from '@core/automation/application/ports/CheckoutServicePort'; -import type { LoggerPort } from '@core/automation/application/ports/LoggerPort'; -import type { OverlaySyncPort } from '@core/automation/application/ports/OverlaySyncPort'; +import type { SessionRepositoryPort } from 'apps/companion/main/automation/application/ports/SessionRepositoryPort'; +import type { IBrowserAutomation } from 'apps/companion/main/automation/application/ports/ScreenAutomationPort'; +import type { AutomationEnginePort } from 'apps/companion/main/automation/application/ports/AutomationEnginePort'; +import type { AuthenticationServicePort } from 'apps/companion/main/automation/application/ports/AuthenticationServicePort'; +import type { CheckoutConfirmationPort } from 'apps/companion/main/automation/application/ports/CheckoutConfirmationPort'; +import type { CheckoutServicePort } from 'apps/companion/main/automation/application/ports/CheckoutServicePort'; +import type { LoggerPort } from 'apps/companion/main/automation/application/ports/LoggerPort'; +import type { OverlaySyncPort } from 'apps/companion/main/automation/application/ports/OverlaySyncPort'; // Re-export for backward compatibility export { resolveSessionDataPath, resolveTemplatePath }; diff --git a/apps/companion/main/ipc-handlers.ts b/apps/companion/main/ipc-handlers.ts index 3dd75db9d..a666f757b 100644 --- a/apps/companion/main/ipc-handlers.ts +++ b/apps/companion/main/ipc-handlers.ts @@ -1,11 +1,11 @@ import { ipcMain } from 'electron'; import type { BrowserWindow, IpcMainInvokeEvent } from 'electron'; import { DIContainer } from './di-container'; -import type { HostedSessionConfig } from 'core/automation/domain/types/HostedSessionConfig'; -import { StepId } from 'core/automation/domain/value-objects/StepId'; -import { AuthenticationState } from 'core/automation/domain/value-objects/AuthenticationState'; +import type { HostedSessionConfig } from 'apps/companion/main/automation/domain/types/HostedSessionConfig'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; +import { AuthenticationState } from 'apps/companion/main/automation/domain/value-objects/AuthenticationState'; import { ElectronCheckoutConfirmationAdapter } from 'core/automation/infrastructure//ipc/ElectronCheckoutConfirmationAdapter'; -import type { OverlayAction } from 'core/automation/application/ports/OverlaySyncPort'; +import type { OverlayAction } from 'apps/companion/main/automation/application/ports/OverlaySyncPort'; import type { IAutomationLifecycleEmitter } from 'core/automation/infrastructure//IAutomationLifecycleEmitter'; let progressMonitorInterval: NodeJS.Timeout | null = null; diff --git a/apps/companion/main/preload.ts b/apps/companion/main/preload.ts index 696f4fa5d..7959c1f1a 100644 --- a/apps/companion/main/preload.ts +++ b/apps/companion/main/preload.ts @@ -1,6 +1,6 @@ import { contextBridge, ipcRenderer } from 'electron'; -import type { HostedSessionConfig } from '../../../core/automation/domain/types/HostedSessionConfig'; -import type { AuthenticationState } from '../../../core/automation/domain/value-objects/AuthenticationState'; +import type { HostedSessionConfig } from './automation/domain/types/HostedSessionConfig'; +import type { AuthenticationState } from './automation/domain/value-objects/AuthenticationState'; export interface AuthStatusEvent { state: AuthenticationState; diff --git a/apps/companion/renderer/App.tsx b/apps/companion/renderer/App.tsx index 4a7de8a6d..d96281210 100644 --- a/apps/companion/renderer/App.tsx +++ b/apps/companion/renderer/App.tsx @@ -5,8 +5,8 @@ import { LoginPrompt } from './components/LoginPrompt'; import { BrowserModeToggle } from './components/BrowserModeToggle'; import { CheckoutConfirmationDialog } from './components/CheckoutConfirmationDialog'; import { RaceCreationSuccessScreen } from './components/RaceCreationSuccessScreen'; -import type { HostedSessionConfig } from '../../../core/automation/domain/types/HostedSessionConfig'; -import type { AuthenticationState } from '../../../core/automation/domain/value-objects/AuthenticationState'; +import type { HostedSessionConfig } from '../main/automation/domain/types/HostedSessionConfig'; +import type { AuthenticationState } from '../main/automation/domain/value-objects/AuthenticationState'; import type { StartAutomationResponse } from '../main/preload'; interface SessionProgress { diff --git a/apps/companion/renderer/components/SessionCreationForm.tsx b/apps/companion/renderer/components/SessionCreationForm.tsx index fe84203e9..38c660dea 100644 --- a/apps/companion/renderer/components/SessionCreationForm.tsx +++ b/apps/companion/renderer/components/SessionCreationForm.tsx @@ -1,5 +1,5 @@ import React, { useState } from 'react'; -import type { HostedSessionConfig } from '@core/automation/domain/types/HostedSessionConfig'; +import type { HostedSessionConfig } from 'apps/companion/main/automation/domain/types/HostedSessionConfig'; interface SessionCreationFormProps { onSubmit: (config: HostedSessionConfig) => void; diff --git a/core/automation/application/CompleteDriverOnboardingUseCase.test.ts b/core/automation/application/CompleteDriverOnboardingUseCase.test.ts deleted file mode 100644 index c9172e25e..000000000 --- a/core/automation/application/CompleteDriverOnboardingUseCase.test.ts +++ /dev/null @@ -1,102 +0,0 @@ -import { describe, it, expect, beforeEach, vi } from 'vitest'; -import { CompleteDriverOnboardingUseCase } from '@core/racing/application/use-cases/CompleteDriverOnboardingUseCase'; -import { IDriverRepository } from '@core/racing/domain/repositories/IDriverRepository'; -import { CompleteOnboardingPresenter } from '@apps/api/src/modules/driver/presenters/CompleteOnboardingPresenter'; - -describe('CompleteDriverOnboardingUseCase', () => { - let useCase: CompleteDriverOnboardingUseCase; - let driverRepository: { findById: () => Promise; save: () => Promise }; - - beforeEach(() => { - driverRepository = { - findById: vi.fn(), - save: vi.fn(), - }; - useCase = new CompleteDriverOnboardingUseCase(driverRepository as IDriverRepository); - }); - - describe('execute', () => { - it('should create a new driver and return success', async () => { - const input = { - userId: 'user-123', - firstName: 'John', - lastName: 'Doe', - displayName: 'John Doe', - country: 'US', - timezone: 'America/New_York', - bio: 'Racing enthusiast', - }; - - driverRepository.findById.mockResolvedValue(null); // Driver doesn't exist - driverRepository.save.mockResolvedValue(undefined); - - const presenter = new CompleteOnboardingPresenter(); - - await useCase.execute(input, presenter); - - expect(driverRepository.findById).toHaveBeenCalledWith('user-123'); - expect(driverRepository.save).toHaveBeenCalledWith( - expect.objectContaining({ - id: 'user-123', - iracingId: 'user-123', - name: 'John Doe', - country: 'US', - bio: 'Racing enthusiast', - }) - ); - expect(presenter.viewModel).toEqual({ - success: true, - driverId: 'user-123', - errorMessage: undefined, - }); - }); - - it('should return error if driver already exists', async () => { - const input = { - userId: 'user-123', - firstName: 'John', - lastName: 'Doe', - displayName: 'John Doe', - country: 'US', - }; - - const existingDriver = { - id: 'user-123', - name: 'Existing Driver', - }; - - driverRepository.findById.mockResolvedValue(existingDriver); - - const presenter = new CompleteOnboardingPresenter(); - - await useCase.execute(input, presenter); - - expect(driverRepository.findById).toHaveBeenCalledWith('user-123'); - expect(driverRepository.save).not.toHaveBeenCalled(); - expect(presenter.viewModel).toEqual({ - success: false, - driverId: undefined, - errorMessage: 'Driver already exists', - }); - }); - - it('should handle domain validation errors', async () => { - const input = { - userId: 'user-123', - firstName: 'John', - lastName: 'Doe', - displayName: 'John Doe', - country: 'INVALID', // Invalid country code - }; - - driverRepository.findById.mockResolvedValue(null); - - const presenter = new CompleteOnboardingPresenter(); - - await useCase.execute(input, presenter); - - expect(presenter.viewModel.success).toBe(false); - expect(presenter.viewModel.errorMessage).toContain('Country must be a valid ISO code'); - }); - }); -}); \ No newline at end of file diff --git a/core/automation/application/ConfirmCheckoutUseCase.enhanced.test.ts b/core/automation/application/ConfirmCheckoutUseCase.enhanced.test.ts deleted file mode 100644 index f3643c87e..000000000 --- a/core/automation/application/ConfirmCheckoutUseCase.enhanced.test.ts +++ /dev/null @@ -1,164 +0,0 @@ -import { describe, it, expect, vi, beforeEach } from 'vitest'; -import { ConfirmCheckoutUseCase } from '@core/automation/application/use-cases/ConfirmCheckoutUseCase'; -import { Result } from '@core/shared/result/Result'; -import { CheckoutPrice } from '@core/automation/domain/value-objects/CheckoutPrice'; -import { CheckoutState } from '@core/automation/domain/value-objects/CheckoutState'; -import { CheckoutConfirmation } from '@core/automation/domain/value-objects/CheckoutConfirmation'; -import type { CheckoutServicePort } from '@core/automation/application/ports/CheckoutServicePort'; -import type { CheckoutConfirmationPort } from '@core/automation/application/ports/CheckoutConfirmationPort'; - -describe('ConfirmCheckoutUseCase - Enhanced with Confirmation Port', () => { - let mockCheckoutService: CheckoutServicePort; - let mockConfirmationPort: CheckoutConfirmationPort; - let useCase: ConfirmCheckoutUseCase; - - beforeEach(() => { - mockCheckoutService = { - extractCheckoutInfo: vi.fn(), - proceedWithCheckout: vi.fn(), - }; - - mockConfirmationPort = { - requestCheckoutConfirmation: vi.fn(), - }; - - useCase = new ConfirmCheckoutUseCase(mockCheckoutService, mockConfirmationPort); - }); - - describe('with new confirmation flow', () => { - it('should extract price, request confirmation via port, then proceed', async () => { - const price = CheckoutPrice.fromString('$25.50'); - const state = CheckoutState.ready(); - - vi.mocked(mockCheckoutService.extractCheckoutInfo).mockResolvedValue( - Result.ok({ price, state, buttonHtml: '' }) - ); - - vi.mocked(mockConfirmationPort.requestCheckoutConfirmation).mockResolvedValue( - Result.ok(CheckoutConfirmation.create('confirmed')) - ); - - vi.mocked(mockCheckoutService.proceedWithCheckout).mockResolvedValue( - Result.ok(undefined) - ); - - const result = await useCase.execute(); - - expect(mockCheckoutService.extractCheckoutInfo).toHaveBeenCalled(); - expect(mockConfirmationPort.requestCheckoutConfirmation).toHaveBeenCalledWith( - expect.objectContaining({ - price: expect.any(CheckoutPrice), - state: expect.any(CheckoutState), - }) - ); - expect(mockCheckoutService.proceedWithCheckout).toHaveBeenCalled(); - expect(result.isOk()).toBe(true); - }); - - it('should not proceed if user cancels confirmation', async () => { - const price = CheckoutPrice.fromString('$10.00'); - const state = CheckoutState.ready(); - - vi.mocked(mockCheckoutService.extractCheckoutInfo).mockResolvedValue( - Result.ok({ price, state, buttonHtml: '' }) - ); - - vi.mocked(mockConfirmationPort.requestCheckoutConfirmation).mockResolvedValue( - Result.ok(CheckoutConfirmation.create('cancelled')) - ); - - const result = await useCase.execute(); - - expect(mockConfirmationPort.requestCheckoutConfirmation).toHaveBeenCalled(); - expect(mockCheckoutService.proceedWithCheckout).not.toHaveBeenCalled(); - expect(result.isErr()).toBe(true); - expect(result.unwrapErr().message).toContain('cancelled'); - }); - - it('should not proceed if confirmation times out', async () => { - const price = CheckoutPrice.fromString('$10.00'); - const state = CheckoutState.ready(); - - vi.mocked(mockCheckoutService.extractCheckoutInfo).mockResolvedValue( - Result.ok({ price, state, buttonHtml: '' }) - ); - - vi.mocked(mockConfirmationPort.requestCheckoutConfirmation).mockResolvedValue( - Result.ok(CheckoutConfirmation.create('timeout')) - ); - - const result = await useCase.execute(); - - expect(mockConfirmationPort.requestCheckoutConfirmation).toHaveBeenCalled(); - expect(mockCheckoutService.proceedWithCheckout).not.toHaveBeenCalled(); - expect(result.isErr()).toBe(true); - expect(result.unwrapErr().message).toContain('timeout'); - }); - - it('should fail if confirmation port returns error', async () => { - const price = CheckoutPrice.fromString('$10.00'); - const state = CheckoutState.ready(); - - vi.mocked(mockCheckoutService.extractCheckoutInfo).mockResolvedValue( - Result.ok({ price, state, buttonHtml: '' }) - ); - - vi.mocked(mockConfirmationPort.requestCheckoutConfirmation).mockResolvedValue( - Result.err(new Error('IPC communication failed')) - ); - - const result = await useCase.execute(); - - expect(result.isErr()).toBe(true); - expect(result.unwrapErr().message).toContain('IPC communication failed'); - }); - - it('should still reject insufficient funds before confirmation', async () => { - const price = CheckoutPrice.fromString('$10.00'); - const state = CheckoutState.insufficientFunds(); - - vi.mocked(mockCheckoutService.extractCheckoutInfo).mockResolvedValue( - Result.ok({ price, state, buttonHtml: '' }) - ); - - const result = await useCase.execute(); - - expect(mockConfirmationPort.requestCheckoutConfirmation).not.toHaveBeenCalled(); - expect(mockCheckoutService.proceedWithCheckout).not.toHaveBeenCalled(); - expect(result.isErr()).toBe(true); - expect(result.unwrapErr().message).toContain('Insufficient funds'); - }); - - it('should pass session metadata to confirmation port', async () => { - const price = CheckoutPrice.fromString('$25.50'); - const state = CheckoutState.ready(); - const sessionMetadata = { - sessionName: 'Test Race', - trackId: 'spa', - carIds: ['car1', 'car2'], - }; - - vi.mocked(mockCheckoutService.extractCheckoutInfo).mockResolvedValue( - Result.ok({ price, state, buttonHtml: '' }) - ); - - vi.mocked(mockConfirmationPort.requestCheckoutConfirmation).mockResolvedValue( - Result.ok(CheckoutConfirmation.create('confirmed')) - ); - - vi.mocked(mockCheckoutService.proceedWithCheckout).mockResolvedValue( - Result.ok(undefined) - ); - - const result = await useCase.execute(sessionMetadata); - - expect(mockConfirmationPort.requestCheckoutConfirmation).toHaveBeenCalledWith( - expect.objectContaining({ - sessionMetadata, - timeoutMs: expect.any(Number), - }) - ); - expect(result.isOk()).toBe(true); - }); - }); -}); \ No newline at end of file diff --git a/core/automation/application/GetTotalDriversUseCase.test.ts b/core/automation/application/GetTotalDriversUseCase.test.ts deleted file mode 100644 index d657df7cb..000000000 --- a/core/automation/application/GetTotalDriversUseCase.test.ts +++ /dev/null @@ -1,33 +0,0 @@ -import { describe, it, expect, beforeEach, vi } from 'vitest'; -import { GetTotalDriversUseCase } from '@core/racing/application/use-cases/GetTotalDriversUseCase'; -import { IDriverRepository } from '@core/racing/domain/repositories/IDriverRepository'; -import { DriverStatsPresenter } from '@apps/api/src/modules/driver/presenters/DriverStatsPresenter'; - -describe('GetTotalDriversUseCase', () => { - let useCase: GetTotalDriversUseCase; - let driverRepository: { findAll: any }; - - beforeEach(() => { - driverRepository = { - findAll: vi.fn(), - }; - useCase = new GetTotalDriversUseCase(driverRepository as IDriverRepository); - }); - - it('should return total drivers count', async () => { - // Arrange - const mockDrivers = [ - { id: '1', name: 'Driver 1' }, - { id: '2', name: 'Driver 2' }, - ]; - driverRepository.findAll.mockResolvedValue(mockDrivers); - const presenter = new DriverStatsPresenter(); - - // Act - await useCase.execute(undefined, presenter); - - // Assert - expect(driverRepository.findAll).toHaveBeenCalled(); - expect(presenter.viewModel).toEqual({ totalDrivers: 2 }); - }); -}); \ No newline at end of file diff --git a/core/automation/application/ICheckoutConfirmationPort.test.ts b/core/automation/application/ICheckoutConfirmationPort.test.ts deleted file mode 100644 index eb2b3587d..000000000 --- a/core/automation/application/ICheckoutConfirmationPort.test.ts +++ /dev/null @@ -1,180 +0,0 @@ -import { describe, it, expect } from 'vitest'; -import { Result } from '@core/shared/result/Result'; -import { CheckoutConfirmation } from '@core/automation/domain/value-objects/CheckoutConfirmation'; -import { CheckoutPrice } from '@core/automation/domain/value-objects/CheckoutPrice'; -import { CheckoutState } from '@core/automation/domain/value-objects/CheckoutState'; - -/** - * Contract tests for ICheckoutConfirmationPort - * - * Any implementation must: - * 1. Accept CheckoutConfirmationRequest with price, state, sessionMetadata, timeoutMs - * 2. Return Result with decision: confirmed, cancelled, or timeout - * 3. Handle timeout gracefully by returning timeout decision - * 4. Validate request parameters before processing - */ - -export interface CheckoutConfirmationRequest { - price: CheckoutPrice; - state: CheckoutState; - sessionMetadata: { - sessionName: string; - trackId: string; - carIds: string[]; - }; - timeoutMs: number; -} - -export interface ICheckoutConfirmationPort { - requestCheckoutConfirmation( - request: CheckoutConfirmationRequest - ): Promise>; -} - -describe('ICheckoutConfirmationPort contract', () => { - it('should define the required interface structure', () => { - // This test verifies the port interface contract exists - const mockPort: ICheckoutConfirmationPort = { - requestCheckoutConfirmation: async (__request: CheckoutConfirmationRequest) => { - return Result.ok(CheckoutConfirmation.create('confirmed')); - }, - }; - - expect(mockPort.requestCheckoutConfirmation).toBeDefined(); - expect(typeof mockPort.requestCheckoutConfirmation).toBe('function'); - }); - - it('should accept valid CheckoutConfirmationRequest', async () => { - const mockPort: ICheckoutConfirmationPort = { - requestCheckoutConfirmation: async (request: CheckoutConfirmationRequest) => { - expect(request.price).toBeInstanceOf(CheckoutPrice); - expect(request.state).toBeInstanceOf(CheckoutState); - expect(request.sessionMetadata).toBeDefined(); - expect(request.sessionMetadata.sessionName).toBeTruthy(); - expect(request.sessionMetadata.trackId).toBeTruthy(); - expect(Array.isArray(request.sessionMetadata.carIds)).toBe(true); - expect(request.timeoutMs).toBeGreaterThan(0); - return Result.ok(CheckoutConfirmation.create('confirmed')); - }, - }; - - const request: CheckoutConfirmationRequest = { - price: CheckoutPrice.fromString('$10.00'), - state: CheckoutState.ready(), - sessionMetadata: { - sessionName: 'Test Session', - trackId: 'spa', - carIds: ['car1', 'car2'], - }, - timeoutMs: 30000, - }; - - const result = await mockPort.requestCheckoutConfirmation(request); - expect(result.isOk()).toBe(true); - }); - - it('should return Result with CheckoutConfirmation on success', async () => { - const mockPort: ICheckoutConfirmationPort = { - requestCheckoutConfirmation: async () => { - return Result.ok(CheckoutConfirmation.create('confirmed')); - }, - }; - - const request: CheckoutConfirmationRequest = { - price: CheckoutPrice.fromString('$10.00'), - state: CheckoutState.ready(), - sessionMetadata: { - sessionName: 'Test Session', - trackId: 'spa', - carIds: ['car1'], - }, - timeoutMs: 30000, - }; - - const result = await mockPort.requestCheckoutConfirmation(request); - expect(result.isOk()).toBe(true); - - const confirmation = result.unwrap(); - expect(confirmation).toBeInstanceOf(CheckoutConfirmation); - expect(confirmation.isConfirmed()).toBe(true); - }); - - it('should support cancelled decision', async () => { - const mockPort: ICheckoutConfirmationPort = { - requestCheckoutConfirmation: async () => { - return Result.ok(CheckoutConfirmation.create('cancelled')); - }, - }; - - const request: CheckoutConfirmationRequest = { - price: CheckoutPrice.fromString('$10.00'), - state: CheckoutState.ready(), - sessionMetadata: { - sessionName: 'Test Session', - trackId: 'spa', - carIds: ['car1'], - }, - timeoutMs: 30000, - }; - - const result = await mockPort.requestCheckoutConfirmation(request); - expect(result.isOk()).toBe(true); - - const confirmation = result.unwrap(); - expect(confirmation.isCancelled()).toBe(true); - }); - - it('should support timeout decision', async () => { - const mockPort: ICheckoutConfirmationPort = { - requestCheckoutConfirmation: async () => { - return Result.ok(CheckoutConfirmation.create('timeout')); - }, - }; - - const request: CheckoutConfirmationRequest = { - price: CheckoutPrice.fromString('$10.00'), - state: CheckoutState.ready(), - sessionMetadata: { - sessionName: 'Test Session', - trackId: 'spa', - carIds: ['car1'], - }, - timeoutMs: 1000, - }; - - const result = await mockPort.requestCheckoutConfirmation(request); - expect(result.isOk()).toBe(true); - - const confirmation = result.unwrap(); - expect(confirmation.isTimeout()).toBe(true); - }); - - it('should return error Result for invalid requests', async () => { - const mockPort: ICheckoutConfirmationPort = { - requestCheckoutConfirmation: async (request: CheckoutConfirmationRequest) => { - if (request.timeoutMs <= 0) { - return Result.err(new Error('Timeout must be positive')); - } - if (!request.sessionMetadata.sessionName) { - return Result.err(new Error('Session name is required')); - } - return Result.ok(CheckoutConfirmation.create('confirmed')); - }, - }; - - const invalidRequest: CheckoutConfirmationRequest = { - price: CheckoutPrice.fromString('$10.00'), - state: CheckoutState.ready(), - sessionMetadata: { - sessionName: '', - trackId: 'spa', - carIds: ['car1'], - }, - timeoutMs: 30000, - }; - - const result = await mockPort.requestCheckoutConfirmation(invalidRequest); - expect(result.isErr()).toBe(true); - expect(result.unwrapErr().message).toContain('Session name'); - }); -}); \ No newline at end of file diff --git a/core/automation/application/OverlaySyncService.timeout.test.ts b/core/automation/application/OverlaySyncService.timeout.test.ts deleted file mode 100644 index 31c81cd69..000000000 --- a/core/automation/application/OverlaySyncService.timeout.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { describe, expect, test } from 'vitest' -import { OverlayAction } from '@core/automation/application/ports/OverlaySyncPort' -import { IAutomationLifecycleEmitter, LifecycleCallback } from '@core/automation/infrastructure//IAutomationLifecycleEmitter' -import { OverlaySyncService } from '@core/automation/application/services/OverlaySyncService' - -class MockLifecycleEmitter implements IAutomationLifecycleEmitter { - private callbacks: Set = new Set() - onLifecycle(cb: LifecycleCallback): void { - this.callbacks.add(cb) - } - offLifecycle(cb: LifecycleCallback): void { - this.callbacks.delete(cb) - } - async emit(event: { type: 'panel-attached'|'modal-opened'|'action-started'|'action-complete'|'action-failed'|'panel-missing'; actionId: string; timestamp: number }) { - for (const cb of Array.from(this.callbacks)) { - cb(event) - } - } -} - -describe('OverlaySyncService timeout (unit)', () => { - test('startAction with short timeout resolves as tentative when no events', async () => { - const emitter = new MockLifecycleEmitter() - const svc = new OverlaySyncService({ - lifecycleEmitter: emitter, - logger: console as unknown, - publisher: { publish: async () => {} }, - }) - - const action: OverlayAction = { id: 'add-car', label: 'Adding...', timeoutMs: 50 } - - const start = Date.now() - const ack = await svc.startAction(action) - const elapsed = Date.now() - start - - expect(ack.status).toBe('tentative') - expect(ack.id).toBe('add-car') - expect(elapsed).toBeGreaterThanOrEqual(40) - }) -}) \ No newline at end of file diff --git a/core/automation/application/RecalculateChampionshipStandingsUseCase.test.ts b/core/automation/application/RecalculateChampionshipStandingsUseCase.test.ts deleted file mode 100644 index c7716be80..000000000 --- a/core/automation/application/RecalculateChampionshipStandingsUseCase.test.ts +++ /dev/null @@ -1,549 +0,0 @@ -import { describe, it, expect, beforeEach } from 'vitest'; - -import { RecalculateChampionshipStandingsUseCase } from '@core/racing/application/use-cases/RecalculateChampionshipStandingsUseCase'; -import type { ISeasonRepository } from '@core/racing/domain/repositories/ISeasonRepository'; -import type { ILeagueScoringConfigRepository } from '@core/racing/domain/repositories/ILeagueScoringConfigRepository'; -import type { IRaceRepository } from '@core/racing/domain/repositories/IRaceRepository'; -import type { IResultRepository } from '@core/racing/domain/repositories/IResultRepository'; -import type { IPenaltyRepository } from '@core/racing/domain/repositories/IPenaltyRepository'; -import type { IChampionshipStandingRepository } from '@core/racing/domain/repositories/IChampionshipStandingRepository'; - -import { Season } from '@core/racing/domain/entities/Season'; -import type { LeagueScoringConfig } from '@core/racing/domain/entities/LeagueScoringConfig'; -import { Race } from '@core/racing/domain/entities/Race'; -import { Result } from '@core/racing/domain/entities/Result'; -import type { Penalty } from '@core/racing/domain/entities/Penalty'; -import type { ChampionshipStanding } from '@core/racing/domain/entities/ChampionshipStanding'; -import type { ChampionshipConfig } from '@core/racing/domain/types/ChampionshipConfig'; -import { EventScoringService } from '@core/racing/domain/services/EventScoringService'; -import { DropScoreApplier } from '@core/racing/domain/services/DropScoreApplier'; -import { ChampionshipAggregator } from '@core/racing/domain/services/ChampionshipAggregator'; -import { PointsTable } from '@core/racing/domain/value-objects/PointsTable'; -import type { SessionType } from '@core/racing/domain/types/SessionType'; -import type { BonusRule } from '@core/racing/domain/types/BonusRule'; -import type { DropScorePolicy } from '@core/racing/domain/types/DropScorePolicy'; - -class InMemorySeasonRepository implements ISeasonRepository { - private seasons: Season[] = []; - - async findById(id: string): Promise { - return this.seasons.find((s) => s.id === id) || null; - } - - async findByLeagueId(leagueId: string): Promise { - return this.seasons.filter((s) => s.leagueId === leagueId); - } - - async create(season: Season): Promise { - this.seasons.push(season); - return season; - } - - async add(season: Season): Promise { - this.seasons.push(season); - } - - async update(season: Season): Promise { - const index = this.seasons.findIndex((s) => s.id === season.id); - if (index >= 0) { - this.seasons[index] = season; - } - } - - async listByLeague(leagueId: string): Promise { - return this.seasons.filter((s) => s.leagueId === leagueId); - } - - async listActiveByLeague(leagueId: string): Promise { - return this.seasons.filter((s) => s.leagueId === leagueId && s.status === 'active'); - } - - seedSeason(season: Season): void { - this.seasons.push(season); - } -} - -class InMemoryLeagueScoringConfigRepository implements ILeagueScoringConfigRepository { - private configs: LeagueScoringConfig[] = []; - - async findBySeasonId(seasonId: string): Promise { - return this.configs.find((c) => c.seasonId === seasonId) || null; - } - - async save(config: LeagueScoringConfig): Promise { - const index = this.configs.findIndex((c) => c.id === config.id); - if (index >= 0) { - this.configs[index] = config; - } else { - this.configs.push(config); - } - return config; - } - - seedConfig(config: LeagueScoringConfig): void { - this.configs.push(config); - } -} - -class InMemoryRaceRepository implements IRaceRepository { - private races: Race[] = []; - - async findById(id: string): Promise { - return this.races.find((r) => r.id === id) || null; - } - - async findAll(): Promise { - return [...this.races]; - } - - async findByLeagueId(leagueId: string): Promise { - return this.races.filter((r) => r.leagueId === leagueId); - } - - async findUpcomingByLeagueId(): Promise { - return []; - } - - async findCompletedByLeagueId(): Promise { - return []; - } - - async findByStatus(): Promise { - return []; - } - - async findByDateRange(): Promise { - return []; - } - - async create(race: Race): Promise { - this.races.push(race); - return race; - } - - async update(race: Race): Promise { - const index = this.races.findIndex((r) => r.id === race.id); - if (index >= 0) { - this.races[index] = race; - } else { - this.races.push(race); - } - return race; - } - - async delete(id: string): Promise { - this.races = this.races.filter((r) => r.id !== id); - } - - async exists(id: string): Promise { - return this.races.some((r) => r.id === id); - } - - seedRace(race: Race): void { - this.races.push(race); - } -} - -class InMemoryResultRepository implements IResultRepository { - private results: Result[] = []; - - async findById(id: string): Promise { - return this.results.find((r) => r.id === id) || null; - } - - async findAll(): Promise { - return [...this.results]; - } - - async findByRaceId(raceId: string): Promise { - return this.results.filter((r) => r.raceId === raceId); - } - - async findByDriverId(driverId: string): Promise { - return this.results.filter((r) => r.driverId === driverId); - } - - async findByDriverIdAndLeagueId(driverId: string, leagueId: string): Promise { - return this.results.filter((r) => r.driverId === driverId && r.raceId.startsWith(leagueId)); - } - - async create(result: Result): Promise { - this.results.push(result); - return result; - } - - async createMany(results: Result[]): Promise { - this.results.push(...results); - return results; - } - - async update(result: Result): Promise { - const index = this.results.findIndex((r) => r.id === result.id); - if (index >= 0) { - this.results[index] = result; - } - return result; - } - - async delete(id: string): Promise { - this.results = this.results.filter((r) => r.id !== id); - } - - async deleteByRaceId(raceId: string): Promise { - this.results = this.results.filter((r) => r.raceId !== raceId); - } - - async exists(id: string): Promise { - return this.results.some((r) => r.id === id); - } - - async existsByRaceId(raceId: string): Promise { - return this.results.some((r) => r.raceId === raceId); - } - - seedResult(result: Result): void { - this.results.push(result); - } -} - -class InMemoryPenaltyRepository implements IPenaltyRepository { - private penalties: Penalty[] = []; - - async findByRaceId(raceId: string): Promise { - return this.penalties.filter((p) => p.raceId === raceId); - } - - async findByLeagueId(leagueId: string): Promise { - return this.penalties.filter((p) => p.leagueId === leagueId); - } - - async findByLeagueIdAndDriverId( - leagueId: string, - driverId: string, - ): Promise { - return this.penalties.filter( - (p) => p.leagueId === leagueId && p.driverId === driverId, - ); - } - - async findAll(): Promise { - return [...this.penalties]; - } - - async findById(id: string): Promise { - return this.penalties.find((p) => p.id === id) || null; - } - - async findByDriverId(driverId: string): Promise { - return this.penalties.filter((p) => p.driverId === driverId); - } - - async findByProtestId(protestId: string): Promise { - return this.penalties.filter((p) => p.protestId === protestId); - } - - async findPending(): Promise { - return this.penalties.filter((p) => p.status === 'pending'); - } - - async findIssuedBy(stewardId: string): Promise { - return this.penalties.filter((p) => p.issuedBy === stewardId); - } - - async create(penalty: Penalty): Promise { - this.penalties.push(penalty); - } - - async update(penalty: Penalty): Promise { - const index = this.penalties.findIndex((p) => p.id === penalty.id); - if (index >= 0) { - this.penalties[index] = penalty; - } - } - - async exists(id: string): Promise { - return this.penalties.some((p) => p.id === id); - } - - seedPenalty(penalty: Penalty): void { - this.penalties.push(penalty); - } -} - -class InMemoryChampionshipStandingRepository implements IChampionshipStandingRepository { - private standings: ChampionshipStanding[] = []; - - async findBySeasonAndChampionship( - seasonId: string, - championshipId: string, - ): Promise { - return this.standings.filter( - (s) => s.seasonId === seasonId && s.championshipId === championshipId, - ); - } - - async saveAll(standings: ChampionshipStanding[]): Promise { - this.standings = standings; - } - - getAll(): ChampionshipStanding[] { - return [...this.standings]; - } -} - -function makePointsTable(points: number[]): PointsTable { - const byPos: Record = {}; - points.forEach((p, idx) => { - byPos[idx + 1] = p; - }); - return new PointsTable(byPos); -} - -function makeChampionshipConfig(): ChampionshipConfig { - const mainPoints = makePointsTable([25, 18, 15, 12, 10, 8, 6, 4, 2, 1]); - const sprintPoints = makePointsTable([8, 7, 6, 5, 4, 3, 2, 1]); - - const fastestLapBonus: BonusRule = { - id: 'fastest-lap-main', - type: 'fastestLap', - points: 1, - requiresFinishInTopN: 10, - }; - - const sessionTypes: SessionType[] = ['sprint', 'main']; - const pointsTableBySessionType: Record = { - sprint: sprintPoints, - main: mainPoints, - practice: new PointsTable({}), - qualifying: new PointsTable({}), - q1: new PointsTable({}), - q2: new PointsTable({}), - q3: new PointsTable({}), - timeTrial: new PointsTable({}), - }; - - const bonusRulesBySessionType: Record = { - sprint: [], - main: [fastestLapBonus], - practice: [], - qualifying: [], - q1: [], - q2: [], - q3: [], - timeTrial: [], - }; - - const dropScorePolicy: DropScorePolicy = { - strategy: 'bestNResults', - count: 6, - }; - - return { - id: 'driver-champ', - name: 'Driver Championship', - type: 'driver', - sessionTypes, - pointsTableBySessionType, - bonusRulesBySessionType, - dropScorePolicy, - }; -} - -describe('RecalculateChampionshipStandingsUseCase', () => { - const leagueId = 'league-1'; - const seasonId = 'season-1'; - const championshipId = 'driver-champ'; - - let seasonRepository: InMemorySeasonRepository; - let leagueScoringConfigRepository: InMemoryLeagueScoringConfigRepository; - let raceRepository: InMemoryRaceRepository; - let resultRepository: InMemoryResultRepository; - let penaltyRepository: InMemoryPenaltyRepository; - let championshipStandingRepository: InMemoryChampionshipStandingRepository; - - let useCase: RecalculateChampionshipStandingsUseCase; - - beforeEach(() => { - seasonRepository = new InMemorySeasonRepository(); - leagueScoringConfigRepository = new InMemoryLeagueScoringConfigRepository(); - raceRepository = new InMemoryRaceRepository(); - resultRepository = new InMemoryResultRepository(); - penaltyRepository = new InMemoryPenaltyRepository(); - championshipStandingRepository = new InMemoryChampionshipStandingRepository(); - - const eventScoringService = new EventScoringService(); - const dropScoreApplier = new DropScoreApplier(); - const championshipAggregator = new ChampionshipAggregator(dropScoreApplier); - - useCase = new RecalculateChampionshipStandingsUseCase( - seasonRepository, - leagueScoringConfigRepository, - raceRepository, - resultRepository, - penaltyRepository, - championshipStandingRepository, - eventScoringService, - championshipAggregator, - ); - - const season = Season.create({ - id: seasonId, - leagueId, - gameId: 'iracing', - name: 'Demo Season', - status: 'active', - year: 2025, - order: 1, - startDate: new Date('2025-01-01'), - endDate: new Date('2025-12-31'), - }); - - seasonRepository.seedSeason(season); - - const championship = makeChampionshipConfig(); - - const leagueScoringConfig: LeagueScoringConfig = { - id: 'lsc-1', - seasonId, - championships: [championship], - }; - - leagueScoringConfigRepository.seedConfig(leagueScoringConfig); - - const races: Race[] = [ - Race.create({ - id: 'race-1-sprint', - leagueId, - scheduledAt: new Date('2025-02-01'), - track: 'Track 1', - car: 'Car A', - sessionType: 'race', - status: 'completed', - }), - Race.create({ - id: 'race-1-main', - leagueId, - scheduledAt: new Date('2025-02-01'), - track: 'Track 1', - car: 'Car A', - sessionType: 'race', - status: 'completed', - }), - Race.create({ - id: 'race-2-sprint', - leagueId, - scheduledAt: new Date('2025-03-01'), - track: 'Track 2', - car: 'Car A', - sessionType: 'race', - status: 'completed', - }), - Race.create({ - id: 'race-2-main', - leagueId, - scheduledAt: new Date('2025-03-01'), - track: 'Track 2', - car: 'Car A', - sessionType: 'race', - status: 'completed', - }), - Race.create({ - id: 'race-3-sprint', - leagueId, - scheduledAt: new Date('2025-04-01'), - track: 'Track 3', - car: 'Car A', - sessionType: 'race', - status: 'completed', - }), - Race.create({ - id: 'race-3-main', - leagueId, - scheduledAt: new Date('2025-04-01'), - track: 'Track 3', - car: 'Car A', - sessionType: 'race', - status: 'completed', - }), - ]; - - races.forEach((race) => raceRepository.seedRace(race)); - - const _drivers = ['driver-1', 'driver-2', 'driver-3']; - - const resultsData: Array<{ - raceId: string; - finishingOrder: string[]; - fastestLapDriverId: string; - }> = [ - { - raceId: 'race-1-sprint', - finishingOrder: ['driver-1', 'driver-2', 'driver-3'], - fastestLapDriverId: 'driver-2', - }, - { - raceId: 'race-1-main', - finishingOrder: ['driver-2', 'driver-1', 'driver-3'], - fastestLapDriverId: 'driver-1', - }, - { - raceId: 'race-2-sprint', - finishingOrder: ['driver-1', 'driver-3', 'driver-2'], - fastestLapDriverId: 'driver-1', - }, - { - raceId: 'race-2-main', - finishingOrder: ['driver-1', 'driver-2', 'driver-3'], - fastestLapDriverId: 'driver-1', - }, - { - raceId: 'race-3-sprint', - finishingOrder: ['driver-2', 'driver-1', 'driver-3'], - fastestLapDriverId: 'driver-2', - }, - { - raceId: 'race-3-main', - finishingOrder: ['driver-3', 'driver-1', 'driver-2'], - fastestLapDriverId: 'driver-3', - }, - ]; - - let resultIdCounter = 1; - for (const raceData of resultsData) { - raceData.finishingOrder.forEach((driverId, index) => { - const result = Result.create({ - id: `result-${resultIdCounter++}`, - raceId: raceData.raceId, - driverId, - position: index + 1, - fastestLap: driverId === raceData.fastestLapDriverId ? 90000 : 91000 + index * 100, - incidents: 0, - startPosition: index + 1, - }); - resultRepository.seedResult(result); - }); - } - }); - - it('recalculates standings for a driver championship with sprint and main races', async () => { - const dto = await useCase.execute({ - seasonId, - championshipId, - }); - - expect(dto.seasonId).toBe(seasonId); - expect(dto.championshipId).toBe(championshipId); - expect(dto.championshipName).toBe('Driver Championship'); - expect(dto.rows.length).toBeGreaterThan(0); - - const rows = dto.rows; - const sorted = [...rows].sort((a, b) => b.totalPoints - a.totalPoints); - expect(rows.map((r) => r.participant.id)).toEqual( - sorted.map((r) => r.participant.id), - ); - - const leader = rows[0]!; - expect(leader.resultsCounted).toBeLessThanOrEqual(6); - expect(leader.resultsDropped).toBeGreaterThanOrEqual(0); - }); -}); \ No newline at end of file diff --git a/core/automation/application/ports/ILogger.ts b/core/automation/application/ports/ILogger.ts deleted file mode 100644 index 83540b86a..000000000 --- a/core/automation/application/ports/ILogger.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface Logger { - debug(message: string, context?: Record): void; - info(message: string, context?: Record): void; - warn(message: string, context?: Record): void; - error(message: string, error?: Error, context?: Record): void; - verbose?(message: string, context?: Record): void; -} diff --git a/core/automation/domain/services/StepTransitionValidator.test.ts b/core/automation/domain/services/StepTransitionValidator.test.ts deleted file mode 100644 index 17718121e..000000000 --- a/core/automation/domain/services/StepTransitionValidator.test.ts +++ /dev/null @@ -1,231 +0,0 @@ -import { describe, it, expect } from 'vitest'; -import { StepTransitionValidator } from '@core/automation/domain/services/StepTransitionValidator'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; - - -describe('StepTransitionValidator Service', () => { - describe('canTransition', () => { - it('should allow sequential forward transition', () => { - const currentStep = StepId.create(1); - const nextStep = StepId.create(2); - const state = SessionState.create('IN_PROGRESS'); - - const result = StepTransitionValidator.canTransition(currentStep, nextStep, state); - - expect(result.isValid).toBe(true); - expect(result.error).toBeUndefined(); - }); - - it('should reject transition when not IN_PROGRESS', () => { - const currentStep = StepId.create(1); - const nextStep = StepId.create(2); - const state = SessionState.create('PENDING'); - - const result = StepTransitionValidator.canTransition(currentStep, nextStep, state); - - expect(result.isValid).toBe(false); - expect(result.error).toBe('Session must be in progress to transition steps'); - }); - - it('should reject skipping steps', () => { - const currentStep = StepId.create(1); - const nextStep = StepId.create(3); - const state = SessionState.create('IN_PROGRESS'); - - const result = StepTransitionValidator.canTransition(currentStep, nextStep, state); - - expect(result.isValid).toBe(false); - expect(result.error).toBe('Cannot skip steps - must progress sequentially'); - }); - - it('should reject backward transitions', () => { - const currentStep = StepId.create(5); - const nextStep = StepId.create(4); - const state = SessionState.create('IN_PROGRESS'); - - const result = StepTransitionValidator.canTransition(currentStep, nextStep, state); - - expect(result.isValid).toBe(false); - expect(result.error).toBe('Cannot move backward - steps must progress forward only'); - }); - - it('should reject same step transition', () => { - const currentStep = StepId.create(5); - const nextStep = StepId.create(5); - const state = SessionState.create('IN_PROGRESS'); - - const result = StepTransitionValidator.canTransition(currentStep, nextStep, state); - - expect(result.isValid).toBe(false); - expect(result.error).toBe('Already at this step'); - }); - - it('should allow transition through modal steps', () => { - const currentStep = StepId.create(5); - const nextStep = StepId.create(6); - const state = SessionState.create('IN_PROGRESS'); - - const result = StepTransitionValidator.canTransition(currentStep, nextStep, state); - - expect(result.isValid).toBe(true); - }); - - it('should allow transition from modal step to next', () => { - const currentStep = StepId.create(6); - const nextStep = StepId.create(7); - const state = SessionState.create('IN_PROGRESS'); - - const result = StepTransitionValidator.canTransition(currentStep, nextStep, state); - - expect(result.isValid).toBe(true); - }); - }); - - describe('validateModalStepTransition', () => { - it('should allow entering modal step 6', () => { - const currentStep = StepId.create(5); - const nextStep = StepId.create(6); - - const result = StepTransitionValidator.validateModalStepTransition(currentStep, nextStep); - - expect(result.isValid).toBe(true); - }); - - it('should allow entering modal step 9', () => { - const currentStep = StepId.create(8); - const nextStep = StepId.create(9); - - const result = StepTransitionValidator.validateModalStepTransition(currentStep, nextStep); - - expect(result.isValid).toBe(true); - }); - - it('should allow entering modal step 12', () => { - const currentStep = StepId.create(11); - const nextStep = StepId.create(12); - - const result = StepTransitionValidator.validateModalStepTransition(currentStep, nextStep); - - expect(result.isValid).toBe(true); - }); - - it('should allow exiting modal step 6', () => { - const currentStep = StepId.create(6); - const nextStep = StepId.create(7); - - const result = StepTransitionValidator.validateModalStepTransition(currentStep, nextStep); - - expect(result.isValid).toBe(true); - }); - - it('should allow non-modal transitions', () => { - const currentStep = StepId.create(1); - const nextStep = StepId.create(2); - - const result = StepTransitionValidator.validateModalStepTransition(currentStep, nextStep); - - expect(result.isValid).toBe(true); - }); - }); - - describe('shouldStopAtStep18', () => { - it('should return true when transitioning to step 17 (final step)', () => { - const nextStep = StepId.create(17); - - const shouldStop = StepTransitionValidator.shouldStopAtStep18(nextStep); - - expect(shouldStop).toBe(true); - }); - - it('should return false for steps before 17', () => { - const nextStep = StepId.create(16); - - const shouldStop = StepTransitionValidator.shouldStopAtStep18(nextStep); - - expect(shouldStop).toBe(false); - }); - - it('should return false for early steps', () => { - const nextStep = StepId.create(1); - - const shouldStop = StepTransitionValidator.shouldStopAtStep18(nextStep); - - expect(shouldStop).toBe(false); - }); - }); - - describe('getStepDescription', () => { - it('should return description for step 1', () => { - const step = StepId.create(1); - - const description = StepTransitionValidator.getStepDescription(step); - - expect(description).toBe('Navigate to Hosted Racing page'); - }); - - it('should return description for step 6 (modal)', () => { - const step = StepId.create(6); - - const description = StepTransitionValidator.getStepDescription(step); - - expect(description).toBe('Add Admin (Modal)'); - }); - - it('should return description for step 17 (final)', () => { - const step = StepId.create(17); - - const description = StepTransitionValidator.getStepDescription(step); - - expect(description).toBe('Track Conditions (STOP - Manual Submit Required)'); - }); - - it('should return descriptions for all modal steps', () => { - const modalSteps = [6, 9, 12]; - - modalSteps.forEach(stepNum => { - const step = StepId.create(stepNum); - const description = StepTransitionValidator.getStepDescription(step); - expect(description).toContain('(Modal)'); - }); - }); - }); - - describe('edge cases', () => { - it('should handle rapid sequential transitions', () => { - const state = SessionState.create('IN_PROGRESS'); - let currentStep = StepId.create(1); - - for (let i = 2; i <= 17; i++) { - const nextStep = StepId.create(i); - const result = StepTransitionValidator.canTransition(currentStep, nextStep, state); - - expect(result.isValid).toBe(true); - currentStep = nextStep; - } - }); - - it('should prevent transitions from terminal states', () => { - const terminalStates = ['COMPLETED', 'FAILED', 'STOPPED_AT_STEP_18'] as const; - - terminalStates.forEach(stateValue => { - const currentStep = StepId.create(10); - const nextStep = StepId.create(11); - const state = SessionState.create(stateValue); - - const result = StepTransitionValidator.canTransition(currentStep, nextStep, state); - - expect(result.isValid).toBe(false); - }); - }); - - it('should allow transition from PAUSED when resumed', () => { - const currentStep = StepId.create(5); - const nextStep = StepId.create(6); - const state = SessionState.create('IN_PROGRESS'); - - const result = StepTransitionValidator.canTransition(currentStep, nextStep, state); - - expect(result.isValid).toBe(true); - }); - }); -}); \ No newline at end of file diff --git a/tests/e2e/automation.e2e.test.ts b/tests/e2e/automation.e2e.test.ts index 55ea0aa22..5b8910f35 100644 --- a/tests/e2e/automation.e2e.test.ts +++ b/tests/e2e/automation.e2e.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; import { FixtureServer, PlaywrightAutomationAdapter, diff --git a/tests/e2e/companion/companion-ui-full-workflow.e2e.test.ts b/tests/e2e/companion/companion-ui-full-workflow.e2e.test.ts index 23fe0b04b..5a3cb7013 100644 --- a/tests/e2e/companion/companion-ui-full-workflow.e2e.test.ts +++ b/tests/e2e/companion/companion-ui-full-workflow.e2e.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { DIContainer } from '../../../apps/companion/main/di-container'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; -import type { HostedSessionConfig } from '@core/automation/domain/types/HostedSessionConfig'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; +import type { HostedSessionConfig } from 'apps/companion/main/automation/domain/types/HostedSessionConfig'; import { PlaywrightAutomationAdapter } from 'core/automation/infrastructure//automation'; describe('Companion UI - hosted workflow via fixture-backed real stack', () => { diff --git a/tests/e2e/hosted-real/cars-flow.real.e2e.test.ts b/tests/e2e/hosted-real/cars-flow.real.e2e.test.ts index 259fba390..66e6e17e4 100644 --- a/tests/e2e/hosted-real/cars-flow.real.e2e.test.ts +++ b/tests/e2e/hosted-real/cars-flow.real.e2e.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; import { PlaywrightAutomationAdapter, } from 'core/automation/infrastructure//automation'; diff --git a/tests/e2e/hosted-real/login-and-wizard-smoke.e2e.test.ts b/tests/e2e/hosted-real/login-and-wizard-smoke.e2e.test.ts index 67d84268e..97c4d8cf9 100644 --- a/tests/e2e/hosted-real/login-and-wizard-smoke.e2e.test.ts +++ b/tests/e2e/hosted-real/login-and-wizard-smoke.e2e.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; import { PlaywrightAutomationAdapter, } from 'core/automation/infrastructure//automation'; diff --git a/tests/e2e/hosted-real/step-03-race-information.real.e2e.test.ts b/tests/e2e/hosted-real/step-03-race-information.real.e2e.test.ts index ed307efea..d743db020 100644 --- a/tests/e2e/hosted-real/step-03-race-information.real.e2e.test.ts +++ b/tests/e2e/hosted-real/step-03-race-information.real.e2e.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, beforeAll, afterAll } from 'vitest'; import { promises as fs } from 'fs'; import path from 'path'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; import { PlaywrightAutomationAdapter, } from 'core/automation/infrastructure//automation'; diff --git a/tests/e2e/steps/step-17-team-driving.e2e.test.ts b/tests/e2e/steps/step-17-team-driving.e2e.test.ts index 159f6d951..d8b4a0eee 100644 --- a/tests/e2e/steps/step-17-team-driving.e2e.test.ts +++ b/tests/e2e/steps/step-17-team-driving.e2e.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import type { StepHarness } from '../support/StepHarness'; import { createStepHarness } from '../support/StepHarness'; -import { CheckoutConfirmation } from '@core/automation/domain/value-objects/CheckoutConfirmation'; +import { CheckoutConfirmation } from 'apps/companion/main/automation/domain/value-objects/CheckoutConfirmation'; describe('Step 17 – team driving', () => { let harness: StepHarness; diff --git a/tests/e2e/support/AutoNavGuard.ts b/tests/e2e/support/AutoNavGuard.ts index d495f97ab..1e921012c 100644 --- a/tests/e2e/support/AutoNavGuard.ts +++ b/tests/e2e/support/AutoNavGuard.ts @@ -1,6 +1,6 @@ -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; import type { PlaywrightAutomationAdapter } from 'core/automation/infrastructure//automation'; -import type { AutomationResult } from 'core/automation/application/ports/AutomationResults'; +import type { AutomationResult } from 'apps/companion/main/automation/application/ports/AutomationResults'; export function assertAutoNavigationConfig(config: Record): void { const skipFixtureNavigationFlag = diff --git a/tests/e2e/support/StepHarness.ts b/tests/e2e/support/StepHarness.ts index c5140e898..229fb63f6 100644 --- a/tests/e2e/support/StepHarness.ts +++ b/tests/e2e/support/StepHarness.ts @@ -1,5 +1,5 @@ -import type { AutomationResult } from 'core/automation/application/ports/AutomationResults'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import type { AutomationResult } from 'apps/companion/main/automation/application/ports/AutomationResults'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; import { PlaywrightAutomationAdapter, FixtureServer, diff --git a/tests/e2e/validators/hosted-validator-guards.e2e.test.ts b/tests/e2e/validators/hosted-validator-guards.e2e.test.ts index 0c12d9b19..ec85286d5 100644 --- a/tests/e2e/validators/hosted-validator-guards.e2e.test.ts +++ b/tests/e2e/validators/hosted-validator-guards.e2e.test.ts @@ -3,7 +3,7 @@ import { PlaywrightAutomationAdapter, FixtureServer, } from 'core/automation/infrastructure//automation'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; import { PinoLogAdapter } from 'core/automation/infrastructure//logging/PinoLogAdapter'; import { executeStepWithAutoNavigationGuard } from '../support/AutoNavGuard'; diff --git a/tests/e2e/workflows/full-hosted-session.autonav.workflow.e2e.test.ts b/tests/e2e/workflows/full-hosted-session.autonav.workflow.e2e.test.ts index ec10fe289..63bedd527 100644 --- a/tests/e2e/workflows/full-hosted-session.autonav.workflow.e2e.test.ts +++ b/tests/e2e/workflows/full-hosted-session.autonav.workflow.e2e.test.ts @@ -3,7 +3,7 @@ import { PlaywrightAutomationAdapter, FixtureServer, } from 'core/automation/infrastructure//automation'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; import { PinoLogAdapter } from 'core/automation/infrastructure//logging/PinoLogAdapter'; import { IRACING_SELECTORS } from 'core/automation/infrastructure//automation/dom/IRacingSelectors'; import { executeStepWithAutoNavigationGuard } from '../support/AutoNavGuard'; diff --git a/tests/e2e/workflows/full-hosted-session.workflow.e2e.test.ts b/tests/e2e/workflows/full-hosted-session.workflow.e2e.test.ts index 5d8057978..b8e527f76 100644 --- a/tests/e2e/workflows/full-hosted-session.workflow.e2e.test.ts +++ b/tests/e2e/workflows/full-hosted-session.workflow.e2e.test.ts @@ -3,10 +3,10 @@ import { PlaywrightAutomationAdapter, FixtureServer, } from 'core/automation/infrastructure//automation'; -import { InMemorySessionRepository } from 'core/automation/infrastructure/repositories/InMemorySessionRepository'; +import { InMemorySessionRepository } from 'apps/companion/main/automation/infrastructure/repositories/InMemorySessionRepository'; import { AutomationEngineAdapter } from 'core/automation/infrastructure//automation/engine/AutomationEngineAdapter'; -import { StartAutomationSessionUseCase } from 'core/automation/application/use-cases/StartAutomationSessionUseCase'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import { StartAutomationSessionUseCase } from 'apps/companion/main/automation/application/use-cases/StartAutomationSessionUseCase'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; import { PinoLogAdapter } from 'core/automation/infrastructure//logging/PinoLogAdapter'; describe('Workflow – hosted session end-to-end (fixture-backed, real stack)', () => { diff --git a/tests/e2e/workflows/steps-07-09-cars-flow.e2e.test.ts b/tests/e2e/workflows/steps-07-09-cars-flow.e2e.test.ts index c89df345a..ff6804b13 100644 --- a/tests/e2e/workflows/steps-07-09-cars-flow.e2e.test.ts +++ b/tests/e2e/workflows/steps-07-09-cars-flow.e2e.test.ts @@ -3,7 +3,7 @@ import { PlaywrightAutomationAdapter, FixtureServer, } from 'core/automation/infrastructure//automation'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; import { IRACING_SELECTORS } from 'core/automation/infrastructure//automation/dom/IRacingSelectors'; import { PinoLogAdapter } from 'core/automation/infrastructure//logging/PinoLogAdapter'; diff --git a/tests/integration/infrastructure/BrowserModeIntegration.test.ts b/tests/integration/infrastructure/BrowserModeIntegration.test.ts index 1aa400a31..0c0a5ca62 100644 --- a/tests/integration/infrastructure/BrowserModeIntegration.test.ts +++ b/tests/integration/infrastructure/BrowserModeIntegration.test.ts @@ -1,8 +1,8 @@ import { describe, it, expect, beforeEach, afterEach, beforeAll, afterAll } from 'vitest'; import * as fs from 'fs'; import * as path from 'path'; -import type { LoggerPort } from '@core/automation/application/ports/LoggerPort'; -import type { LogContext } from '@core/automation/application/ports/LoggerContext'; +import type { LoggerPort } from 'apps/companion/main/automation/application/ports/LoggerPort'; +import type { LogContext } from 'apps/companion/main/automation/application/ports/LoggerContext'; /** * Integration tests for Browser Mode in PlaywrightAutomationAdapter - GREEN PHASE @@ -293,7 +293,7 @@ describe('Browser Mode Integration - GREEN Phase', () => { 'core/automation/infrastructure//automation' ); const { BrowserModeConfigLoader } = await import( - '../../../core/automation/infrastructure/config/BrowserModeConfig' + '../../../apps/companion/main/automation/infrastructure/config/BrowserModeConfig' ); // Create loader and set to headed diff --git a/tests/integration/infrastructure/CheckoutPriceExtractor.test.ts b/tests/integration/infrastructure/CheckoutPriceExtractor.test.ts index eb72b1ee0..12264c18b 100644 --- a/tests/integration/infrastructure/CheckoutPriceExtractor.test.ts +++ b/tests/integration/infrastructure/CheckoutPriceExtractor.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, beforeEach, vi } from 'vitest'; import { Result } from '../../../core/shared/result/Result'; -import { CheckoutPriceExtractor } from '../../../core/automation/infrastructure//automation/CheckoutPriceExtractor'; -import { CheckoutStateEnum } from '@core/automation/domain/value-objects/CheckoutState'; +import { CheckoutPriceExtractor } from '../../../apps/companion/main/automation/infrastructure/automation/CheckoutPriceExtractor'; +import { CheckoutStateEnum } from 'apps/companion/main/automation/domain/value-objects/CheckoutState'; /** * CheckoutPriceExtractor Integration Tests - GREEN PHASE diff --git a/tests/integration/infrastructure/InMemorySessionRepository.test.ts b/tests/integration/infrastructure/InMemorySessionRepository.test.ts index d67003e77..15521bc25 100644 --- a/tests/integration/infrastructure/InMemorySessionRepository.test.ts +++ b/tests/integration/infrastructure/InMemorySessionRepository.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, beforeEach } from 'vitest'; -import { InMemorySessionRepository } from '../../../core/automation/infrastructure/repositories/InMemorySessionRepository'; -import { AutomationSession } from '@core/automation/domain/entities/AutomationSession'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import { InMemorySessionRepository } from '../../../apps/companion/main/automation/infrastructure/repositories/InMemorySessionRepository'; +import { AutomationSession } from 'apps/companion/main/automation/domain/entities/AutomationSession'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; describe('InMemorySessionRepository Integration Tests', () => { let repository: InMemorySessionRepository; diff --git a/tests/integration/infrastructure/MockBrowserAutomationAdapter.test.ts b/tests/integration/infrastructure/MockBrowserAutomationAdapter.test.ts index 93ce78f9a..7dacd66f3 100644 --- a/tests/integration/infrastructure/MockBrowserAutomationAdapter.test.ts +++ b/tests/integration/infrastructure/MockBrowserAutomationAdapter.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { MockBrowserAutomationAdapter } from 'core/automation/infrastructure//automation'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; describe('MockBrowserAutomationAdapter Integration Tests', () => { let adapter: MockBrowserAutomationAdapter; diff --git a/tests/integration/infrastructure/automation/OverlayLifecycle.integration.test.ts b/tests/integration/infrastructure/automation/OverlayLifecycle.integration.test.ts index 76618da71..fe942ca27 100644 --- a/tests/integration/infrastructure/automation/OverlayLifecycle.integration.test.ts +++ b/tests/integration/infrastructure/automation/OverlayLifecycle.integration.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect } from 'vitest'; -import { OverlaySyncService } from 'core/automation/application/services/OverlaySyncService'; -import type { AutomationEvent } from 'core/automation/application/ports/IAutomationEventPublisher'; +import { OverlaySyncService } from 'apps/companion/main/automation/application/services/OverlaySyncService'; +import type { AutomationEvent } from 'apps/companion/main/automation/application/ports/IAutomationEventPublisher'; import type { IAutomationLifecycleEmitter, LifecycleCallback, @@ -8,7 +8,7 @@ import type { import type { OverlayAction, ActionAck, -} from 'core/automation/application/ports/IOverlaySyncPort'; +} from 'apps/companion/main/automation/application/ports/IOverlaySyncPort'; class TestLifecycleEmitter implements IAutomationLifecycleEmitter { private callbacks: Set = new Set(); diff --git a/tests/integration/infrastructure/automation/ValidatorConformance.integration.test.ts b/tests/integration/infrastructure/automation/ValidatorConformance.integration.test.ts index 065ae6e50..7fcddc009 100644 --- a/tests/integration/infrastructure/automation/ValidatorConformance.integration.test.ts +++ b/tests/integration/infrastructure/automation/ValidatorConformance.integration.test.ts @@ -1,8 +1,8 @@ import { describe, it, expect } from 'vitest'; -import { PageStateValidator } from '@core/automation/domain/services/PageStateValidator'; -import { StepTransitionValidator } from '@core/automation/domain/services/StepTransitionValidator'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; -import { SessionState } from '@core/automation/domain/value-objects/SessionState'; +import { PageStateValidator } from 'apps/companion/main/automation/domain/services/PageStateValidator'; +import { StepTransitionValidator } from 'apps/companion/main/automation/domain/services/StepTransitionValidator'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; +import { SessionState } from 'apps/companion/main/automation/domain/value-objects/SessionState'; describe('Validator conformance (integration)', () => { describe('PageStateValidator with hosted-session selectors', () => { diff --git a/tests/integration/interface/companion/companion-start-automation.browser-mode-refresh.integration.test.ts b/tests/integration/interface/companion/companion-start-automation.browser-mode-refresh.integration.test.ts index ebcfb88f8..ee81d0963 100644 --- a/tests/integration/interface/companion/companion-start-automation.browser-mode-refresh.integration.test.ts +++ b/tests/integration/interface/companion/companion-start-automation.browser-mode-refresh.integration.test.ts @@ -1,8 +1,8 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { DIContainer } from '../../../..//apps/companion/main/di-container'; -import type { HostedSessionConfig } from '@core/automation/domain/types/HostedSessionConfig'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; -import { PlaywrightAutomationAdapter } from '../../../..//core/automation/infrastructure//automation'; +import type { HostedSessionConfig } from 'apps/companion/main/automation/domain/types/HostedSessionConfig'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; +import { PlaywrightAutomationAdapter } from '../../../../apps/companion/main/automation/infrastructure/automation'; describe('companion start automation - browser mode refresh wiring', () => { const originalEnv = { ...process.env }; diff --git a/tests/integration/interface/companion/companion-start-automation.browser-not-connected.integration.test.ts b/tests/integration/interface/companion/companion-start-automation.browser-not-connected.integration.test.ts index 2f19cab8d..6313cac4f 100644 --- a/tests/integration/interface/companion/companion-start-automation.browser-not-connected.integration.test.ts +++ b/tests/integration/interface/companion/companion-start-automation.browser-not-connected.integration.test.ts @@ -1,8 +1,8 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { DIContainer } from '../../../..//apps/companion/main/di-container'; -import type { HostedSessionConfig } from '@core/automation/domain/types/HostedSessionConfig'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; -import { PlaywrightAutomationAdapter } from '../../../..//core/automation/infrastructure//automation'; +import type { HostedSessionConfig } from 'apps/companion/main/automation/domain/types/HostedSessionConfig'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; +import { PlaywrightAutomationAdapter } from '../../../../apps/companion/main/automation/infrastructure/automation'; describe('companion start automation - browser not connected at step 1', () => { const originalEnv = { ...process.env }; diff --git a/tests/integration/interface/companion/companion-start-automation.connection-failure.integration.test.ts b/tests/integration/interface/companion/companion-start-automation.connection-failure.integration.test.ts index c49a0abb9..0fc1059fc 100644 --- a/tests/integration/interface/companion/companion-start-automation.connection-failure.integration.test.ts +++ b/tests/integration/interface/companion/companion-start-automation.connection-failure.integration.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { DIContainer } from '../../../..//apps/companion/main/di-container'; -import type { HostedSessionConfig } from '@core/automation/domain/types/HostedSessionConfig'; -import { PlaywrightAutomationAdapter } from '../../../..//core/automation/infrastructure//automation'; +import type { HostedSessionConfig } from 'apps/companion/main/automation/domain/types/HostedSessionConfig'; +import { PlaywrightAutomationAdapter } from '../../../../apps/companion/main/automation/infrastructure/automation'; describe('companion start automation - browser connection failure before steps', () => { const originalEnv = { ...process.env }; diff --git a/tests/integration/interface/companion/companion-start-automation.happy.integration.test.ts b/tests/integration/interface/companion/companion-start-automation.happy.integration.test.ts index cb718e5af..5e06e2328 100644 --- a/tests/integration/interface/companion/companion-start-automation.happy.integration.test.ts +++ b/tests/integration/interface/companion/companion-start-automation.happy.integration.test.ts @@ -1,7 +1,7 @@ import { describe, it, expect, beforeEach, afterEach } from 'vitest'; import { DIContainer } from '../../../..//apps/companion/main/di-container'; -import type { HostedSessionConfig } from '@core/automation/domain/types/HostedSessionConfig'; -import { StepId } from '@core/automation/domain/value-objects/StepId'; +import type { HostedSessionConfig } from 'apps/companion/main/automation/domain/types/HostedSessionConfig'; +import { StepId } from 'apps/companion/main/automation/domain/value-objects/StepId'; describe('companion start automation - happy path', () => { const originalEnv = { ...process.env }; diff --git a/tests/integration/interface/renderer/renderer-overlay-lifecycle.integration.test.ts b/tests/integration/interface/renderer/renderer-overlay-lifecycle.integration.test.ts index 72fefa366..aa7e16a77 100644 --- a/tests/integration/interface/renderer/renderer-overlay-lifecycle.integration.test.ts +++ b/tests/integration/interface/renderer/renderer-overlay-lifecycle.integration.test.ts @@ -1,8 +1,8 @@ import { describe, it, expect } from 'vitest'; import { MockAutomationLifecycleEmitter } from '../../../mocks/MockAutomationLifecycleEmitter'; -import { OverlaySyncService } from 'core/automation/application/services/OverlaySyncService'; -import type { AutomationEvent } from 'core/automation/application/ports/IAutomationEventPublisher'; -import type { OverlayAction } from 'core/automation/application/ports/IOverlaySyncPort'; +import { OverlaySyncService } from 'apps/companion/main/automation/application/services/OverlaySyncService'; +import type { AutomationEvent } from 'apps/companion/main/automation/application/ports/IAutomationEventPublisher'; +import type { OverlayAction } from 'apps/companion/main/automation/application/ports/IOverlaySyncPort'; type RendererOverlayState = | { status: 'idle' } diff --git a/tests/integration/interface/renderer/renderer-overlay.integration.test.ts b/tests/integration/interface/renderer/renderer-overlay.integration.test.ts index 3d372fa9f..442fc9ccf 100644 --- a/tests/integration/interface/renderer/renderer-overlay.integration.test.ts +++ b/tests/integration/interface/renderer/renderer-overlay.integration.test.ts @@ -1,6 +1,6 @@ import { describe, expect, test } from 'vitest' import { MockAutomationLifecycleEmitter } from '../../../mocks/MockAutomationLifecycleEmitter' -import { OverlaySyncService } from 'core/automation/application/services/OverlaySyncService' +import { OverlaySyncService } from 'apps/companion/main/automation/application/services/OverlaySyncService' describe('renderer overlay integration', () => { test('renderer shows confirmed only after main acks confirmed', async () => { diff --git a/tests/smoke/electron-init.smoke.test.ts b/tests/smoke/electron-init.smoke.test.ts index fbbc5c44a..e13a016fa 100644 --- a/tests/smoke/electron-init.smoke.test.ts +++ b/tests/smoke/electron-init.smoke.test.ts @@ -1,12 +1,12 @@ import { describe, it, expect, beforeEach, vi } from 'vitest'; import { DIContainer } from '@apps/companion/main/di-container'; -import { StartAutomationSessionUseCase } from '@core/automation/application/use-cases/StartAutomationSessionUseCase'; -import { CheckAuthenticationUseCase } from '@core/automation/application/use-cases/CheckAuthenticationUseCase'; -import { InitiateLoginUseCase } from '@core/automation/application/use-cases/InitiateLoginUseCase'; -import { ClearSessionUseCase } from '@core/automation/application/use-cases/ClearSessionUseCase'; -import { ConfirmCheckoutUseCase } from '@core/automation/application/use-cases/ConfirmCheckoutUseCase'; +import { StartAutomationSessionUseCase } from 'apps/companion/main/automation/application/use-cases/StartAutomationSessionUseCase'; +import { CheckAuthenticationUseCase } from 'apps/companion/main/automation/application/use-cases/CheckAuthenticationUseCase'; +import { InitiateLoginUseCase } from 'apps/companion/main/automation/application/use-cases/InitiateLoginUseCase'; +import { ClearSessionUseCase } from 'apps/companion/main/automation/application/use-cases/ClearSessionUseCase'; +import { ConfirmCheckoutUseCase } from 'apps/companion/main/automation/application/use-cases/ConfirmCheckoutUseCase'; import { PlaywrightAutomationAdapter } from 'core/automation/infrastructure//automation'; -import { InMemorySessionRepository } from '@core/automation/infrastructure/repositories/InMemorySessionRepository'; +import { InMemorySessionRepository } from 'apps/companion/main/automation/infrastructure/repositories/InMemorySessionRepository'; import { NoOpLogAdapter } from '@core/automation/infrastructure//logging/NoOpLogAdapter'; // Mock Electron's app module