racecraft — Vue.js Web Client Notes

# racecraft — Vue.js Web Client Notes

> **Parent note:** [Sim Racing Telemetry Analysis Platform — Project Plan](joplin://6c0dcb2a567348fd9796f50c790082e4)
> **Repo:** `~/WebstormProjects/racecraft`
> **Companion:** [rusty-telemetry — REST API Reference](joplin://0c837f4e6b7e462a997cbc19e47c864a)
> **Current version:** v0.1.3

---

## Tech Stack

| Component | Technology |
|-----------|-----------|
| Framework | Vue 3.5 (Composition API, `<script setup>`) |
| Language | TypeScript 5.7 |
| Build | Vite 6 (dev server with API proxy to localhost:8080) |
| State | Pinia 3 |
| Routing | Vue Router 4 |
| HTTP | Axios |
| Charts | Chart.js 4 + vue-chartjs 5 |
| Track maps | HTML Canvas 2D |

---

## Architecture

```
src/
├── api/
│   └── client.ts              — Axios HTTP client, all API functions
├── components/
│   └── FeedStatus.vue         — Per-feed health display
├── router/
│   └── index.ts               — Vue Router config
├── stores/
│   └── sessions.ts            — Pinia store for session/run management
├── types/
│   └── index.ts               — TypeScript interfaces matching API responses
├── utils/
│   └── analysis.ts            — Type guards for analysis results
├── views/
│   ├── DashboardView.vue      — Main dashboard (live feeds, status cards)
│   ├── LiveView.vue           — Live telemetry gauges
│   ├── SessionsView.vue       — Session list + create
│   ├── SessionDetailView.vue  — Session detail, run management, analysis
│   ├── ShiftPointsView.vue    — Shift point analysis charts
│   └── TrackMapView.vue       — Track map visualization
├── App.vue
└── main.ts
```

---

## Key Pages & Features

### Dashboard (`/`)
- System status cards (API Server, Sim Connection, Recording) in 3-column grid
- Active recording info
- Quick links to sessions

### Live View (`/live`)
- Real-time telemetry gauges (speed, RPM, gear, throttle, brake)
- Per-feed status panels via FeedStatus component
- Polls `/api/live` endpoint

### Sessions (`/sessions`)
- Session list with status badges
- Create new session form (use case selector, label)
- Delete sessions

### Session Detail (`/sessions/:id`)
- Session info card (use case, runs, timestamps, guidance)
- **Run management:**
  - Start run with feed selector and optional label
  - Merge feeds toggle (select additional feeds to merge into the run) — v0.1.3
  - Stop active runs
  - Delete runs with confirmation dialog — v0.1.3
- **Session lifecycle:**
  - Complete session → triggers auto-analysis
  - Reopen completed session (to add more runs) — v0.1.3
  - Re-analyze button
  - View full analysis (navigates to analysis-specific page)
- **Quick stats** for shift points (recommended RPM, crossover count, runs analyzed)
- **Quick stats** for track map (boundaries, total points)

### Shift Points Analysis (`/analysis/shift-points/:id`)
- Summary stats (recommended shift RPM, crossover points, runs analyzed, frames analyzed)
- **Charts (in order):**
  1. RPM vs. Force — x: RPM, y: acceleration_g (v0.1.2)
  2. Speed vs. Force — x: speed_kmh, y: acceleration_g (v0.1.2)
  3. Speed vs. RPM (Gear Ratios) — x: speed_kmh, y: rpm (v0.1.2)
  4. Crossover Points — grouped bar chart (RPM + speed per gear change)
- Crossover points table

### Track Map (`/analysis/track-map/:id`)
- Track boundary visualization via Canvas 2D
- Center line overlay

---

## API Client Functions

Defined in `src/api/client.ts`:

| Function | Endpoint | Added |
|----------|----------|-------|
| `getLiveTelemetry()` | GET `/api/live` | v0.1.0 |
| `listRecordings()` | GET `/api/recordings` | v0.1.0 |
| `getRecording(id)` | GET `/api/recordings/{id}` | v0.1.0 |
| `startRecording(req?)` | POST `/api/recordings` | v0.1.0 |
| `stopActiveRecording()` | POST `/api/recordings/stop` | v0.1.0 |
| `stopRecording(id)` | POST `/api/recordings/{id}/stop` | v0.1.0 |
| `deleteRecording(id)` | DELETE `/api/recordings/{id}` | v0.1.0 |
| `listSessions()` | GET `/api/sessions` | v0.1.0 |
| `getSession(id)` | GET `/api/sessions/{id}` | v0.1.0 |
| `createSession(req)` | POST `/api/sessions` | v0.1.0 |
| `deleteSession(id)` | DELETE `/api/sessions/{id}` | v0.1.0 |
| `startRun(sessionId, req)` | POST `/api/sessions/{id}/runs` | v0.1.0 |
| `stopRun(sessionId, runId)` | POST `/api/sessions/{id}/runs/{runId}/stop` | v0.1.0 |
| `completeSession(id)` | POST `/api/sessions/{id}/complete` | v0.1.0 |
| `getAnalysis(id)` | GET `/api/sessions/{id}/analysis` | v0.1.0 |
| `reAnalyze(id)` | POST `/api/sessions/{id}/analyze` | v0.1.0 |
| `deleteRun(sessionId, runId)` | DELETE `/api/sessions/{id}/runs/{run_id}` | v0.1.3 |
| `reopenSession(id)` | POST `/api/sessions/{id}/reopen` | v0.1.3 |

---

## TypeScript Types

Defined in `src/types/index.ts`. Key interfaces:

- `StartRunRequest` — `{ feed_name, label?, merge_feeds?: string[] }` (merge_feeds added v0.1.3)
- `SessionRun` — `{ id, label, feed_name, status, start_marker, end_marker, frame_count, data_truncated }`
- `UseCaseSession` — `{ id, use_case, label, status, runs, analysis, guidance, recording_id }`
- `ShiftPointAnalysis` — `{ gear_curves, crossover_points, recommended_shift_rpm, runs_analyzed, total_frames_analyzed }`
- `GearCurve` — `{ gear, gear_display, run_label, data_points, min/max rpm, min/max speed, sample_count }`
- `GearDataPoint` — `{ speed_kmh, rpm, acceleration_g }`

---

## Pinia Store Actions

Defined in `src/stores/sessions.ts`:

| Action | Added |
|--------|-------|
| `fetchSessions()` | v0.1.0 |
| `fetchSession(id)` | v0.1.0 |
| `createSession(req)` | v0.1.0 |
| `deleteSession(id)` | v0.1.0 |
| `startRun(sessionId, req)` | v0.1.0 |
| `stopRun(sessionId, runId)` | v0.1.0 |
| `completeSession(id)` | v0.1.0 |
| `reAnalyze(id)` | v0.1.0 |
| `deleteRun(sessionId, runId)` | v0.1.3 |
| `reopenSession(id)` | v0.1.3 |

---

## Change Log

### v0.1.3 (2026-06-06) — Run Management & Feed Merging

**New Features:**
- Feed merging: toggle + checkbox selector when starting a run (sends `merge_feeds` to API)
- Run deletion: delete button per run with confirmation dialog (`DELETE /api/sessions/{id}/runs/{run_id}`)
- Session reopen: "Reopen Session" button on completed sessions (`POST /api/sessions/{id}/reopen`)
- New API client functions: `deleteRun()`, `reopenSession()`
- New store actions: `deleteRun()`, `reopenSession()`
- `StartRunRequest` type extended with optional `merge_feeds: string[]`

### v0.1.2 (2026-06-06) — Shifting Analysis Charts

- Added RPM vs. Force scatter chart (x: RPM, y: acceleration_g)
- Added Speed vs. RPM scatter chart (x: speed_kmh, y: rpm)
- Renamed "RPM vs. Acceleration (Tractive Force)" → "RPM vs. Force"
- Renamed "Gear Acceleration Curves" → "Speed vs. Force"
- Chart order: RPM vs. Force → Speed vs. Force → Speed vs. RPM → Crossover Points

### v0.1.1 (2026-06-05) — Dashboard Status Card Layout

- Refactored System Status to 3 individual cards in a row (3-column grid)
- Responsive: collapses to single column below 768px

### v0.1.0 (2026-06-05) — Initial Release

- Dashboard with live feeds and recording status
- Session management (create, list, detail, delete)
- Run management (start, stop)
- Shift point analysis with charts
- Track map visualization
- API client with proxy to localhost:8080

---

## Cross-References

- **Main project plan:** [Sim Racing Telemetry Analysis Platform — Project Plan](joplin://6c0dcb2a567348fd9796f50c790082e4)
- **API reference:** [rusty-telemetry — REST API Reference](joplin://0c837f4e6b7e462a997cbc19e47c864a)
- **Architecture note:** [Architecture & Infrastructure](joplin://c1c3a7b2055642268ab230b95551f470)

---

*Last updated: 2026-06-06 — v0.1.3: run management, feed merging, shifting chart updates*

id: 50a09627d5d347009197b94bcee90411
parent_id: 0e8e00b432a840628faa4df5bc2068bc
created_time: 2026-06-06T08:10:39.362Z
updated_time: 2026-06-06T08:10:39.362Z
is_conflict: 0
latitude: 0.00000000
longitude: 0.00000000
altitude: 0.0000
author: 
source_url: 
is_todo: 0
todo_due: 0
todo_completed: 0
source: joplin-desktop
source_application: net.cozic.joplin-desktop
application_data: 
order: 1780733439362
user_created_time: 2026-06-06T08:10:39.362Z
user_updated_time: 2026-06-06T08:10:39.362Z
encryption_cipher_text: 
encryption_applied: 0
markup_language: 1
is_shared: 0
share_id: 
conflict_original_id: 
master_key_id: 
user_data: 
deleted_time: 0
type_: 1