Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
c4e981e
feat(iracing): capture IBT and replay measured paths
iameddieyayaya Oct 15, 2026
880387a
chore: merge main into iRacing branch
iameddieyayaya Oct 15, 2026
7eb96a6
Merge remote-tracking branch 'origin/main' into iameddieyayaya/459-ir…
iameddieyayaya Oct 16, 2026
444fbbd
Merge remote-tracking branch 'origin/main' into iameddieyayaya/459-ir…
iameddieyayaya Oct 16, 2026
9a1776d
Merge branch 'main' into iameddieyayaya/459-iracing
iameddieyayaya Oct 17, 2026
9e734d0
feat(iracing): add incident reports
iameddieyayaya Oct 17, 2026
6281e05
chore(telemetry): refresh generated catalog
iameddieyayaya Oct 17, 2026
5ef4a04
Merge remote-tracking branch 'origin/main' into iameddieyayaya/459-ir…
iameddieyayaya Oct 17, 2026
fd65f72
feat(iracing): add live and comparison map support
iameddieyayaya Oct 18, 2026
f21980d
Merge branch 'main' of github.com:SpeedHQ/RaceIQ into iameddieyayaya/…
iameddieyayaya Oct 18, 2026
bfc0582
fix(comparison): align map chevrons to path
iameddieyayaya Oct 18, 2026
9cc6049
Merge main into iameddieyayaya/459-iracing
iameddieyayaya Oct 19, 2026
8d30321
Merge branch 'main' into iameddieyayaya/459-iracing
iameddieyayaya Oct 19, 2026
9cb654a
fix(capture): preserve telemetry across timing gaps
iameddieyayaya Oct 19, 2026
580bad9
test(iracing): seed Navarra telemetry
iameddieyayaya Oct 19, 2026
fa42547
feat(iracing): smooth replay cursor playback
iameddieyayaya Oct 19, 2026
3266354
fix(session-capture): preserve atomic recording migration
iameddieyayaya Oct 20, 2026
b96f49d
test(e2e): align iRacing checks with current UI
iameddieyayaya Oct 20, 2026
e59af34
chore: merge origin/main into iRacing branch
iameddieyayaya Oct 21, 2026
1809ea1
chore: merge origin/main into iRacing branch
iameddieyayaya Oct 21, 2026
3f73ef4
fix: relocate iRacing report and repair Windows checks
iameddieyayaya Oct 21, 2026
be866c5
fix(iracing): persist capture opt-in
iameddieyayaya Oct 21, 2026
8eb10f9
merge: update iRacing branch from main
iameddieyayaya Oct 21, 2026
130f5c7
test(e2e): align checks with Spectate UI
iameddieyayaya Oct 21, 2026
c59559c
Merge remote-tracking branch 'origin/main' into iameddieyayaya/459-ir…
Snazzie Oct 21, 2026
874f52f
fix(iracing): restore native replay and visuals
Snazzie Oct 21, 2026
6c3cf95
docs(iracing): plan automatic IBT reconciliation
Snazzie Oct 21, 2026
fe8b6c3
fix(iracing): recover recorded IBT brake bias
iameddieyayaya Oct 21, 2026
99e1f46
docs(iracing): close reconciliation contract gaps
iameddieyayaya Oct 21, 2026
6c594bb
Merge main into 459-iracing
iameddieyayaya Oct 21, 2026
4b6b21a
fix(iracing): align compare maps and car headings
iameddieyayaya Oct 22, 2026
f6e582a
fix(iracing): correct track map test package imports
iameddieyayaya Oct 22, 2026
818b177
test(iracing): remove stale pressure assertion
iameddieyayaya Oct 22, 2026
3f7cd3e
Merge origin/main into 459-iracing
iameddieyayaya Oct 22, 2026
ff49ed9
Regenerate lockfile with Bun 1.4.4
iameddieyayaya Oct 22, 2026
9db5461
test: update recording and browser coverage
iameddieyayaya Oct 22, 2026
a4bd6da
Revert "test: update recording and browser coverage"
iameddieyayaya Oct 22, 2026
ddb90d1
Merge branch 'main' into iameddieyayaya/459-iracing
iameddieyayaya Oct 22, 2026
2f46425
Merge main into iameddieyayaya/459-iracing
iameddieyayaya Oct 22, 2026
4b51ad8
Fix session review integration fixture
iameddieyayaya Oct 23, 2026
c20572e
fix(e2e): repair seeded CI regressions
iameddieyayaya Oct 23, 2026
0deb7f3
fix(ci): repair Windows test and lint portability
iameddieyayaya Oct 24, 2026
a9337ec
Merge main into 459-iracing
iameddieyayaya Oct 25, 2026
9590322
Merge origin/main into 459-iracing
iameddieyayaya Oct 26, 2026
340586e
fix(iracing): smooth gaps in lap replay
iameddieyayaya Oct 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 50 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
## Unreleased

### Features
- Drag and drop recordings into the session import dialog, including matching DuckDB WAL sidecars, while retaining the file picker.
- Restore iRacing Live sidebar access with a dedicated dashboard for driving inputs, timing, fuel, vehicle motion, suspension travel, and temperatures; hide stale readings when telemetry stops.
- Add an overall clean-driving score to the iRacing Latest Session card, based on valid timed laps and excluding pit laps.
- Review observed personal incident-point increases, sampled off-track spans, and recorded clean-lap streaks in saved iRacing sessions, with event links and replay timeline markers limited to recorded lap evidence.
- Keep iRacing replay incident markers alongside the shared replay visualization and telemetry panels.
- Render iRacing comparison laps in Focus View, Spectate and circuit overviews from recorded GPS; project live lap progress onto official track geometry when GPS is unavailable, using replay's map handedness, forward car headings, and official turn labels without treating projected positions as measured racing lines.
- Replace category tabs on the AMS2 and iRacing Cars pages with a searchable dropdown that shows the total as a placeholder, clears the search when opened, and preserves category counts and the All categories reset.
- Add AMS2 support: native Windows shared-memory telemetry capture, game-specific car and track identity, per-wheel Replay metrics, 235 track maps, car thumbnails, dashboard branding and a separate Driver profile; include Live connection guidance and correct lap capture, export, replay and track-map behavior. Keep adapter availability and native capture development-only.
- Show animated suspension springs and chassis movement in Replay and Compare → Spectate; use the lap's observed travel range when no game range is specified, while preserving native normalized readings.
Expand Down Expand Up @@ -30,6 +36,27 @@
- Show lap classifications separately from validity in expanded session lap tables.
- Simplify session timelines into compact circles with single-word event labels, starting positions, and arrows showing the new position.
- Provide a Linux x86_64 AppImage for Ubuntu 22.04 and newer, with AppImageUpdate-compatible GitHub release deltas.
- Smooth iRacing lap replay by interpolating the track marker and timeline cursor between recorded telemetry frames.

### Fixes
- Keep Replay and Compare → Spectate circuit overviews clear of mobile input dashboards and camera/focus controls.
- Restore resized Replay and Spectate panel widths when reopening the same panels, while preserving compact defaults for different panel combinations.
- Keep dashboard summaries available when historical recordings cannot be decoded.
- Hide iRacing tire temperatures and pressure in live and replay telemetry views instead of presenting pit-only snapshots or cold setup pressure as live readings.
- Keep tire silhouettes visible in 2D layouts when temperature telemetry is unavailable, without inventing temperature readings.
- Restore iRacing track edges and 3D track placement for official maps that use symbol-based start/finish markers.
- Remove automatic 3D track centerlines and control the recorded purple trajectory with the Racing line toggle independently of track edges.
- Open iRacing IBT preview and confirmation directly from the session import dialog, preserve the selected ownership, and describe original-file storage accurately.
- Preserve original iRacing IBT recordings through import, replay, and reprocessing without generating BIN captures; seed Navarra through the same production import workflow instead of a downsampled, preconverted fixture.
- Restore iRacing replay's shared 2D/3D visualization and data panels; remove the game-specific replay data panel.
- Detect replay timeline and chart gaps relative to the recording cadence, so regular sparse samples are not painted as missing telemetry.
- Replace the iRacing session review's end-of-lap tire section with the incident report below detected telemetry issues.
- Preserve session lap-selection drafts while choosing the primary lap.
- Prevent live recording startup from failing on Windows, leaving empty capture manifests and recorded laps without replay telemetry.
- Restore recording-layout migration and interrupted-recording recovery on Windows by avoiding unsupported directory synchronization and serializing migration journal reads and replacement.
- Persist the iRacing automatic IBT capture opt-in and restore capture after backend restart.
- Keep iRacing telemetry flowing when native lap timing stalls; mark unresolved lap data incomplete instead of stopping capture.
- Replace iRacing comparison-map yaw ticks with lap-colored travel-direction chevrons and align follow view to the plotted path; retain plain dots when nearby positions cannot establish direction.
- Capture LMU opponents by default in a separate removable companion recording; opt out for the next live session, preview and explicitly compare an exact recorded opponent through session, driver, and lap filters with car details and without coverage or telemetry status labels, switch Driver to Me to browse every player lap in the session, export its full interval, or irreversibly remove session-wide opponent data while preserving player telemetry. Compare partial opponent laps even when scoring updates lag behind the player's lap boundary. Keep stale, removed, missing and unrecorded references distinct.
- Expand an LMU session on the Sessions page to see recorded opponents immediately, without choosing a player lap, as collapsible driver rows showing their fastest recorded lap and its sector splits. Sort recorded opponents by fastest valid best lap by default. Browse opponents in a scrollable child table that stays within the session table, with lap warnings behind compact info indicators. Expand a driver to replay or compare an exact recorded lap without duplicating recordings, keeping opponent laps together across player recording splits. Opponent Replay fills the available workspace. Keep opponent cars and paths on the flat track plane without changing recorded elevation.
- Use black backgrounds for recorded opponent tables and expanded opponent lap rows on the Sessions page.
Expand Down Expand Up @@ -131,12 +158,18 @@
- Restore dashboard, driver-profile, and Analyse pages when opening the app.
- Block screenshots for chat models without verified image support and keep text conversations usable.
- Hide the entire Tires section on iRacing live dashboards without changing recorded-lap analysis or other games.
- Show fresh iRacing SDK telemetry even when UDP status is unavailable; hide readings after frames stop.
- Orient the iRacing replay map marker along the plotted lap path instead of simulator-frame yaw.
- Hide iRacing 3D track, racing-line, tire-trail, and input overlays because live telemetry does not provide world-position samples.
- Complete first-run sparse recording migration in compiled builds instead of failing.
- Correct iRacing clutch pedal direction so released reads 0% and fully pressed reads 100% in live telemetry and replay.
- Complete first-run sparse recording migration in packaged builds, including Windows.

- Skip LMU outline requests when stored track names do not identify one layout.

### Internal
- Align seeded E2E capability and dialog checks with production behavior, isolate native game discovery, and use release-pinned Bun for historical upgrade fixtures.
- Remove the stale tire-pressure capability snapshot assertion; retain parser/resolver coverage that prevents iRacing cold setup pressures from appearing as live readings.
- Run workspace lint through the installed Oxlint CLI and isolate native database test fixtures in subprocesses to keep Windows pre-commit checks reliable.
- Preserve Windows directory-sync path errors when validating recording publication directories.
- Target comparison lap pickers explicitly in browser checks and wait for rendered frames in the native camera zoom check.
- Keep diagnostic dump runs in one BIN per selected source, retain raw Forza/F1 datagrams, stream live telemetry over WebSocket for every game, and bypass telemetry-driven session/database processing and background recording maintenance.
Expand All @@ -149,7 +182,7 @@
- Use Ubuntu instead of macOS for CI runners and cap Mars memory requests at 6 GB.
- Invalidate cached frontend builds when source changes in dependent workspaces.
- Extract tracks and cars catalogues into feature-owned UI, server, contract, and E2E workspaces with enforced browser boundaries, inherited Turbo impact inputs, and isolated compiled-app browser tasks.
- Run native Spectate camera and transition checks in a dedicated browser lane while retaining coverage for CPU-compatible rendering paths.
- Run native Spectate camera and transition checks with full Chromium and a required hardware WebGPU adapter in a dedicated lane, retaining CPU-compatible coverage separately.
- Verify LMU recorded pit-cycle classifications independently of lap validity, preserving telemetry-quality failures and incomplete tails.
- Synchronize zoom-reversal checks with rendered transition frames and wait for concurrent SQLite writers during migration fixture setup.
- Keep sparse-capture fixtures schema-valid and verify failed classification recordings without waiting for dashboard work blocked by startup repair prerequisites.
Expand Down Expand Up @@ -181,7 +214,9 @@
### Breaking
- Legacy full-frame RaceIQ captures are no longer supported for import and replay. Ensure any remaining legacy recordings are migrated when prompted before updating.

### Feature
### Features
- Connect to iRacing on Windows to automatically save completed native .ibt recordings while leaving original files untouched.
- Replay recorded iRacing .ibt driving lines and elevation, with the official map retained as an approximate reference and map-based placement for recordings without GPS data.
- New desktop and self-hosted installs restrict dashboard access to this computer until you select additional network interfaces.
- Password-protected dashboards use a login screen and browser sessions; API clients must sign in and send the session cookie and a CSRF token for writes.
- Use string car and track IDs across imports and integrations instead of ordinal fields. Existing sessions and setup links migrate automatically; downgrading requires restoring a pre-upgrade database backup.
Expand All @@ -200,6 +235,17 @@
- Choose a recording folder, safely relocate existing recordings, and optionally migrate recordings into per-game `own` and `others` folders.

### Fixes
- Close reference track outlines without joining the ends of recorded driving traces.
- Keep converted recordings from older releases readable after updating, including checkpoint-only F1, iRacing, and LMU captures.
- Stop reopening the recording-organization success dialog after reload when no recordings need migration.
- Show the track layout after the track name with a hyphen and remove the track-detail header subtitle.
- Hide the track-detail Debug tab in production builds.
- Clarify setup browser labels with “Save to my setups” and the “Mine” filter.
- Adapt dashboard activity to the selected period: daily duration for Today, daily bars for This Week, weekday-column calendars for This Month, and monthly totals for This Year; fill the available panel width.
- Show monthly Clean laps trend points for This Year while preserving cumulative clean rates.
- Keep dashboard period controls visible while scrolling.
- Reduce excess space above the dashboard period controls.
- Restore the visible down arrow and solid background on the AI chat scroll-to-bottom button.
- Restore migration of existing recordings into organized folders on Windows.
- Keep experiment lap counts and review analysis tied to the selected test when importing historical laps or returning to an older setup, and preserve test membership during live updates.
- Keep lap-chat follow-ups grounded in the selected lap and its latest analysis, use fresh telemetry for requested corner measurements, and preserve earlier driver notes without asking for internal lap identifiers.
Expand Down Expand Up @@ -264,6 +310,7 @@

### Fixes
- Keep racing, throttle, and braking lines sharp when zooming into the replay map.
- Restore track edges and tyre details in iRacing 3D replays while labeling map-based positions and historical pit readings.

### Internal
- Package organized recording paths in seeded Playwright databases while rejecting unsafe capture paths.
Expand Down
29 changes: 27 additions & 2 deletions apps/backend/scripts/data/seed-db-runner.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { ROOT_DIR } from "@raceiq/backend-core/runtime/config/paths";
import { db, closeDb, initDb } from "@raceiq/backend-core/db/index";
import { createReadStream, existsSync, readFileSync } from "node:fs";
import { link, mkdir, unlink } from "node:fs/promises";
import { basename, join, relative, resolve, sep } from "node:path";
import { createGunzip } from "node:zlib";
import { db, closeDb, initDb } from "@raceiq/backend-core/db/index";
import { commitStagedIbt, stageIbtUpload } from "../../src/imports/iracing-ibt";
import { importSessionBin } from "@raceiq/backend-core/session-capture/import-capture";
import { importSessionFrames } from "@raceiq/backend-core/session-capture/import-pipeline";
import {
Expand All @@ -24,8 +25,8 @@ import { developmentReleaseFeatures } from "@raceiq/tooling-release/release/deve
import { profiles, sessions } from "@raceiq/backend-core/db/schema";
import { and, eq, inArray, like } from "drizzle-orm";
import { stopMaintenanceTasks } from "@raceiq/backend-core/telemetry/live-pipeline";
import { seedIRacingSession } from "@raceiq/tooling-data/data/seed-db-iracing";
import { assertSafeTarget, seedRowCount } from "@raceiq/tooling-data/data/seed-db-safety";
import { seedIRacingSession } from "@raceiq/tooling-data/data/seed-db-iracing";
import { insertDemoRows, markOnboardingComplete } from "@raceiq/tooling-data/data/seed-db-demo";
import { removeSeedData } from "@raceiq/tooling-data/data/seed-db-reset";
import { FIXTURES, PROFILE_NAME, parseOptions, SEED_MARKER } from "@raceiq/tooling-data/data/seed-db-options";
Expand Down Expand Up @@ -178,6 +179,10 @@ async function main(): Promise<void> {
const excludedFixtures = new Set(options.excludedFixtures);
for (const game of options.games) {
const fixtures = (options.fixtures ?? FIXTURES[game]).filter((fixture) => !excludedFixtures.has(fixture));
if (fixtures.length === 0) {
console.log(`[DB Seed] ${game}: skipped; no recording fixtures are configured.`);
continue;
}
for (const fixture of fixtures) {
const partMatch = /^(.*)\.part(\d+)$/i.exec(fixture);
if (partMatch && Number(partMatch[2]) !== 1) continue;
Expand All @@ -195,6 +200,26 @@ async function main(): Promise<void> {
const fixturePath = combined?.path ?? partPaths[0]!;
try {
if (game === "iracing") {
if (!fixturePath.toLowerCase().endsWith(".ibt")) {
await seedIRacingSession(fixturePath);
continue;
}
const existingSessionIds = new Set(
(await db.select({ id: sessions.id }).from(sessions).where(eq(sessions.gameId, game)).all()).map((row) => row.id),
);
const staged = await stageIbtUpload(
Bun.file(fixturePath).stream(),
basename(fixturePath),
);
if (!staged.token) throw new Error(`iRacing seed fixture cannot be imported: ${staged.preview.reason ?? fixturePath}`);
const result = await commitStagedIbt(staged.token, "mine", { notifyDriverProfile: false });
const createdSessionIds = (await db.select({ id: sessions.id }).from(sessions).where(eq(sessions.gameId, game)).all())
.map((row) => row.id)
.filter((id) => !existingSessionIds.has(id));
if (createdSessionIds.length === 0) throw new Error(`No iRacing telemetry imported from ${fixturePath}`);
await db.update(sessions).set({ notes: SEED_MARKER }).where(inArray(sessions.id, createdSessionIds)).run();
importedLapIds.push(...result.laps.filter((lap) => lap.isValid).map((lap) => lap.lapId));
console.log(`[DB Seed] iracing: ${result.laps.length} laps from ${fixture}`);
const importStartedAt = performance.now();
try {
await seedIRacingSession(fixturePath);
Expand Down
Loading