rename to core
This commit is contained in:
@@ -38,10 +38,10 @@ Everything else from the concept docs (league/season management, result aggregat
|
||||
- React renderer: [`App`](apps/companion/renderer/App.tsx), UI components under [`components`](apps/companion/renderer/components).
|
||||
|
||||
- Automation & browser integration:
|
||||
- Domain models around hosted sessions and steps, e.g. [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1), [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1).
|
||||
- Application layer ports and use-cases, e.g. [`IAutomationEngine`](packages/application/ports/IAutomationEngine.ts:1), [`ISessionRepository`](packages/application/ports/ISessionRepository.ts:1), [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- Playwright-based automation adapter and helpers, e.g. [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1), [`CheckoutPriceExtractor`](packages/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1).
|
||||
- Logging, config and in-memory repository implementations, e.g. [`InMemorySessionRepository`](packages/infrastructure/repositories/InMemorySessionRepository.ts:1), [`AutomationConfig`](packages/infrastructure/config/AutomationConfig.ts:1), [`LoggingConfig`](packages/infrastructure/config/LoggingConfig.ts:1), [`PinoLogAdapter`](packages/infrastructure/adapters/logging/PinoLogAdapter.ts:1).
|
||||
- Domain models around hosted sessions and steps, e.g. [`AutomationSession`](core/domain/entities/AutomationSession.ts:1), [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1).
|
||||
- Application layer ports and use-cases, e.g. [`IAutomationEngine`](core/application/ports/IAutomationEngine.ts:1), [`ISessionRepository`](core/application/ports/ISessionRepository.ts:1), [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- Playwright-based automation adapter and helpers, e.g. [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1), [`CheckoutPriceExtractor`](core/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1).
|
||||
- Logging, config and in-memory repository implementations, e.g. [`InMemorySessionRepository`](core/infrastructure/repositories/InMemorySessionRepository.ts:1), [`AutomationConfig`](core/infrastructure/config/AutomationConfig.ts:1), [`LoggingConfig`](core/infrastructure/config/LoggingConfig.ts:1), [`PinoLogAdapter`](core/infrastructure/adapters/logging/PinoLogAdapter.ts:1).
|
||||
|
||||
- Testing:
|
||||
- Unit tests for domain, application and infrastructure.
|
||||
@@ -162,14 +162,14 @@ The website under [`apps/website`](apps/website:1) is the primary presentation s
|
||||
- Read standings, stats snapshots and rating values.
|
||||
- Submit registrations, complaints and admin actions.
|
||||
- Trigger or schedule result imports and (where allowed) automation runs.
|
||||
- These APIs are implemented by the platform application layer and are conceptually separate from the automation-specific ports in `packages/application`.
|
||||
- These APIs are implemented by the platform application layer and are conceptually separate from the automation-specific ports in `core/application`.
|
||||
|
||||
### 2.4 Platform Integration with Automation
|
||||
|
||||
The web platform uses the automation & companion subsystem as a hosted-session engine, without coupling to Playwright or Electron details:
|
||||
|
||||
- **From league/season data to automation intent**
|
||||
- The platform aggregates league configuration (series settings, car/track choices, schedule, server settings) and derives a hosted-session configuration structure conceptually equivalent to [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1).
|
||||
- The platform aggregates league configuration (series settings, car/track choices, schedule, server settings) and derives a hosted-session configuration structure conceptually equivalent to [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1).
|
||||
- This configuration captures the intent of a single hosted session (or a batch of sessions across a season) in a platform-neutral format.
|
||||
|
||||
- **Hand-off to automation**
|
||||
@@ -207,9 +207,9 @@ This section describes how the automation engine and companion in this repo sit
|
||||
|
||||
- **Automation Engine & Domain (this repo)**
|
||||
- Clean Architecture core for iRacing hosted-session automation:
|
||||
- Domain and value objects under [`packages/domain`](packages/domain/entities/AutomationSession.ts:1).
|
||||
- Application use-cases and ports under [`packages/application`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- Infrastructure adapters under [`packages/infrastructure`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1).
|
||||
- Domain and value objects under [`core/domain`](core/domain/entities/AutomationSession.ts:1).
|
||||
- Application use-cases and ports under [`core/application`](core/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- Infrastructure adapters under [`core/infrastructure`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1).
|
||||
- Exposes automation capabilities via application ports that can be used both by the companion and by external orchestrators.
|
||||
|
||||
- **iRacing Web (members.iracing.com)**
|
||||
@@ -228,7 +228,7 @@ This section describes how the automation engine and companion in this repo sit
|
||||
|
||||
- Shared concept space:
|
||||
- Both surfaces operate on the competition concepts described in [`CONCEPT.md`](docs/concept/CONCEPT.md), [`ADMINS.md`](docs/concept/ADMINS.md), [`DRIVERS.md`](docs/concept/DRIVERS.md), [`COMPETITION.md`](docs/concept/COMPETITION.md), [`RACING.md`](docs/concept/RACING.md), [`SOCIAL.md`](docs/concept/SOCIAL.md), [`TEAMS.md`](docs/concept/TEAMS.md).
|
||||
- The automation engine uses [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) as the canonical representation of a hosted-session setup derived from those higher-level concepts.
|
||||
- The automation engine uses [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) as the canonical representation of a hosted-session setup derived from those higher-level concepts.
|
||||
|
||||
- Division of responsibilities:
|
||||
- The **website** is the primary UI for league management, discovery, stats and rating (core platform concerns).
|
||||
@@ -245,7 +245,7 @@ At a high level, communication flows are designed around the automation engine a
|
||||
- Companion App → Application Use-cases → Automation Engine → Playwright Adapter → iRacing Web.
|
||||
|
||||
- Hand-off of automation intent:
|
||||
- Core platform services or the web app can derive a [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) from league data and store it server-side.
|
||||
- Core platform services or the web app can derive a [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) from league data and store it server-side.
|
||||
- The companion app or a headless orchestrator retrieves these configs via platform APIs and invokes the automation engine using the same application ports used in this repo.
|
||||
|
||||
### 2.4 System context diagram
|
||||
@@ -300,7 +300,7 @@ The automation strategy is shaped by iRacing’s platform boundaries and Terms o
|
||||
- Hooking the sim process or game memory.
|
||||
- Running any automation that is not clearly aligned with “browser automation of a public web UI”.
|
||||
|
||||
The [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) contains additional safeguards, such as:
|
||||
The [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) contains additional safeguards, such as:
|
||||
|
||||
- Guardrails around checkout/payment-like buttons using iRacing-specific selector maps.
|
||||
- Explicit “blocked selector” detection before clicks.
|
||||
@@ -336,7 +336,7 @@ Inner layers:
|
||||
**Layer responsibilities**
|
||||
|
||||
- **Domain**
|
||||
- Competition-neutral automation concepts such as [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1), [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1), session and step invariants and validators.
|
||||
- Competition-neutral automation concepts such as [`AutomationSession`](core/domain/entities/AutomationSession.ts:1), [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1), session and step invariants and validators.
|
||||
- Independent of Electron, Playwright, HTTP or persistence.
|
||||
|
||||
- **Application**
|
||||
@@ -354,9 +354,9 @@ Inner layers:
|
||||
|
||||
**Key rules in this repo**
|
||||
|
||||
- `packages/domain/*` has no dependencies on application, infrastructure, or Electron.
|
||||
- `packages/application/*` depends only on `packages/domain/*` (plus shared types).
|
||||
- `packages/infrastructure/*` depends on domain and application ports, and on external libraries (Playwright, Pino, etc.).
|
||||
- `core/domain/*` has no dependencies on application, infrastructure, or Electron.
|
||||
- `core/application/*` depends only on `core/domain/*` (plus shared types).
|
||||
- `core/infrastructure/*` depends on domain and application ports, and on external libraries (Playwright, Pino, etc.).
|
||||
- `apps/companion/*` depends on inner layers and glues application use-cases to Electron UI and IPC.
|
||||
|
||||
This keeps the **automation engine** stable and reusable across presentation surfaces (companion today, web or backend orchestrators later), while allowing infrastructure and UI details to evolve without rewriting business logic.
|
||||
@@ -365,19 +365,19 @@ This keeps the **automation engine** stable and reusable across presentation sur
|
||||
|
||||
## 4. Layer-by-Layer Mapping
|
||||
|
||||
### 4.1 Domain Layer (`packages/domain/*`)
|
||||
### 4.1 Domain Layer (`core/domain/*`)
|
||||
|
||||
The domain models what an “automation session” is, how it progresses, and which invariants must hold regardless of UI or tooling.
|
||||
|
||||
**Core entities**
|
||||
|
||||
- [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1)
|
||||
- [`AutomationSession`](core/domain/entities/AutomationSession.ts:1)
|
||||
- Represents a single hosted-session automation run.
|
||||
- Tracks:
|
||||
- `id`
|
||||
- `currentStep` (wizard step, via [`StepId`](packages/domain/value-objects/StepId.ts:1))
|
||||
- `state` (via [`SessionState`](packages/domain/value-objects/SessionState.ts:1))
|
||||
- immutable [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1)
|
||||
- `currentStep` (wizard step, via [`StepId`](core/domain/value-objects/StepId.ts:1))
|
||||
- `state` (via [`SessionState`](core/domain/value-objects/SessionState.ts:1))
|
||||
- immutable [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1)
|
||||
- timestamps (`startedAt`, `completedAt`)
|
||||
- failure information (`errorMessage`).
|
||||
- Enforces invariants:
|
||||
@@ -385,44 +385,44 @@ The domain models what an “automation session” is, how it progresses, and wh
|
||||
- Steps can only move forward and must progress sequentially (`n → n+1`, no skipping or going backwards).
|
||||
- Terminal states (e.g. `STOPPED_AT_STEP_18`, `FAILED`) cannot be mutated further.
|
||||
|
||||
- [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1)
|
||||
- [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1)
|
||||
- Describes the admin’s intended hosted session:
|
||||
- Required: `sessionName`, `trackId`, `carIds`.
|
||||
- Optional QoL fields: `serverName`, `password`, `adminPassword`, `maxDrivers`, weather/time-of-day, lengths, damage model, track state, etc.
|
||||
- Acts as the **canonical session description** that higher layers use to map into iRacing’s wizard fields.
|
||||
|
||||
- [`StepExecution`](packages/domain/entities/StepExecution.ts:1)
|
||||
- [`StepExecution`](core/domain/entities/StepExecution.ts:1)
|
||||
- Encapsulates the result of executing a single wizard step, including timing and error data.
|
||||
|
||||
**Value objects**
|
||||
|
||||
- Session lifecycle and step identity:
|
||||
- [`SessionState`](packages/domain/value-objects/SessionState.ts:1)
|
||||
- [`SessionLifetime`](packages/domain/value-objects/SessionLifetime.ts:1)
|
||||
- [`StepId`](packages/domain/value-objects/StepId.ts:1)
|
||||
- [`SessionState`](core/domain/value-objects/SessionState.ts:1)
|
||||
- [`SessionLifetime`](core/domain/value-objects/SessionLifetime.ts:1)
|
||||
- [`StepId`](core/domain/value-objects/StepId.ts:1)
|
||||
|
||||
- Authentication and browser state:
|
||||
- [`AuthenticationState`](packages/domain/value-objects/AuthenticationState.ts:1)
|
||||
- [`BrowserAuthenticationState`](packages/domain/value-objects/BrowserAuthenticationState.ts:1)
|
||||
- [`CookieConfiguration`](packages/domain/value-objects/CookieConfiguration.ts:1)
|
||||
- [`AuthenticationState`](core/domain/value-objects/AuthenticationState.ts:1)
|
||||
- [`BrowserAuthenticationState`](core/domain/value-objects/BrowserAuthenticationState.ts:1)
|
||||
- [`CookieConfiguration`](core/domain/value-objects/CookieConfiguration.ts:1)
|
||||
|
||||
- Checkout and pricing safety:
|
||||
- [`CheckoutPrice`](packages/domain/value-objects/CheckoutPrice.ts:1)
|
||||
- [`CheckoutState`](packages/domain/value-objects/CheckoutState.ts:1)
|
||||
- [`CheckoutConfirmation`](packages/domain/value-objects/CheckoutConfirmation.ts:1)
|
||||
- [`CheckoutPrice`](core/domain/value-objects/CheckoutPrice.ts:1)
|
||||
- [`CheckoutState`](core/domain/value-objects/CheckoutState.ts:1)
|
||||
- [`CheckoutConfirmation`](core/domain/value-objects/CheckoutConfirmation.ts:1)
|
||||
|
||||
- Overlay/visual integration:
|
||||
- [`ScreenRegion`](packages/domain/value-objects/ScreenRegion.ts:1)
|
||||
- [`RaceCreationResult`](packages/domain/value-objects/RaceCreationResult.ts:1)
|
||||
- [`ScreenRegion`](core/domain/value-objects/ScreenRegion.ts:1)
|
||||
- [`RaceCreationResult`](core/domain/value-objects/RaceCreationResult.ts:1)
|
||||
|
||||
**Domain services**
|
||||
|
||||
- [`PageStateValidator`](packages/domain/services/PageStateValidator.ts:1)
|
||||
- [`PageStateValidator`](core/domain/services/PageStateValidator.ts:1)
|
||||
- Declaratively describes what it means for the automation to be “on the right wizard page”.
|
||||
- Evaluates combinations of required/forbidden selectors into a structured result.
|
||||
- Used by [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) to avoid driving the wrong UI state.
|
||||
- Used by [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) to avoid driving the wrong UI state.
|
||||
|
||||
- [`StepTransitionValidator`](packages/domain/services/StepTransitionValidator.ts:1)
|
||||
- [`StepTransitionValidator`](core/domain/services/StepTransitionValidator.ts:1)
|
||||
- Enforces legal transitions between wizard steps and session states.
|
||||
- Centralizes the rules for when it is safe to move to the next step or finalize.
|
||||
|
||||
@@ -433,133 +433,133 @@ The domain models what an “automation session” is, how it progresses, and wh
|
||||
|
||||
---
|
||||
|
||||
### 4.2 Application Layer (`packages/application/*`)
|
||||
### 4.2 Application Layer (`core/application/*`)
|
||||
|
||||
The application layer orchestrates use-cases by coordinating domain entities and calling ports that are implemented in infrastructure.
|
||||
|
||||
**Key ports**
|
||||
|
||||
- [`IAutomationEngine`](packages/application/ports/IAutomationEngine.ts:1)
|
||||
- [`IAutomationEngine`](core/application/ports/IAutomationEngine.ts:1)
|
||||
- `validateConfiguration(config)` → checks whether the intended hosted session is structurally valid and automatable.
|
||||
- `executeStep(stepId, config)` → drives a single wizard step using the underlying browser automation.
|
||||
- `stopAutomation()` → halts the current run.
|
||||
|
||||
- [`ISessionRepository`](packages/application/ports/ISessionRepository.ts:1)
|
||||
- Persists [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1) instances for tracking and later inspection.
|
||||
- [`ISessionRepository`](core/application/ports/ISessionRepository.ts:1)
|
||||
- Persists [`AutomationSession`](core/domain/entities/AutomationSession.ts:1) instances for tracking and later inspection.
|
||||
|
||||
- Screen & browser integration:
|
||||
- [`IScreenAutomation`](packages/application/ports/IScreenAutomation.ts:1) (implemented by [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1)).
|
||||
- [`IAuthenticationService`](packages/application/ports/IAuthenticationService.ts:1) for login/session management.
|
||||
- [`ICheckoutService`](packages/application/ports/ICheckoutService.ts:1) and [`ICheckoutConfirmationPort`](packages/application/ports/ICheckoutConfirmationPort.ts:1) for safe credits/checkout flows.
|
||||
- [`IScreenAutomation`](core/application/ports/IScreenAutomation.ts:1) (implemented by [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1)).
|
||||
- [`IAuthenticationService`](core/application/ports/IAuthenticationService.ts:1) for login/session management.
|
||||
- [`ICheckoutService`](core/application/ports/ICheckoutService.ts:1) and [`ICheckoutConfirmationPort`](core/application/ports/ICheckoutConfirmationPort.ts:1) for safe credits/checkout flows.
|
||||
|
||||
- Cross-cutting:
|
||||
- [`ILogger`](packages/application/ports/ILogger.ts:1)
|
||||
- [`IOverlaySyncPort`](packages/application/ports/IOverlaySyncPort.ts:1)
|
||||
- [`IAutomationEventPublisher`](packages/application/ports/IAutomationEventPublisher.ts:1)
|
||||
- [`IUserConfirmationPort`](packages/application/ports/IUserConfirmationPort.ts:1)
|
||||
- [`ILogger`](core/application/ports/ILogger.ts:1)
|
||||
- [`IOverlaySyncPort`](core/application/ports/IOverlaySyncPort.ts:1)
|
||||
- [`IAutomationEventPublisher`](core/application/ports/IAutomationEventPublisher.ts:1)
|
||||
- [`IUserConfirmationPort`](core/application/ports/IUserConfirmationPort.ts:1)
|
||||
|
||||
**Key services**
|
||||
|
||||
- [`OverlaySyncService`](packages/application/services/OverlaySyncService.ts:1)
|
||||
- [`OverlaySyncService`](core/application/services/OverlaySyncService.ts:1)
|
||||
- Bridges the automation lifecycle (from infrastructure) to overlay/presentation consumers (companion renderer).
|
||||
- Consumes an [`IAutomationLifecycleEmitter`](packages/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) (implemented by the Playwright adapter) and publishes state to an overlay sync port.
|
||||
- Consumes an [`IAutomationLifecycleEmitter`](core/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) (implemented by the Playwright adapter) and publishes state to an overlay sync port.
|
||||
|
||||
**Key use-cases**
|
||||
|
||||
- [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1)
|
||||
- Creates a new [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1) from a [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1).
|
||||
- Calls [`IAutomationEngine`](packages/application/ports/IAutomationEngine.ts:1) to perform validation before any browser work starts.
|
||||
- Persists the session via [`ISessionRepository`](packages/application/ports/ISessionRepository.ts:1).
|
||||
- [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1)
|
||||
- Creates a new [`AutomationSession`](core/domain/entities/AutomationSession.ts:1) from a [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1).
|
||||
- Calls [`IAutomationEngine`](core/application/ports/IAutomationEngine.ts:1) to perform validation before any browser work starts.
|
||||
- Persists the session via [`ISessionRepository`](core/application/ports/ISessionRepository.ts:1).
|
||||
- Returns a DTO that the companion app tracks as progress state.
|
||||
|
||||
- Authentication:
|
||||
- [`CheckAuthenticationUseCase`](packages/application/use-cases/CheckAuthenticationUseCase.ts:1)
|
||||
- [`InitiateLoginUseCase`](packages/application/use-cases/InitiateLoginUseCase.ts:1)
|
||||
- [`ClearSessionUseCase`](packages/application/use-cases/ClearSessionUseCase.ts:1)
|
||||
- [`CheckAuthenticationUseCase`](core/application/use-cases/CheckAuthenticationUseCase.ts:1)
|
||||
- [`InitiateLoginUseCase`](core/application/use-cases/InitiateLoginUseCase.ts:1)
|
||||
- [`ClearSessionUseCase`](core/application/use-cases/ClearSessionUseCase.ts:1)
|
||||
- These map the ToS-compliant login flow described in [`CONCEPT.md`](docs/concept/CONCEPT.md) and [`ADMINS.md`](docs/concept/ADMINS.md) into explicit use-cases (no password handling by GridPilot).
|
||||
|
||||
- Automation completion & checkout:
|
||||
- [`CompleteRaceCreationUseCase`](packages/application/use-cases/CompleteRaceCreationUseCase.ts:1)
|
||||
- [`ConfirmCheckoutUseCase`](packages/application/use-cases/ConfirmCheckoutUseCase.ts:1)
|
||||
- Uses [`ICheckoutService`](packages/application/ports/ICheckoutService.ts:1) from the Playwright layer to inspect price/state and defers to a UI-side confirmation port to comply with “never surprise-charge the admin”.
|
||||
- [`CompleteRaceCreationUseCase`](core/application/use-cases/CompleteRaceCreationUseCase.ts:1)
|
||||
- [`ConfirmCheckoutUseCase`](core/application/use-cases/ConfirmCheckoutUseCase.ts:1)
|
||||
- Uses [`ICheckoutService`](core/application/ports/ICheckoutService.ts:1) from the Playwright layer to inspect price/state and defers to a UI-side confirmation port to comply with “never surprise-charge the admin”.
|
||||
|
||||
- Guarding against stale auth:
|
||||
- [`VerifyAuthenticatedPageUseCase`](packages/application/use-cases/VerifyAuthenticatedPageUseCase.ts:1) ensures the current page is still authenticated before continuing automation.
|
||||
- [`VerifyAuthenticatedPageUseCase`](core/application/use-cases/VerifyAuthenticatedPageUseCase.ts:1) ensures the current page is still authenticated before continuing automation.
|
||||
|
||||
The application layer is where “admin intent” (start automation, confirm checkout, verify login) is encoded and exposed to the companion, without exposing Playwright or DOM specifics.
|
||||
|
||||
---
|
||||
|
||||
### 4.3 Infrastructure Layer (`packages/infrastructure/*`)
|
||||
### 4.3 Infrastructure Layer (`core/infrastructure/*`)
|
||||
|
||||
The infrastructure layer implements the ports using concrete tools and services.
|
||||
|
||||
**Automation adapters**
|
||||
|
||||
- [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1)
|
||||
- [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1)
|
||||
- Implements:
|
||||
- [`IScreenAutomation`](packages/application/ports/IScreenAutomation.ts:1)
|
||||
- [`IAuthenticationService`](packages/application/ports/IAuthenticationService.ts:1)
|
||||
- [`IAutomationLifecycleEmitter`](packages/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) used by [`OverlaySyncService`](packages/application/services/OverlaySyncService.ts:1).
|
||||
- [`IScreenAutomation`](core/application/ports/IScreenAutomation.ts:1)
|
||||
- [`IAuthenticationService`](core/application/ports/IAuthenticationService.ts:1)
|
||||
- [`IAutomationLifecycleEmitter`](core/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) used by [`OverlaySyncService`](core/application/services/OverlaySyncService.ts:1).
|
||||
- Responsibilities:
|
||||
- Managing Playwright browser, context, and page lifecycle (headed/headless, fixture vs real mode).
|
||||
- Navigating to the iRacing hosted-session wizard, login pages and fixtures.
|
||||
- Driving wizard steps through an internal [`WizardStepOrchestrator`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1).
|
||||
- Driving wizard steps through an internal [`WizardStepOrchestrator`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1).
|
||||
- Injecting and updating the on-page automation overlay.
|
||||
- Enforcing click safety (blocked selectors, checkout detection).
|
||||
- Handling authentication flows, cookies and persistent sessions via [`SessionCookieStore`](packages/infrastructure/adapters/automation/auth/SessionCookieStore.ts:1) and [`PlaywrightAuthSessionService`](packages/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.ts:1).
|
||||
- Validating page state using [`PageStateValidator`](packages/domain/services/PageStateValidator.ts:1).
|
||||
- Handling authentication flows, cookies and persistent sessions via [`SessionCookieStore`](core/infrastructure/adapters/automation/auth/SessionCookieStore.ts:1) and [`PlaywrightAuthSessionService`](core/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.ts:1).
|
||||
- Validating page state using [`PageStateValidator`](core/domain/services/PageStateValidator.ts:1).
|
||||
|
||||
- [`MockBrowserAutomationAdapter`](packages/infrastructure/adapters/automation/engine/MockBrowserAutomationAdapter.ts:1)
|
||||
- [`MockBrowserAutomationAdapter`](core/infrastructure/adapters/automation/engine/MockBrowserAutomationAdapter.ts:1)
|
||||
- Lightweight adapter used in tests to simulate automation without real browser interactions.
|
||||
|
||||
- [`FixtureServer`](packages/infrastructure/adapters/automation/engine/FixtureServer.ts:1)
|
||||
- [`FixtureServer`](core/infrastructure/adapters/automation/engine/FixtureServer.ts:1)
|
||||
- Serves static HTML fixtures from `html-dumps-optimized/` to exercise the automation logic deterministically in tests and local development.
|
||||
|
||||
**DOM helpers**
|
||||
|
||||
- [`IRacingDomNavigator`](packages/infrastructure/adapters/automation/dom/IRacingDomNavigator.ts:1)
|
||||
- [`IRacingDomNavigator`](core/infrastructure/adapters/automation/dom/IRacingDomNavigator.ts:1)
|
||||
- High-level navigation and waiting logic for wizard steps and key UI elements.
|
||||
|
||||
- [`IRacingDomInteractor`](packages/infrastructure/adapters/automation/dom/IRacingDomInteractor.ts:1)
|
||||
- [`IRacingDomInteractor`](core/infrastructure/adapters/automation/dom/IRacingDomInteractor.ts:1)
|
||||
- Encapsulates filling fields, clicking elements, handling modals.
|
||||
|
||||
- [`SafeClickService`](packages/infrastructure/adapters/automation/dom/SafeClickService.ts:1)
|
||||
- [`SafeClickService`](core/infrastructure/adapters/automation/dom/SafeClickService.ts:1)
|
||||
- A safer click abstraction that combines timeouts, modal-dismiss logic and safety checks.
|
||||
|
||||
- Selectors and constants:
|
||||
- [`IRACING_SELECTORS`](packages/infrastructure/adapters/automation/dom/IRacingSelectors.ts:1)
|
||||
- Additional helper types under `packages/infrastructure/adapters/automation/dom/*`.
|
||||
- [`IRACING_SELECTORS`](core/infrastructure/adapters/automation/dom/IRacingSelectors.ts:1)
|
||||
- Additional helper types under `core/infrastructure/adapters/automation/dom/*`.
|
||||
|
||||
**Checkout & pricing**
|
||||
|
||||
- [`CheckoutPriceExtractor`](packages/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1)
|
||||
- [`CheckoutPriceExtractor`](core/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1)
|
||||
- Reads DOM labels and buttons in the iRacing wizard to produce:
|
||||
- [`CheckoutPrice`](packages/domain/value-objects/CheckoutPrice.ts:1) (if parsable).
|
||||
- [`CheckoutState`](packages/domain/value-objects/CheckoutState.ts:1) (derived from button classes).
|
||||
- [`CheckoutPrice`](core/domain/value-objects/CheckoutPrice.ts:1) (if parsable).
|
||||
- [`CheckoutState`](core/domain/value-objects/CheckoutState.ts:1) (derived from button classes).
|
||||
- Raw `buttonHtml` for debugging.
|
||||
- Returns results wrapped in [`Result`](packages/shared/result/Result.ts:1) to avoid throwing during automation.
|
||||
- Returns results wrapped in [`Result`](core/shared/result/Result.ts:1) to avoid throwing during automation.
|
||||
|
||||
**Repositories & configuration**
|
||||
|
||||
- [`InMemorySessionRepository`](packages/infrastructure/repositories/InMemorySessionRepository.ts:1)
|
||||
- Simple in-process implementation of [`ISessionRepository`](packages/application/ports/ISessionRepository.ts:1), used in the companion app and tests.
|
||||
- [`InMemorySessionRepository`](core/infrastructure/repositories/InMemorySessionRepository.ts:1)
|
||||
- Simple in-process implementation of [`ISessionRepository`](core/application/ports/ISessionRepository.ts:1), used in the companion app and tests.
|
||||
|
||||
- Config:
|
||||
- [`AutomationConfig`](packages/infrastructure/config/AutomationConfig.ts:1)
|
||||
- [`AutomationConfig`](core/infrastructure/config/AutomationConfig.ts:1)
|
||||
- Mode selection: `production`, `development`, `test`.
|
||||
- Default timeouts and base URLs for fixtures vs live.
|
||||
- [`BrowserModeConfig`](packages/infrastructure/config/BrowserModeConfig.ts:1)
|
||||
- Controls headed/headless behavior, with [`BrowserModeConfigLoader`](packages/infrastructure/config/BrowserModeConfig.ts:1) used heavily in [`di-container`](apps/companion/main/di-container.ts:1).
|
||||
- [`LoggingConfig`](packages/infrastructure/config/LoggingConfig.ts:1)
|
||||
- [`BrowserModeConfig`](core/infrastructure/config/BrowserModeConfig.ts:1)
|
||||
- Controls headed/headless behavior, with [`BrowserModeConfigLoader`](core/infrastructure/config/BrowserModeConfig.ts:1) used heavily in [`di-container`](apps/companion/main/di-container.ts:1).
|
||||
- [`LoggingConfig`](core/infrastructure/config/LoggingConfig.ts:1)
|
||||
|
||||
- Logging:
|
||||
- [`PinoLogAdapter`](packages/infrastructure/adapters/logging/PinoLogAdapter.ts:1)
|
||||
- [`NoOpLogAdapter`](packages/infrastructure/adapters/logging/NoOpLogAdapter.ts:1) (used in tests to keep noise low).
|
||||
- [`PinoLogAdapter`](core/infrastructure/adapters/logging/PinoLogAdapter.ts:1)
|
||||
- [`NoOpLogAdapter`](core/infrastructure/adapters/logging/NoOpLogAdapter.ts:1) (used in tests to keep noise low).
|
||||
|
||||
**IPC / UI integration**
|
||||
|
||||
- [`ElectronCheckoutConfirmationAdapter`](packages/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts:1)
|
||||
- [`ElectronCheckoutConfirmationAdapter`](core/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts:1)
|
||||
- Bridges application-level checkout confirmation flows to the companion renderer via IPC.
|
||||
|
||||
This layer is where the “messy reality” of Playwright, Electron, file paths and selectors is implemented, while honoring the constraints defined at the domain/application layers.
|
||||
@@ -579,22 +579,22 @@ The presentation layer in this repo is currently a **single Electron app** that
|
||||
|
||||
- [`di-container`](apps/companion/main/di-container.ts)
|
||||
- Central wiring for:
|
||||
- Logger ([`ILogger`](packages/application/ports/ILogger.ts:1)) via `createLogger()` and [`LoggingConfig`](packages/infrastructure/config/LoggingConfig.ts:1).
|
||||
- Session repository ([`ISessionRepository`](packages/application/ports/ISessionRepository.ts:1)) via [`InMemorySessionRepository`](packages/infrastructure/repositories/InMemorySessionRepository.ts:1).
|
||||
- Browser automation adapter via `createBrowserAutomationAdapter()` using [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) or [`MockBrowserAutomationAdapter`](packages/infrastructure/adapters/automation/engine/MockBrowserAutomationAdapter.ts:1) depending on mode.
|
||||
- [`IAutomationEngine`](packages/application/ports/IAutomationEngine.ts:1) via [`AutomationEngineAdapter`](packages/infrastructure/adapters/automation/engine/AutomationEngineAdapter.ts:1) / [`MockAutomationEngineAdapter`](packages/infrastructure/adapters/automation/engine/MockAutomationEngineAdapter.ts:1).
|
||||
- Logger ([`ILogger`](core/application/ports/ILogger.ts:1)) via `createLogger()` and [`LoggingConfig`](core/infrastructure/config/LoggingConfig.ts:1).
|
||||
- Session repository ([`ISessionRepository`](core/application/ports/ISessionRepository.ts:1)) via [`InMemorySessionRepository`](core/infrastructure/repositories/InMemorySessionRepository.ts:1).
|
||||
- Browser automation adapter via `createBrowserAutomationAdapter()` using [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) or [`MockBrowserAutomationAdapter`](core/infrastructure/adapters/automation/engine/MockBrowserAutomationAdapter.ts:1) depending on mode.
|
||||
- [`IAutomationEngine`](core/application/ports/IAutomationEngine.ts:1) via [`AutomationEngineAdapter`](core/infrastructure/adapters/automation/engine/AutomationEngineAdapter.ts:1) / [`MockAutomationEngineAdapter`](core/infrastructure/adapters/automation/engine/MockAutomationEngineAdapter.ts:1).
|
||||
- Application use-cases:
|
||||
- [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1)
|
||||
- [`CheckAuthenticationUseCase`](packages/application/use-cases/CheckAuthenticationUseCase.ts:1)
|
||||
- [`InitiateLoginUseCase`](packages/application/use-cases/InitiateLoginUseCase.ts:1)
|
||||
- [`ClearSessionUseCase`](packages/application/use-cases/ClearSessionUseCase.ts:1)
|
||||
- [`ConfirmCheckoutUseCase`](packages/application/use-cases/ConfirmCheckoutUseCase.ts:1)
|
||||
- Overlay sync orchestration via [`OverlaySyncService`](packages/application/services/OverlaySyncService.ts:1) and [`IAutomationLifecycleEmitter`](packages/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1).
|
||||
- [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1)
|
||||
- [`CheckAuthenticationUseCase`](core/application/use-cases/CheckAuthenticationUseCase.ts:1)
|
||||
- [`InitiateLoginUseCase`](core/application/use-cases/InitiateLoginUseCase.ts:1)
|
||||
- [`ClearSessionUseCase`](core/application/use-cases/ClearSessionUseCase.ts:1)
|
||||
- [`ConfirmCheckoutUseCase`](core/application/use-cases/ConfirmCheckoutUseCase.ts:1)
|
||||
- Overlay sync orchestration via [`OverlaySyncService`](core/application/services/OverlaySyncService.ts:1) and [`IAutomationLifecycleEmitter`](core/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1).
|
||||
- Exposes methods like `getStartAutomationUseCase()`, `initializeBrowserConnection()`, `getBrowserModeConfigLoader()`, and `refreshBrowserAutomation()` that are used by IPC handlers and tests.
|
||||
|
||||
- [`ipc-handlers`](apps/companion/main/ipc-handlers.ts)
|
||||
- Translates renderer IPC calls into use-case invocations:
|
||||
- `startAutomation` → [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- `startAutomation` → [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- `checkAuth` / `initiateLogin` / `clearSession` → authentication use-cases.
|
||||
- Browser connection initialization and overlay sync wiring.
|
||||
|
||||
@@ -607,7 +607,7 @@ The presentation layer in this repo is currently a **single Electron app** that
|
||||
- [`App`](apps/companion/renderer/App.tsx)
|
||||
- Controls high-level UI state:
|
||||
- Authentication state (`AuthState`) and login flow.
|
||||
- Current [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) passed from the session creation form.
|
||||
- Current [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) passed from the session creation form.
|
||||
- Session progress tracking (step, state, errors).
|
||||
- Checkout confirmation dialog and race creation success views.
|
||||
- Talks to Electron via `window.electronAPI`:
|
||||
@@ -618,17 +618,17 @@ The presentation layer in this repo is currently a **single Electron app** that
|
||||
|
||||
- Components (selection):
|
||||
- [`SessionCreationForm`](apps/companion/renderer/components/SessionCreationForm.tsx)
|
||||
- Collects the data that becomes [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1).
|
||||
- Collects the data that becomes [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1).
|
||||
- [`SessionProgressMonitor`](apps/companion/renderer/components/SessionProgressMonitor.tsx)
|
||||
- Visualizes the current step, completed steps, and error state of the [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1).
|
||||
- Visualizes the current step, completed steps, and error state of the [`AutomationSession`](core/domain/entities/AutomationSession.ts:1).
|
||||
- [`LoginPrompt`](apps/companion/renderer/components/LoginPrompt.tsx)
|
||||
- Renders different messages for `AUTHENTICATED`, `EXPIRED`, `LOGGED_OUT`, `UNKNOWN` states and wires `onLogin`/`onRetry`.
|
||||
- [`BrowserModeToggle`](apps/companion/renderer/components/BrowserModeToggle.tsx)
|
||||
- Allows switching between headed/headless behavior in development, talking to the [`BrowserModeConfigLoader`](packages/infrastructure/config/BrowserModeConfig.ts:1) through IPC.
|
||||
- Allows switching between headed/headless behavior in development, talking to the [`BrowserModeConfigLoader`](core/infrastructure/config/BrowserModeConfig.ts:1) through IPC.
|
||||
- [`CheckoutConfirmationDialog`](apps/companion/renderer/components/CheckoutConfirmationDialog.tsx)
|
||||
- Presents a clear, time-bounded dialog where the admin must confirm or cancel a credit purchase-like action.
|
||||
- [`RaceCreationSuccessScreen`](apps/companion/renderer/components/RaceCreationSuccessScreen.tsx)
|
||||
- Displays the final result of a successful race creation as modeled by [`RaceCreationResult`](packages/domain/value-objects/RaceCreationResult.ts:1).
|
||||
- Displays the final result of a successful race creation as modeled by [`RaceCreationResult`](core/domain/value-objects/RaceCreationResult.ts:1).
|
||||
|
||||
The companion app is intentionally a **single presentation layer implemented in this repo**, but the application and domain layers are structured so that other presentation layers (web client, backend orchestration service) can reuse the same automation engine via the same ports.
|
||||
|
||||
@@ -644,7 +644,7 @@ This subsection summarizes how the GridPilot Web App / Website and the companion
|
||||
- League and season management, scheduling and calendars.
|
||||
- Driver and team views, stats, rating, discovery and social features as described in the concept docs.
|
||||
- Runs in browsers, talking to core platform services over HTTP or GraphQL.
|
||||
- Produces configuration artifacts such as hosted-session definitions that can be mapped into [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) on the platform side.
|
||||
- Produces configuration artifacts such as hosted-session definitions that can be mapped into [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) on the platform side.
|
||||
|
||||
**GridPilot Companion App (desktop presentation, this repo)**
|
||||
|
||||
@@ -657,9 +657,9 @@ This subsection summarizes how the GridPilot Web App / Website and the companion
|
||||
**Communication pattern between website, platform and companion**
|
||||
|
||||
- A typical flow for a scheduled league race:
|
||||
- The web app and core platform services use competition data (league, calendar, formats) to derive a [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) or equivalent structure server-side.
|
||||
- The web app and core platform services use competition data (league, calendar, formats) to derive a [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) or equivalent structure server-side.
|
||||
- The core platform stores and schedules these configs and can expose them via APIs.
|
||||
- The companion app fetches or receives the relevant configs, calls into the application layer (for example [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1)) and executes them against iRacing through Playwright.
|
||||
- The companion app fetches or receives the relevant configs, calls into the application layer (for example [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1)) and executes them against iRacing through Playwright.
|
||||
- Status and results flow back through overlays and events, and can be consumed both by the companion UI and by platform-side stats and rating services.
|
||||
|
||||
- This repo provides:
|
||||
@@ -679,66 +679,66 @@ This section describes how a typical hosted-session automation run flows through
|
||||
1. **Admin configures a session**
|
||||
|
||||
- In the companion UI, the admin fills out [`SessionCreationForm`](apps/companion/renderer/components/SessionCreationForm.tsx).
|
||||
- The form builds a [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1)-compatible object and calls `window.electronAPI.startAutomation(config)`.
|
||||
- The form builds a [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1)-compatible object and calls `window.electronAPI.startAutomation(config)`.
|
||||
|
||||
2. **IPC → main process**
|
||||
|
||||
- The preload script forwards this call to an IPC handler in [`ipc-handlers`](apps/companion/main/ipc-handlers.ts).
|
||||
- The handler resolves the singleton [`DIContainer`](apps/companion/main/di-container.ts:1) and obtains:
|
||||
- [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- [`IAutomationEngine`](packages/application/ports/IAutomationEngine.ts:1) and [`ISessionRepository`](packages/application/ports/ISessionRepository.ts:1) behind the scenes.
|
||||
- [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1).
|
||||
- [`IAutomationEngine`](core/application/ports/IAutomationEngine.ts:1) and [`ISessionRepository`](core/application/ports/ISessionRepository.ts:1) behind the scenes.
|
||||
|
||||
3. **Use-case and domain**
|
||||
|
||||
- [`StartAutomationSessionUseCase`](packages/application/use-cases/StartAutomationSessionUseCase.ts:1):
|
||||
- Creates a new [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1) by calling `AutomationSession.create(config)`, which validates the core invariants (non-empty session name, track, cars).
|
||||
- [`StartAutomationSessionUseCase`](core/application/use-cases/StartAutomationSessionUseCase.ts:1):
|
||||
- Creates a new [`AutomationSession`](core/domain/entities/AutomationSession.ts:1) by calling `AutomationSession.create(config)`, which validates the core invariants (non-empty session name, track, cars).
|
||||
- Calls `automationEngine.validateConfiguration(config)` to perform more detailed checks (e.g. compatibility with supported wizard flows).
|
||||
- Persists the new session via [`ISessionRepository`](packages/application/ports/ISessionRepository.ts:1) (implemented by [`InMemorySessionRepository`](packages/infrastructure/repositories/InMemorySessionRepository.ts:1)).
|
||||
- Persists the new session via [`ISessionRepository`](core/application/ports/ISessionRepository.ts:1) (implemented by [`InMemorySessionRepository`](core/infrastructure/repositories/InMemorySessionRepository.ts:1)).
|
||||
- Returns a DTO to the IPC handler which is forwarded to the renderer.
|
||||
|
||||
4. **Browser and Playwright setup**
|
||||
|
||||
- The [`DIContainer`](apps/companion/main/di-container.ts:1) uses [`AutomationConfig`](packages/infrastructure/config/AutomationConfig.ts:1) and [`BrowserModeConfig`](packages/infrastructure/config/BrowserModeConfig.ts:1) to:
|
||||
- The [`DIContainer`](apps/companion/main/di-container.ts:1) uses [`AutomationConfig`](core/infrastructure/config/AutomationConfig.ts:1) and [`BrowserModeConfig`](core/infrastructure/config/BrowserModeConfig.ts:1) to:
|
||||
- Decide between `production`, `development`, `test` modes.
|
||||
- Decide headed vs headless rendering.
|
||||
- Potentially start a [`FixtureServer`](packages/infrastructure/adapters/automation/engine/FixtureServer.ts:1) in test/fixture modes.
|
||||
- [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) connects to a browser and ensures the context is ready via `connect()` / `ensureBrowserContext()`.
|
||||
- Potentially start a [`FixtureServer`](core/infrastructure/adapters/automation/engine/FixtureServer.ts:1) in test/fixture modes.
|
||||
- [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1) connects to a browser and ensures the context is ready via `connect()` / `ensureBrowserContext()`.
|
||||
|
||||
5. **Authentication and login**
|
||||
|
||||
- For real iRacing usage:
|
||||
- [`CheckAuthenticationUseCase`](packages/application/use-cases/CheckAuthenticationUseCase.ts:1) and [`VerifyAuthenticatedPageUseCase`](packages/application/use-cases/VerifyAuthenticatedPageUseCase.ts:1) verify whether the session is still valid.
|
||||
- If not, the renderer triggers [`InitiateLoginUseCase`](packages/application/use-cases/InitiateLoginUseCase.ts:1) via IPC.
|
||||
- [`CheckAuthenticationUseCase`](core/application/use-cases/CheckAuthenticationUseCase.ts:1) and [`VerifyAuthenticatedPageUseCase`](core/application/use-cases/VerifyAuthenticatedPageUseCase.ts:1) verify whether the session is still valid.
|
||||
- If not, the renderer triggers [`InitiateLoginUseCase`](core/application/use-cases/InitiateLoginUseCase.ts:1) via IPC.
|
||||
- The Playwright adapter opens a headed browser window, navigates to the login page, and lets the admin log in manually.
|
||||
- Once login is complete, [`PlaywrightAuthSessionService`](packages/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.ts:1) stores cookies in [`SessionCookieStore`](packages/infrastructure/adapters/automation/auth/SessionCookieStore.ts:1), and future runs reuse them.
|
||||
- Once login is complete, [`PlaywrightAuthSessionService`](core/infrastructure/adapters/automation/auth/PlaywrightAuthSessionService.ts:1) stores cookies in [`SessionCookieStore`](core/infrastructure/adapters/automation/auth/SessionCookieStore.ts:1), and future runs reuse them.
|
||||
|
||||
6. **Step-by-step wizard automation**
|
||||
|
||||
- The automation engine (implemented by [`AutomationEngineAdapter`](packages/infrastructure/adapters/automation/engine/AutomationEngineAdapter.ts:1) and backed by [`PlaywrightAutomationAdapter`](packages/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1)) proceeds through steps:
|
||||
- The automation engine (implemented by [`AutomationEngineAdapter`](core/infrastructure/adapters/automation/engine/AutomationEngineAdapter.ts:1) and backed by [`PlaywrightAutomationAdapter`](core/infrastructure/adapters/automation/core/PlaywrightAutomationAdapter.ts:1)) proceeds through steps:
|
||||
|
||||
- Navigate to hosted sessions.
|
||||
- Open “Create a Race” and the hosted-session wizard.
|
||||
- For each step (race information, server details, admins, cars, tracks, weather, race options, conditions):
|
||||
- Ensure the correct page is active using [`PageStateValidator`](packages/domain/services/PageStateValidator.ts:1) and selectors from [`IRACING_SELECTORS`](packages/infrastructure/adapters/automation/dom/IRacingSelectors.ts:1).
|
||||
- Fill fields and toggles using [`IRacingDomInteractor`](packages/infrastructure/adapters/automation/dom/IRacingDomInteractor.ts:1).
|
||||
- Click the correct “Next” / “Create Race” / “New Race” buttons, guarded by [`SafeClickService`](packages/infrastructure/adapters/automation/dom/SafeClickService.ts:1) and blocked-selector logic.
|
||||
- Ensure the correct page is active using [`PageStateValidator`](core/domain/services/PageStateValidator.ts:1) and selectors from [`IRACING_SELECTORS`](core/infrastructure/adapters/automation/dom/IRacingSelectors.ts:1).
|
||||
- Fill fields and toggles using [`IRacingDomInteractor`](core/infrastructure/adapters/automation/dom/IRacingDomInteractor.ts:1).
|
||||
- Click the correct “Next” / “Create Race” / “New Race” buttons, guarded by [`SafeClickService`](core/infrastructure/adapters/automation/dom/SafeClickService.ts:1) and blocked-selector logic.
|
||||
|
||||
- At each step, the Playwright adapter:
|
||||
- Updates the overlay via `updateOverlay(step, message)`.
|
||||
- Emits lifecycle events consumed by [`OverlaySyncService`](packages/application/services/OverlaySyncService.ts:1), which the companion uses to update [`SessionProgressMonitor`](apps/companion/renderer/components/SessionProgressMonitor.tsx).
|
||||
- Emits lifecycle events consumed by [`OverlaySyncService`](core/application/services/OverlaySyncService.ts:1), which the companion uses to update [`SessionProgressMonitor`](apps/companion/renderer/components/SessionProgressMonitor.tsx).
|
||||
|
||||
7. **Checkout and confirmation**
|
||||
|
||||
- For flows that involve iRacing credits or non-zero prices:
|
||||
- [`CheckoutPriceExtractor`](packages/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1) is used by the Playwright adapter to parse price and state from the wizard UI.
|
||||
- [`ConfirmCheckoutUseCase`](packages/application/use-cases/ConfirmCheckoutUseCase.ts:1) sends a confirmation request to the renderer via [`ElectronCheckoutConfirmationAdapter`](packages/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts:1).
|
||||
- [`CheckoutPriceExtractor`](core/infrastructure/adapters/automation/CheckoutPriceExtractor.ts:1) is used by the Playwright adapter to parse price and state from the wizard UI.
|
||||
- [`ConfirmCheckoutUseCase`](core/application/use-cases/ConfirmCheckoutUseCase.ts:1) sends a confirmation request to the renderer via [`ElectronCheckoutConfirmationAdapter`](core/infrastructure/adapters/ipc/ElectronCheckoutConfirmationAdapter.ts:1).
|
||||
- [`CheckoutConfirmationDialog`](apps/companion/renderer/components/CheckoutConfirmationDialog.tsx) shows the admin the price and state, with an explicit timeout and cancel path.
|
||||
- Only after explicit confirmation does the adapter simulate the checkout sequence (and in real mode, additional safeguards ensure no ToS-violating clicks occur).
|
||||
|
||||
8. **Completion and result**
|
||||
|
||||
- Once the final step is reached, [`AutomationSession`](packages/domain/entities/AutomationSession.ts:1) transitions into a terminal state (`STOPPED_AT_STEP_18`, `FAILED`, etc.).
|
||||
- The companion renderer may present a [`RaceCreationResult`](packages/domain/value-objects/RaceCreationResult.ts:1) via [`RaceCreationSuccessScreen`](apps/companion/renderer/components/RaceCreationSuccessScreen.tsx).
|
||||
- Once the final step is reached, [`AutomationSession`](core/domain/entities/AutomationSession.ts:1) transitions into a terminal state (`STOPPED_AT_STEP_18`, `FAILED`, etc.).
|
||||
- The companion renderer may present a [`RaceCreationResult`](core/domain/value-objects/RaceCreationResult.ts:1) via [`RaceCreationSuccessScreen`](apps/companion/renderer/components/RaceCreationSuccessScreen.tsx).
|
||||
- The browser context is closed or re-used based on mode and configuration; debug artifacts may be written by the Playwright adapter for failed runs.
|
||||
|
||||
---
|
||||
@@ -763,7 +763,7 @@ Although this repo focuses on automation and companion, it is deliberately shape
|
||||
|
||||
- The automation engine is designed so that a future league platform can:
|
||||
|
||||
- Generate [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) from league and calendar data (cars, tracks, formats) defined in the core competition services.
|
||||
- Generate [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) from league and calendar data (cars, tracks, formats) defined in the core competition services.
|
||||
- Trigger automation runs at scheduled times, with the admin supervising in the companion app.
|
||||
- Use consistent, error-free sessions as the basis for reliable result capture and stats, supporting the narratives in [`DRIVERS.md`](docs/concept/DRIVERS.md), [`TEAMS.md`](docs/concept/TEAMS.md), [`RACING.md`](docs/concept/RACING.md) and [`STATS.md`](docs/concept/STATS.md).
|
||||
|
||||
@@ -831,7 +831,7 @@ In a future GridPilot platform:
|
||||
|
||||
- The **automation engine** in this repo would be used as a **hosted-session execution backend**:
|
||||
|
||||
- The platform would derive [`HostedSessionConfig`](packages/domain/entities/HostedSessionConfig.ts:1) objects from league/season metadata (cars, tracks, formats) defined in the platform.
|
||||
- The platform would derive [`HostedSessionConfig`](core/domain/entities/HostedSessionConfig.ts:1) objects from league/season metadata (cars, tracks, formats) defined in the platform.
|
||||
- It would call into the automation layer via explicit use-cases or IPC/API, using the same ports used by the companion app today.
|
||||
- The Electron companion may remain the primary operator UI, or an additional headless orchestration mode could be added (still respecting ToS and admin control).
|
||||
|
||||
@@ -846,13 +846,13 @@ In a future GridPilot platform:
|
||||
The automation domain (sessions, steps, validation) is free of Electron/Playwright details, making it straightforward to embed into other hosts.
|
||||
|
||||
- **Ports for automation & auth**:
|
||||
Using [`IAutomationEngine`](packages/application/ports/IAutomationEngine.ts:1), [`IScreenAutomation`](packages/application/ports/IScreenAutomation.ts:1), [`IAuthenticationService`](packages/application/ports/IAuthenticationService.ts:1) means new drivers (or alternative browser runtimes) can be introduced without changing the use-cases.
|
||||
Using [`IAutomationEngine`](core/application/ports/IAutomationEngine.ts:1), [`IScreenAutomation`](core/application/ports/IScreenAutomation.ts:1), [`IAuthenticationService`](core/application/ports/IAuthenticationService.ts:1) means new drivers (or alternative browser runtimes) can be introduced without changing the use-cases.
|
||||
|
||||
- **Explicit checkout/confirmation path**:
|
||||
The combination of [`CheckoutPrice`](packages/domain/value-objects/CheckoutPrice.ts:1), [`CheckoutState`](packages/domain/value-objects/CheckoutState.ts:1), [`CheckoutConfirmation`](packages/domain/value-objects/CheckoutConfirmation.ts:1) and the UI-side confirmation port aligns with the transparency and fairness requirements in [`ADMINS.md`](docs/concept/ADMINS.md) and [`RACING.md`](docs/concept/RACING.md).
|
||||
The combination of [`CheckoutPrice`](core/domain/value-objects/CheckoutPrice.ts:1), [`CheckoutState`](core/domain/value-objects/CheckoutState.ts:1), [`CheckoutConfirmation`](core/domain/value-objects/CheckoutConfirmation.ts:1) and the UI-side confirmation port aligns with the transparency and fairness requirements in [`ADMINS.md`](docs/concept/ADMINS.md) and [`RACING.md`](docs/concept/RACING.md).
|
||||
|
||||
- **Overlay and lifecycle emitter**:
|
||||
The overlay and [`IAutomationLifecycleEmitter`](packages/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) abstraction make it easy to:
|
||||
The overlay and [`IAutomationLifecycleEmitter`](core/infrastructure/adapters/IAutomationLifecycleEmitter.ts:1) abstraction make it easy to:
|
||||
- Drive visual overlays (like those described in admin QoL features) across different frontends.
|
||||
- Feed telemetry into a central stats/ops UI for debugging, while keeping the engine itself small.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user