Files
gridpilot.gg/docs/ARCHITECTURE.md
2025-12-15 13:46:07 +01:00

58 KiB
Raw Blame History

GridPilot Architecture

This document describes how the current GridPilot repository fits into the broader competition platform vision described in the concept docs, with a primary focus on the GridPilot Web Platform (website + core platform services) and a supporting focus on the Automation & Companion subsystem.

The architecture is organized into two main parts:

  1. GridPilot Web Platform Architecture (primary; website + core platform services).
  2. Automation & Companion Architecture (supporting subsystem that executes hosted sessions for the platform and admins).

A short system context comes first, then the web platform, then the automation/companion subsystem, then evolution and integration.


1. System Context and Boundaries

The concept docs define GridPilot as a full competition layer for iRacing leagues:

  • League identity, seasons, signups, teams, results, penalties, stats, social, discovery.

The current codebase in this repo implements only a narrow, but critical slice of that vision:

  • A desktop companion app that runs on the admins machine.
  • A hosted-session automation engine that drives iRacings web UI (members.iracing.com) via Playwright.
  • Supporting domain models for sessions, steps, page validation, checkout safety and overlays.

Everything else from the concept docs (league/season management, result aggregation, team stats, complaints, social features) is future or external to this repo and should be treated as an integrating platform that will later consume this automation layer.

1.1 Current Scope (this repo)

1.2 Future / External Scope (concept platform)

The following are product/domain concerns from the concept docs that are NOT implemented in this repo and should be treated as external or future services:

  • League/season/series modeling and identity (League, Season, Race, etc.).
  • Driver and team accounts, cross-league profiles, stats and history.
  • Standing/points systems, drop weeks, team scoring, analytics.
  • Complaint & penalty workflow, protest queues, visibility and audit trails.
  • Social graph, discovery, messaging, notifications.

In a future state, these would live in separate services or applications (e.g. “GridPilot Core Platform”) and integrate with this automation layer via API or IPC boundaries. The automation layer is deliberately kept small, testable and ToS-safe to serve as a reliable hosted-session engine for those higher-level features.


2. GridPilot Web Platform Architecture

This section describes the GridPilot Web Platform (website + core platform services) as the primary system. The automation and companion slice in this repo exist to serve this platform and the admins/drivers described in the concept docs.

2.1 Web Platform Scope

The web platform is responsible for the competition-layer features described in the concept docs, presented through the website and backed by platform services:

  • League and season management

    • League identity, branding and public presence as described in CONCEPT.md and ADMINS.md.
    • Season calendars, formats, rules and information pages.
    • Configuration of point systems, drop weeks, solo vs team modes.
  • Driver and team system

    • Driver registration, league join flows and rosters as described in DRIVERS.md and TEAMS.md.
    • Team creation and management, constructors-style championships and history.
  • Results, standings, stats and rating

    • Import and storage of race results (either via manual upload or result automation) and computation of standings.
    • Season and all-time statistics per STATS.md.
    • Rating computation and presentation per RATING.md.
  • Complaints, penalties and classification

    • Complaint intake, review workflows and penalty assignment as described in COMPETITION.md and ADMINS.md.
    • Penalty-aware classification and standings adjustment.
  • Social and discovery

    • League landing and discovery surfaces per SOCIAL.md and LANDING.md.
    • Links to Discord, streaming, content, and lightweight social graph features.

Architecturally:

  • The website frontend lives in this monorepo under apps/website as the primary web presentation surface (even if only partially implemented today).
  • The core platform / backend services form a separate layer of APIs, databases and background workers that implement the competition, stats and rating logic; they may live in this monorepo or in separate services, but are conceptually distinct from the automation slice.
  • The automation & companion subsystem in this repo acts as a hosted-session execution backend that the platform can call when it needs to create or manage iRacing hosted sessions.

2.2 Layering for the Web Platform

The web platform itself is designed using a Clean / Hexagonal style, conceptually mirroring the layering used for the automation slice but with a competition-first domain:

  • Presentation (Web)

    • Website SPA/SSR app under apps/website.
    • Routes for league pages, season views, schedules, standings, driver profiles, team pages, stats dashboards, rating insights and social/discovery pages.
    • UI components for admin configuration flows (league setup, season configuration, team/driver management) and for driver-facing views (signups, results, standings, stats, complaints).
  • Application (Platform use-cases)

    • Use-cases that implement the flows described in the concept docs, for example:
      • CreateLeague, ConfigureSeason, OpenRegistration, CloseRegistration.
      • ImportResults, RecalculateStandings, ApplyPenalty, RebuildClassification.
      • SubmitComplaint, ReviewComplaint, AssignPenalty.
      • ComputeStatsSnapshot, ComputeRatingUpdate.
    • These use-cases orchestrate domain models, repositories and external services but stay independent of HTTP frameworks and database details.
  • Domain (Competition models)

    • Conceptual aggregates such as League, Season, Event, Race, Driver, Team, Complaint, Penalty, Standing, SeasonStats, DriverStats, TeamStats, RatingSnapshot.
    • Invariants around eligibility, registration windows, scoring rules, penalty impacts and rating updates.
    • These models are conceptual in this architecture document; they are not yet implemented as concrete TypeScript files in this repo and should be treated as the target design for future platform work.
  • Infrastructure (Platform adapters)

    • Persistence adapters for storing leagues, seasons, events, results, stats, rating snapshots, complaints and penalties in one or more databases.
    • Messaging/queue adapters for background processing (e.g. delayed stats/rating recomputation after penalties).
    • Integration adapters for authentication, payment/billing (if added later), email/notifications and external identity providers.
    • HTTP/GraphQL controllers that expose the application use-cases to the website, companion and other consumers.

The same dependency rule applies as in the automation slice:

  • Presentation and infrastructure depend inwards on application and domain.
  • Domain and application stay free of framework and transport details so that the platform can support multiple frontends (web, admin consoles, APIs) over time.

2.3 Website Frontend Architecture

The website under apps/website is the primary presentation surface for admins, drivers and teams:

  • Application shell and routing

    • A SPA/SSR architecture (for example, React/Next-style) with route groups for:
      • League landing and overview pages.
      • Season calendars, event detail and schedule pages.
      • Standings and championship tables (driver and team).
      • Driver profiles and team pages.
      • Stats dashboards and rating views as described in STATS.md and RATING.md.
      • Complaint and penalty views, including driver- and admin-facing lists.
  • State and data management

    • A query-driven data access pattern (e.g. query client plus local UI store) to fetch and cache platform data from backend APIs.
    • UI state for filters, table sorting, visualization settings and admin workflows kept distinct from server data.
    • Optimistic updates used carefully for admin actions where eventual consistency is acceptable.
  • Presentation of competition concepts

    • League homepages present branding, schedule, standings, rosters and links as described in ADMINS.md and CONCEPT.md.
    • Season pages combine calendar, results, standings and stats into a coherent narrative.
    • Driver profiles show season and all-time stats, rating progression, team history and complaint/penalty context consistent with DRIVERS.md and STATS.md.
    • Team pages present constructors-style standings, driver contribution and historical performance in line with TEAMS.md.
    • Rating views explain changes over time and per-race contributions in a way that matches the principles described in RATING.md.
  • APIs consumed by the website

    • The website calls platform APIs (HTTP/REST or GraphQL) to:
      • Read league, season, event, driver and team data.
      • 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 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.
    • 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

    • The platform stores these hosted-session configurations and exposes them via APIs to operator-facing tools:
      • The companion app retrieves configurations and invokes automation use-cases using the shared application ports.
      • A future headless orchestrator service could call the same ports directly, as long as it respects iRacing ToS and keeps an admin in the loop.
    • The automation subsystem executes the configurations against iRacings web UI and reports back status and results.
  • Ingesting results back into the platform

    • Once automation completes, race results and any derived classification (including incident counts and penalties applied later) are ingested by platform services.
    • The stats and scoring engine described in STATS.md processes these inputs to update standings and rich analytics.
    • The rating engine described in RATING.md uses the same inputs (plus broader season context) to update driver ratings and team evaluations.
  • Separation of concerns

    • Automation is explicitly a helper for admins and the platform: it creates predictable, repeatable hosted sessions and reduces workload, but it does not own competition identity, standings, stats or rating.
    • The platform retains ownership of all long-term competition data and presents it through the website under apps/website.

2. System Context and Boundaries

This section describes how the automation engine and companion in this repo sit alongside the GridPilot Web App / Website, future core platform services, and iRacing itself.

2.1 Main components

  • GridPilot Web App / Website

    • Browser-based UI for admins, drivers and teams.
    • Focused on league management, stats, rating, discovery and social features, as described in the concept docs.
    • Lives in a separate codebase as a presentation & API consumer that talks to core platform services over HTTP or GraphQL.
  • GridPilot Companion App (Electron, this repo)

    • Desktop operator console running on the admin machine.
    • Provides the UI for configuring and supervising hosted-session automation.
    • Integrates directly with the automation engine in this repo and owns the relationship with Playwright and the local browser.
  • Automation Engine & Domain (this repo)

    • Clean Architecture core for iRacing hosted-session automation:
    • Exposes automation capabilities via application ports that can be used both by the companion and by external orchestrators.
  • iRacing Web (members.iracing.com)

    • External system whose hosted-session wizard is automated via Playwright running in a standard browser on the admin machine.
    • Treated strictly as a browser-automation target to remain within iRacing Terms of Service.
  • Core Platform / Backend Services (future/external)

    • Own competition domain concerns such as leagues, schedules, results, stats, rating and social graph as described in STATS.md and RATING.md.
    • Consume the automation engine as a hosted-session execution backend.

2.2 Side-by-side presentation layers

  • The GridPilot Web App / Website and the GridPilot Companion App are sibling presentation layers:

    • Both serve admins and drivers, but with different roles.
    • Both live outside the automation core and depend inward on shared domain and application concepts.
  • Shared concept space:

  • Division of responsibilities:

    • The website is the primary UI for league management, discovery, stats and rating (core platform concerns).
    • The companion is the trusted operator console for ToS-safe automation on the admins machine.

2.3 Communication model

At a high level, communication flows are designed around the automation engine as a reusable core:

  • Typical platform-driven flow:

    • Website UI → Core Platform APIs → Automation Orchestrator → Automation Engine (this repo) → Companion App (operator and overlay) → iRacing Web.
  • Typical companion-driven flow:

    • 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 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

flowchart LR
  Website[GridPilot Web App]
  Platform[Core Platform Services]
  Companion[GridPilot Companion App]
  Engine[Automation Engine and Domain this repo]
  IRacing[iRacing Web members.iracing com]

  Website -- HTTPS APIs --> Platform
  Platform -- Automation requests --> Engine
  Companion -- Local IPC and function calls --> Engine
  Engine -- Browser automation via Playwright --> IRacing
  Platform -- Results events and stats inputs --> Platform

3. iRacing Automation Constraints

The automation strategy is shaped by iRacings platform boundaries and Terms of Service.

2.1 Two iRacing surfaces

  1. Web site (members.iracing.com)

    • Standard HTML/DOM web app at https://members-ng.iracing.com/.
    • Hosted session creation wizard lives here.
    • This repo automates this surface using Playwright, treating it like any other web UI.
    • All automation happens inside a normal browser, launched on the admins machine.
  2. Desktop app (iRacing launcher / sim)

    • Electron-based desktop launcher and the racing sim itself.
    • DOM and process are off-limits; modifying or injecting into this client is ToS-violating.
    • This repo does not automate or modify the desktop app or the sim.

2.2 Allowed vs forbidden approaches

Allowed (and used here)

  • Browser automation of the iRacing website via Playwright.
  • Navigating, filling forms, clicking DOM elements in members.iracing.com.
  • Using local HTML/JSON fixtures to test selectors and flows.
  • Running everything on the admins machine, under their control.

Forbidden (and explicitly avoided)

  • Injecting scripts into the official iRacing desktop client.
  • Reading or manipulating the Electron apps internal DOM.
  • 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 contains additional safeguards, such as:

  • Guardrails around checkout/payment-like buttons using iRacing-specific selector maps.
  • Explicit “blocked selector” detection before clicks.
  • Separate mock/fixture mode for tests vs “real” mode for live sessions.

This aligns with the safety and trust constraints in CONCEPT.md and RACING.md: automation is a helper, not a cheat, and always runs transparently on the admins machine.


4. Clean Architecture Overview (Automation Slice)

The automation & companion code follows a layered, Clean Architecture style where core domain and application logic are shared across multiple presentation and infrastructure options.

4.1 Conceptual layering

Outer layers:
  Presentation (Web App, Companion, APIs)
  Infrastructure (Playwright, logging, persistence, IPC)

Inner layers:
  Application (Use-cases, Ports)
  Domain (Entities, Value Objects, Validators)

Dependency rule

  • Code may only depend inwards:
    • Presentation → Application → Domain.
    • Infrastructure → Application → Domain.
  • Inner layers have no knowledge of specific UIs, frameworks or transport.

Layer responsibilities

  • Domain

    • Competition-neutral automation concepts such as AutomationSession, HostedSessionConfig, session and step invariants and validators.
    • Independent of Electron, Playwright, HTTP or persistence.
  • Application

    • Use-cases that express admin intent (start automation, verify auth, confirm checkout) and orchestrate domain entities via ports.
    • Defines the automation API that both the companion and any future platform orchestrators use.
  • Infrastructure

    • Adapters that implement ports using concrete technologies such as Playwright, Pino, IPC and in-memory repositories.
    • Contains browser automation, DOM helpers, logging and configuration.
  • Presentation

    • UIs and process hosts that call application use-cases:
      • Today: the Electron-based companion app under apps/companion.
      • Future: a web app or backend services that invoke the same use-cases via HTTP, IPC or other transports.

Key rules in this repo

  • 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.


4. Layer-by-Layer Mapping

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

    • Represents a single hosted-session automation run.
    • Tracks:
    • Enforces invariants:
      • Cannot start unless config is valid and state is pending.
      • 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

    • Describes the admins 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 iRacings wizard fields.
  • StepExecution

    • Encapsulates the result of executing a single wizard step, including timing and error data.

Value objects

Domain services

  • PageStateValidator

    • 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 to avoid driving the wrong UI state.
  • StepTransitionValidator

    • 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.

How this ties back to the concept docs

  • Admin workload reduction: the domain ensures that once configured, the automation moves deterministically through the iRacing wizard (no skipped or repeated steps).
  • Safety and trust: session states and validators make failures explicit and traceable, aligning with the transparency goals in ADMINS.md and RACING.md.

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

Key services

  • OverlaySyncService
    • Bridges the automation lifecycle (from infrastructure) to overlay/presentation consumers (companion renderer).
    • Consumes an IAutomationLifecycleEmitter (implemented by the Playwright adapter) and publishes state to an overlay sync port.

Key use-cases

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 (core/infrastructure/*)

The infrastructure layer implements the ports using concrete tools and services.

Automation adapters

DOM helpers

  • IRacingDomNavigator

    • High-level navigation and waiting logic for wizard steps and key UI elements.
  • IRacingDomInteractor

    • Encapsulates filling fields, clicking elements, handling modals.
  • SafeClickService

    • A safer click abstraction that combines timeouts, modal-dismiss logic and safety checks.
  • Selectors and constants:

    • IRACING_SELECTORS
    • Additional helper types under core/infrastructure/adapters/automation/dom/*.

Checkout & pricing

Repositories & configuration

IPC / UI integration

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.


4.4 Presentation Layer (apps/companion/*)

The presentation layer in this repo is currently a single Electron app that provides UI and IPC for admins, but the architecture explicitly anticipates additional presentation surfaces (web app, backend APIs) that reuse the same application and domain layers.

Electron main

React renderer

  • Root:

    • App
      • Controls high-level UI state:
        • Authentication state (AuthState) and login flow.
        • Current HostedSessionConfig 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:
        • checkAuth() and initiateLogin() for auth.
        • startAutomation() and stopAutomation() for sessions.
        • onSessionProgress() to update the right-hand progress monitor.
        • onCheckoutConfirmationRequest() to show CheckoutConfirmationDialog.
  • Components (selection):

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.


4.5 Presentation Surfaces: Web App and Companion

This subsection summarizes how the GridPilot Web App / Website and the companion app relate to the automation engine.

GridPilot Web App / Website (external presentation)

  • Primary UI for:
    • 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 on the platform side.

GridPilot Companion App (desktop presentation, this repo)

  • Operator UI running on the admin PC.
  • Owns:
    • The relationship with Playwright and the local browser.
    • Local configuration, browser mode, fixture usage and overlay rendering.
  • Integrates with the automation engine via application use-cases and ports that are shared with other potential callers (for example, a core platform automation orchestrator).

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 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) 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:

    • The domain, application, and infrastructure for safe, repeatable hosted-session automation.
    • A concrete desktop presentation in the form of the companion app.
  • The web app and core platform are separate outer layers that integrate with this automation slice via APIs and must respect the same dependency direction (only depend inwards on application and domain, not vice versa).


5. Automation Flow: From Admin Click to iRacing Wizard

This section describes how a typical hosted-session automation run flows through the layers.

5.1 High-level sequence

  1. Admin configures a session

  2. IPC → main process

  3. Use-case and domain

    • StartAutomationSessionUseCase:
      • Creates a new AutomationSession 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 (implemented by InMemorySessionRepository).
      • Returns a DTO to the IPC handler which is forwarded to the renderer.
  4. Browser and Playwright setup

  5. Authentication and login

  6. Step-by-step wizard automation

    • The automation engine (implemented by AutomationEngineAdapter and backed by PlaywrightAutomationAdapter) 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):
    • At each step, the Playwright adapter:

  7. Checkout and confirmation

    • For flows that involve iRacing credits or non-zero prices:
  8. Completion and result

    • Once the final step is reached, AutomationSession transitions into a terminal state (STOPPED_AT_STEP_18, FAILED, etc.).
    • The companion renderer may present a RaceCreationResult via RaceCreationSuccessScreen.
    • 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.

6. How This Serves Admins, Drivers, Teams

Although this repo focuses on automation and companion, it is deliberately shaped to support the value promised in the concept docs.

For admins (see ADMINS.md)

  • Less repetitive work:
    • Hosted-session creation for a league calendar can be scripted once and reused.
    • Validation catches inconsistent configs before iRacing errors do.
  • Reliability and safety:
    • Playwright runs in a controlled, tested way, with domain validators and guardrails.
    • Checkout logic always goes through a confirmation dialog and blocked selectors.
  • Transparency:
    • Session state (pending, in progress, terminal) and step progress are visible in the companion UI.
    • Debug artifacts for failures are generated in a controlled way, enabling root-cause analysis.

For drivers and teams (via future platform integration)

  • The automation engine is designed so that a future league platform can:

    • Generate HostedSessionConfig 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, TEAMS.md, RACING.md and STATS.md.

The architecture is intentionally narrow but solid, so that when the broader competition platform arrives, it can treat this automation module as a trustworthy, ToS-compliant “session engine” for many leagues.


7. Testing and Validation

Testing is structured to mirror the Clean Architecture layering and the automation flow, without enumerating every individual test file.

  • See TESTS.md for detailed structure and conventions; this section summarizes how tests align with the architecture.

Unit tests

  • Domain:

    • Focus on entities, value objects and validators such as AutomationSession and PageStateValidator.
    • Ensure that hosted-session invariants and page transition rules hold independently of any UI or automation adapter.
  • Application:

    • Exercise use-cases such as StartAutomationSessionUseCase, authentication flows and checkout confirmation coordination.
    • Verify that ports are invoked correctly and that domain state transitions are orchestrated as intended.
  • Infrastructure:

Integration tests

  • Automation flows:

    • Validate that Playwright-based adapters, DOM helpers, overlay emitters and repositories work together across the iRacing wizard steps using fixtures.
  • Repositories and browser modes:

    • Ensure that session persistence and browser mode configuration behave consistently across environments.
  • Interface-level flows:

    • Exercise IPC wiring and renderer integration to ensure the companion presentation layer correctly drives use-cases and reacts to lifecycle events.

E2E and smoke tests

  • E2E:

    • Drive full hosted-session workflows end-to-end (fixtures and, when configured, real iRacing) through the companion UI and automation engine.
    • Validate that the system behaves correctly from admin input through to iRacing wizard completion.
  • Smoke:

    • Provide fast feedback that critical wiring (Electron boot, Playwright initialization, browser-mode toggle) is intact.

This layered testing approach mirrors the architecture and makes it safe to evolve selectors, overlay UX or Electron wiring without regressing the core admin value of safe, repeatable automation.


8. Evolution and Integration with the Competition Platform

The concept docs describe a much broader platform: leagues, teams, seasons, stats, rating, social features and structured protests. This section explains how the current automation & companion architecture is designed to plug into that future.

8.1 Integration points

In a future GridPilot platform:

  • A core competition service would own:

    • League, season, and race schedules.
    • Team and driver registration.
    • Points, standings, penalties, stats and rating.
    • The competition identity and rating model described in STATS.md and RATING.md.
  • The automation engine in this repo would be used as a hosted-session execution backend:

    • The platform would derive HostedSessionConfig 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).
  • A future rating service (part of the core platform, not this repo) would:

    • Compute GridPilot Rating using league results, incidents, team points and attendance as outlined in RATING.md.
    • Treat automation outputs (trusted hosted-session configs, results, and penalty-aware outcomes) as structured inputs from this repo, not as rating logic implemented here.
    • Depend on the platforms stats and competition data model from STATS.md rather than any in-repo class or service.

8.2 Design decisions that support this evolution

  • Clean separation of domain vs adapters:
    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, IScreenAutomation, IAuthenticationService means new drivers (or alternative browser runtimes) can be introduced without changing the use-cases.

  • Explicit checkout/confirmation path:
    The combination of CheckoutPrice, CheckoutState, CheckoutConfirmation and the UI-side confirmation port aligns with the transparency and fairness requirements in ADMINS.md and RACING.md.

  • Overlay and lifecycle emitter:
    The overlay and IAutomationLifecycleEmitter 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.

8.3 What this document intentionally does not specify

To stay honest to the current repo and avoid overpromising:

  • There is no web API, web client or full league database in this repo. Any such components described in older docs were removed from this architecture description.
  • There is no implementation of the full complaints/penalties engine, team scoring or cross-league stats here only the automation slice that can support them later.
  • Any mention of those features should be read as future integration context, not current implementation.

When those broader services exist (likely as separate apps/services), they should define their own architecture documents and link back here when describing how they use the hosted-session automation engine.


9. Cross-References

This ARCHITECTURE.md is the source of truth for how the current repo implements the automation engine + companion app, and how that slice is intended to underpin the broader GridPilot competition platform over time.