id: 485cf245d89b4bd994e5c3f19eb439f6
parent_id: ef2e072fff6a4a528b52a6c64daaa267
item_type: 1
item_id: 6c0dcb2a567348fd9796f50c790082e4
item_updated_time: 1782287368069
title_diff: "[]"
body_diff: "[{\"diffs\":[[0,\"*v0.\"],[-1,\"6.0 + Track Mapping — Persistent TrackModel, T\"],[1,\"7.0 — Session persistence, car characteristics DB, t\"],[0,\"rack\"],[-1,\" API, PCARS Position Data\"],[1,\"_map removal\"],[0,\"** |\"]],\"start1\":508,\"start2\":508,\"length1\":83,\"length2\":76},{\"diffs\":[[0,\"0.1.\"],[-1,\"4 — Track Mapping Web Client, Persistent TrackModel Views, Canvas 2D Geometry\"],[1,\"5 — Characteristics views, tracks views, track_map removal\"],[0,\"** |\"]],\"start1\":1045,\"start2\":1045,\"length1\":85,\"length2\":66},{\"diffs\":[[0,\"n data\\\n\\\n\"],[1,\"- **1.12 Session Persistence + Car Characteristics — IMPLEMENTED 2026-06-24 (both repos)**\\\n  - [x] **Persistent sessions** — Session metadata, runs, and analysis results survive server restart\\\n    - Metadata stored at `data/sessions/<id>.json` (runs, analysis, car_name)\\\n    - Frames stored separately at `data/sessions/<id>.frames.json` (lazy-loaded on demand)\\\n    - Metadata-only load on startup for fast session listing\\\n    - `ensure_frames_loaded()` lazy-loads frames before analysis/extraction\\\n    - Atomic writes (temp file + rename), compact JSON serialization\\\n    - Frame serialization offloaded to background thread (clone under lock, write off-thread)\\\n    - `car_name: Option<String>` cached on `UseCaseSession` (set during `stop_run`/`complete_session`)\\\n    - Recording runs normalized to `Stopped` on reload (stale ring-buffer markers)\\\n    - `extract_car_name()` helper scans frames for first non-empty car name\\\n  - [x] **Car characteristics aggregation** — Cross-session shift-point profiles per car\\\n    - `characteristics.rs` — aggregate shift-point data from all completed `shift_points` sessions\\\n    - `GET /api/characteristics/cars` — list all cars with session_count + recommended_shift_rpm\\\n    - `GET /api/characteristics/cars/{car}` — detailed per-gear RPM/speed ranges\\\n    - Typed `Deserialize` view structs (`ShiftPointAnalysisView`, `GearCurveView`) for analysis JSON\\\n  - [x] **Remove obsolete `track_map` use case** — Superseded by `track_mapping` (track_map was the old analysis-only variant)\\\n    - Removed from `UseCase` enum, `analysis.rs` dispatch\\\n    - Removed from racecraft types, views, router\\\n    - Deleted `TrackMapView.vue` in racecraft\\\n  - [x] **racecraft: CharacteristicsView** — Expandable car cards with per-gear RPM/speed ranges\\\n    - `listCarProfiles()` API client function\\\n    - `CarProfile`, `CarGearProfile` TypeScript types\\\n    - Characteristics nav item + route\\\n  - [x] **racecraft: UX fix** — `handleBuildTrack` now auto-runs `reAnalyze()` before `buildTrackModel()`\\\n  - [x] **TelemetryFrame** — Added `Deserialize` derive (needed for session frame round-trip)\\\n  - [x] Documentation updated: READMEs, AGENTS.md (both repos)\\\n\\\n\"],[0,\"---\\\n\\\n## \"]],\"start1\":10500,\"start2\":10500,\"length1\":16,\"length2\":2188},{\"diffs\":[[0,\"------|\\\n\"],[1,\"| rusty-telemetry v0.7.0 | 2026-06-24 | Session persistence (split metadata/frames files, atomic writes, lazy load), car characteristics DB (`characteristics.rs`, 2 API endpoints), remove `track_map` use case, `Deserialize` on TelemetryFrame |\\\n| racecraft v0.1.5 | 2026-06-24 | CharacteristicsView (expandable car cards), tracks views committed, `track_map` removal, auto-analyze before build track model, API endpoint count updated (28) |\\\n\"],[0,\"| racecr\"]],\"start1\":14409,\"start2\":14409,\"length1\":16,\"length2\":456},{\"diffs\":[[0,\"-v0.\"],[-1,\"6\"],[1,\"7\"],[0,\".0\"],[-1,\" + track mapping\"],[0,\"):**\"]],\"start1\":16288,\"start2\":16288,\"length1\":27,\"length2\":11},{\"diffs\":[[0,\"REST API\"],[1,\" (28 endpoints)\"],[0,\" with re\"]],\"start1\":16549,\"start2\":16549,\"length1\":16,\"length2\":31},{\"diffs\":[[0,\"reopen),\"],[-1,\" basic\"],[0,\" analysi\"]],\"start1\":16657,\"start2\":16657,\"length1\":22,\"length2\":16},{\"diffs\":[[0,\" maps), \"],[-1,\"and \"],[0,\"track mo\"]],\"start1\":16695,\"start2\":16695,\"length1\":20,\"length2\":16},{\"diffs\":[[0,\"sistence\"],[1,\", and **car characteristics aggregation**\\\n- **Persistent sessions** — Session metadata, runs, analysis results, and frames survive server restart; lazy-loaded frames for fast startup; atomic writes\\\n- **Car characteristics database** — Aggregated shift-point profiles per car across all sessions (`characteristics.rs`, `GET /api/characteristics/cars`)\"],[0,\"\\\n- **Per\"]],\"start1\":16718,\"start2\":16718,\"length1\":16,\"length2\":366},{\"diffs\":[[0,\"arts, **\"],[1,\"car characteristics views**, \"],[0,\"track li\"]],\"start1\":17675,\"start2\":17675,\"length1\":16,\"length2\":45},{\"diffs\":[[0,\"endering\"],[-1,\"**\"],[0,\"\\\n- Ring \"]],\"start1\":17764,\"start2\":17764,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"From v0.\"],[-1,\"6\"],[1,\"7\"],[0,\".0 to Se\"]],\"start1\":23177,\"start2\":23177,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"t v0.1.4) |\\\n\"],[1,\"| **A3b: ~~Session persistence + characteristics~~ ✅ DONE** | Persistent sessions, car characteristics DB, track_map removal | Shipped 2026-06-24 (v0.7.0 / v0.1.5) |\\\n\"],[0,\"| **A4: WebS\"]],\"start1\":23666,\"start2\":23666,\"length1\":24,\"length2\":190},{\"diffs\":[[0,\".1.4)\\\n3.\"],[1,\" ~~Ship session persistence + characteristics~~ ✅ DONE (2026-06-24 — v0.7.0 / v0.1.5)\\\n4.\"],[0,\" **Verif\"]],\"start1\":27645,\"start2\":27645,\"length1\":16,\"length2\":104},{\"diffs\":[[0,\"-to-end\\\n\"],[-1,\"4\"],[1,\"5\"],[0,\". **Add \"]],\"start1\":27807,\"start2\":27807,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"ne data\\\n\"],[-1,\"5\"],[1,\"6\"],[0,\". **Buil\"]],\"start1\":27869,\"start2\":27869,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"feature\\\n\"],[-1,\"6\"],[1,\"7\"],[0,\". **Purc\"]],\"start1\":27939,\"start2\":27939,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"n sale)\\\n\"],[-1,\"7\"],[1,\"8\"],[0,\". **Impl\"]],\"start1\":28020,\"start2\":28020,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\" effort\\\n\"],[-1,\"8\"],[1,\"9\"],[0,\". **Rese\"]],\"start1\":28098,\"start2\":28098,\"length1\":17,\"length2\":17},{\"diffs\":[[0,\"rs work\\\n\"],[-1,\"9\"],[1,\"10\"],[0,\". **Draf\"]],\"start1\":28177,\"start2\":28177,\"length1\":17,\"length2\":18},{\"diffs\":[[0,\"Status (2026-06-\"],[-1,\"08\"],[1,\"24\"],[0,\"):** Steps 1–2 p\"]],\"start1\":30000,\"start2\":30000,\"length1\":34,\"length2\":34},{\"diffs\":[[0,\"2026-06-23**\"],[1,\" (partner verified 2026-06-23)\"],[0,\"\\\n> **Context\"]],\"start1\":39706,\"start2\":39706,\"length1\":24,\"length2\":54},{\"diffs\":[[0,\"h via a \"],[1,\"**\"],[0,\"local pa\"]],\"start1\":39964,\"start2\":39964,\"length1\":16,\"length2\":18},{\"diffs\":[[0,\" partner\"],[1,\": Styria Karting (Kalsdorf/Zettling, Styria)**\"],[0,\".\\\n\\\n### 1\"]],\"start1\":39979,\"start2\":39979,\"length1\":16,\"length2\":62},{\"diffs\":[[0,\"9.3 \"],[-1,\"Go-To-Market:\"],[1,\"Anchor\"],[0,\" Partner\"],[-1,\" with \"],[1,\": Styri\"],[0,\"a Ka\"]],\"start1\":42049,\"start2\":42049,\"length1\":35,\"length2\":29},{\"diffs\":[[0,\"ing \"],[-1,\"Venue\\\n\\\nA single anchor venue gives us real data, a test bed, credibility, and a first di\"],[1,\"(VERIFIED)\\\n\\\n> **Partner confirmed:** https://styriakarting.at/ — StyriaKarting, \\\"Ihre Kartstrecken in Graz Umgebung\\\" (Kalsdorf / Zettling, Styria, Austria).\\\n\\\n**Why this is an ideal pilot partner:**\\\n\\\n| Attribute | Detail |\\\n|---|---|\\\n| **Operator** | StyriaKarting (Styria Karting) — regional karting operator, Graz Umgebung |\\\n| **Website** | https://\"],[0,\"st\"],[1,\"y\"],[0,\"ri\"],[-1,\"bution channel. **Styria Karting** (Steiermark / Styria region, Austria) is identified as a strong candidate partner. (Note: exact venue identity, scale, and contact details need to be verified — capture the lead and research the spec\"],[1,\"akarting.at/ |\\\n| **Locations** | Two sites: **Indoor** (Feldkirchenstraße 30, 8401 Kalsdorf) and **Outdoor** (Industriestraße 39, 8401 Zettling) |\\\n| **Tracks (4 layouts)** | **Outdoor Spielberg** — 380 m, 200 cc 6.5 PS rental karts, +2 kids karts + double-seater. **Outdoor Nordschleife** — 13 PS 390 cc sport karts, ages 16+. **Outdoor Le Mans** — Spielberg + Nordschleife combined = **1,260 m**, 13 PS sport karts. **Indoor** — 290 m covered (with outdoor section), 200 cc 6.5 PS. |\\\n| **Audience breadth** | Families, friends, corporate events, birthdays (casual) AND beginners/amateurs/pros (competitive) — see below |\\\n| **Race program** | \\\"Mindestens 2 Rennen pro Woche\\\" (≥2 races/week); free practice sessions; beginner/amateur/pro categories |\\\n| **Timing infra** | Already publishes **Ergebnisse (results)** on the site → they already run timing/transponder systems (likely MYLAPS-style). This is critical: a data layer already exists we could enrich. |\\\n| **Motorsportclub** | Affiliated **Styria Karting Motorsportclub** (https://styriakarting-motorsportclub.at/) — structured competitive community, ideal coaching cohort |\\\n| **Contact** | office@styriakarting.at (outdoor) / indoor@styriakarting.at; outdoor +43 3135 56 8 76 / indoor +43 3135 57 890 |\\\n| **Season** | Outdoor Mar–Oct; Indoor year-round (14:00–22:00 wk / 11:00–22:00 wknd) |\\\n| **Why it fits** | Local → low-friction, in-person testing; multi-layout venue (small rental → full 1.2 km sport kart) lets us validate across d\"],[0,\"if\"],[1,\"f\"],[0,\"ic\"],[-1,\" operator.)\"],[1,\"ulty levels; existing timing + a motorsport club give us a ready user base and a baseline to compare our analysis against |\"],[0,\"\\\n\\\n##\"]],\"start1\":42080,\"start2\":42080,\"length1\":349,\"length2\":1983},{\"diffs\":[[0,\"arting P\"],[-1,\"artnership\"],[1,\"ilot\"],[0,\" — Conce\"]],\"start1\":44087,\"start2\":44087,\"length1\":26,\"length2\":20},{\"diffs\":[[0,\"ng (\"],[-1,\"regional karting venue/operator in Styria, Aust\"],[1,\"Kalsdorf/Zettling, Sty\"],[0,\"ria)\"]],\"start1\":44171,\"start2\":44171,\"length1\":55,\"length2\":30},{\"diffs\":[[0,\"sessions\"],[1,\" (motorsport club members)\"],[0,\"; venue \"]],\"start1\":44306,\"start2\":44306,\"length1\":16,\"length2\":42},{\"diffs\":[[0,\" channel\"],[1,\"; existing timing data to validate against\"],[0,\" |\\\n| **W\"]],\"start1\":44363,\"start2\":44363,\"length1\":16,\"length2\":58},{\"diffs\":[[0,\"eports; \"],[-1,\"t\"],[1,\"**T\"],[0,\"rack\"],[-1,\" m\"],[1,\"M\"],[0,\"odels of\"]],\"start1\":44530,\"start2\":44530,\"length1\":23,\"length2\":24},{\"diffs\":[[0,\" of \"],[-1,\"their circuits |\\\n| **Pilot scope** | 1 track, ~10–20\"],[1,\"all 4 layouts** (esp. the 1,260 m Le Mans layout); CSV/post-session summaries |\\\n| **Pilot scope** | 1 track first (recommend Le Mans — longest, most corners, best coaching value), ~10–20 motorsport-club\"],[0,\" dri\"]],\"start1\":44551,\"start2\":44551,\"length1\":60,\"length2\":210},{\"diffs\":[[0,\"emetry (\"],[1,\"external \"],[0,\"GPS + en\"]],\"start1\":44801,\"start2\":44801,\"length1\":16,\"length2\":25},{\"diffs\":[[0,\"put vs. \"],[-1,\"perceived value\"],[1,\"venue's published lap times\"],[0,\" |\\\n| **V\"]],\"start1\":44877,\"start2\":44877,\"length1\":31,\"length2\":43},{\"diffs\":[[0,\"ing data\"],[1,\" with cheap hardware\"],[0,\"? (2) Do\"]],\"start1\":44970,\"start2\":44970,\"length1\":16,\"length2\":36},{\"diffs\":[[0,\"tionable\"],[1,\" vs. their own feel\"],[0,\"? (3) Do\"]],\"start1\":45035,\"start2\":45035,\"length1\":16,\"length2\":35},{\"diffs\":[[0,\"isition?\"],[1,\" (4) Do our theoretical-best-lap / sector deltas align with their existing timing?\"],[0,\" |\\\n| **C\"]],\"start1\":45122,\"start2\":45122,\"length1\":16,\"length2\":98},{\"diffs\":[[0,\"ecraft\\\" \"],[-1,\"for\"],[1,\"on\"],[0,\" the ven\"]],\"start1\":45323,\"start2\":45323,\"length1\":19,\"length2\":18},{\"diffs\":[[0,\"he venue\"],[1,\" site\"],[0,\"; freemi\"]],\"start1\":45335,\"start2\":45335,\"length1\":16,\"length2\":21},{\"diffs\":[[0,\"ell \"],[-1,\"|\\\n| **Why Styria** | Local/regional → low-friction relationship; poten\"],[1,\"(coaching reports, video overlay) |\\\n| **Differentiator to pitch** | Their current timing = lap times only. We add **line, braking, consistency, theore\"],[0,\"ti\"],[1,\"c\"],[0,\"al \"],[-1,\"for in-person testing; Austrian motorsport ecosystem (Red Bull Ring proximity, karting tradition)\"],[1,\"best lap** — the analysis layer their timing system lacks. Cheap (phone + 10 Hz GPS) vs. Aim/Unipro gear.\"],[0,\" |\\\n\\\n\"]],\"start1\":45390,\"start2\":45390,\"length1\":180,\"length2\":269},{\"diffs\":[[0,\". **\"],[-1,\"Verify the partner:** Identify the exact S\"],[1,\"Reach out to Styria Karting** — contact via office@s\"],[0,\"tyria\"],[-1,\" K\"],[1,\"k\"],[0,\"arting\"],[-1,\" venue/operator, scale, facilities, and a contact\"],[1,\".at; pitch the free pilot + venue-branded leaderboard (no hardware cost to them)\"],[0,\". \"],[-1,\"(\"],[0,\"Lead \"],[-1,\"captured from this session; research needed.)\"],[1,\"with the motorsport club cohort.\"],[0,\"\\\n2. \"]],\"start1\":45707,\"start2\":45707,\"length1\":165,\"length2\":191},{\"diffs\":[[0,\"ture\"],[-1,\":** Decide\"],[1,\" MVP** —\"],[0,\" min\"]],\"start1\":45923,\"start2\":45923,\"length1\":18,\"length2\":16},{\"diffs\":[[0,\"ble \"],[-1,\"data \"],[0,\"source\"],[1,\":\"],[0,\" \"],[-1,\"for karts (\"],[0,\"exte\"]],\"start1\":45947,\"start2\":45947,\"length1\":31,\"length2\":16},{\"diffs\":[[0,\"ckup\"],[-1,\")\"],[0,\". De\"],[-1,\"termine whether\"],[1,\"cide\"],[0,\" pho\"]],\"start1\":45993,\"start2\":45993,\"length1\":28,\"length2\":16},{\"diffs\":[[0,\"tyle\"],[-1,\") or a small logger is needed.\\\n3\"],[1,\", §18) vs. small logger. Note the Indoor track is covered — GPS may be unreliable there; prioritize Outdoor (Spielberg/Nordschleife/Le Mans).\\\n3. **Build TrackModels for the 4 layouts** — once access is granted, run our boundary-recording method on each layout (esp. Le Mans 1,260 m). This also seeds our community track library (§18.4).\\\n4\"],[0,\". **\"]],\"start1\":46039,\"start2\":46039,\"length1\":40,\"length2\":346},{\"diffs\":[[0,\"al**\"],[-1,\" for the venue\"],[0,\" (fr\"]],\"start1\":46414,\"start2\":46414,\"length1\":22,\"length2\":8},{\"diffs\":[[0,\"are)\"],[-1,\".\\\n4. **Re-tag** relevant notes (karting, partnership) once the partner is confirmed\"],[1,\" tailored to their race nights\"],[0,\".\\\n5.\"]],\"start1\":46465,\"start2\":46465,\"length1\":91,\"length2\":38},{\"diffs\":[[0,\"ly.\\\n\"],[-1,\"\\\n---\\\n\\\n*Last updated: 2026-06-23 — Added §18 (RaceChrono inspiration & feature ideas) and §19 (Karting market + Styria Karting partnership). racecraft v0.1.4: Track mapping web client with persistent track model views, Canvas 2D geometry rendering (curvature heat map, corner markers, sector shading), t\"],[1,\"6. **Investigate their timing system** — confirm what transponder/timing they use (results page implies MYLAPS/AMB-style) so we can integrate/compare rather than duplicate.\\\n\\\n---\\\n\\\n*Last updated: 2026-06-24 — v0.7.0 (rusty-telemetry) + v0.1.5 (racecraft): Session persistence (split metadata/frames, lazy load, atomic writes, off-thread serialization), car characteristics DB (`characteristics.rs`, 2 API endpoints), removed obsolete `track_map` use case, CharacteristicsView + CharacteristicsView, T\"],[0,\"rack\"],[-1,\" API integration, build track model workflow\"],[1,\"sView/TrackDetailView committed, auto-analyze before build track model, READMEs + AGENTS.md updated\"],[0,\". Up\"]],\"start1\":46617,\"start2\":46617,\"length1\":358,\"length2\":609},{\"diffs\":[[0,\"ed §8, §\"],[1,\"9 (\"],[0,\"1.1\"],[-1,\"1\"],[1,\"2)\"],[0,\", §15, §\"]],\"start1\":47229,\"start2\":47229,\"length1\":20,\"length2\":24},{\"diffs\":[[0,\"§17.\"],[-1,\"1, §17.2, §17.4, §17.5, §17.10\"],[1,\"2\"],[0,\".*\\\n*\"]],\"start1\":47274,\"start2\":47274,\"length1\":38,\"length2\":9},{\"diffs\":[[0,\".0, \"],[-1,\"research\"],[1,\"contact\"],[0,\" Sty\"]],\"start1\":47358,\"start2\":47358,\"length1\":16,\"length2\":15},{\"diffs\":[[0,\"Karting \"],[-1,\"partner\"],[1,\"for pilot\"],[0,\".*\"]],\"start1\":47377,\"start2\":47377,\"length1\":17,\"length2\":19}]"
metadata_diff: {"new":{},"deleted":[]}
encryption_cipher_text: 
encryption_applied: 0
updated_time: 2026-06-24T07:57:22.555Z
created_time: 2026-06-24T07:57:22.555Z
type_: 13