From d6982db868b6a75dec4ab2b26505a862d4c90af0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ullrich=20Sch=C3=A4fer?= Date: Sat, 11 Apr 2026 03:24:54 +0200 Subject: [PATCH] Update specs: session-notes, route-coloring, gpx-import session-notes: Reflect CodeMirror 6 editor with character-level sync, remote cursor awareness, dedicated undo manager, awareness isolation. route-coloring: Added grade color mode, moved toggle to chart, added surface/grade chart coloring, legends for all modes, contextual hover. gpx-import: Added day break preservation (overnight waypoints survive GPX roundtrip). Co-Authored-By: Claude Opus 4.6 (1M context) --- openspec/specs/gpx-import/spec.md | 12 +++++++ openspec/specs/route-coloring/spec.md | 48 ++++++++++++++++++++++++--- openspec/specs/session-notes/spec.md | 32 ++++++++++++++---- 3 files changed, 81 insertions(+), 11 deletions(-) diff --git a/openspec/specs/gpx-import/spec.md b/openspec/specs/gpx-import/spec.md index f066bff..e9d7222 100644 --- a/openspec/specs/gpx-import/spec.md +++ b/openspec/specs/gpx-import/spec.md @@ -40,3 +40,15 @@ The Planner SHALL reject non-GPX files dropped on the map. #### Scenario: Drop non-GPX file - **WHEN** a user drops a non-GPX file on the map - **THEN** the file is ignored with a brief error toast + +### Requirement: Day break preservation +GPX import SHALL preserve overnight waypoint metadata for multi-day routes. + +#### Scenario: Import GPX with overnight waypoints +- **WHEN** a GPX file contains waypoints with `overnight` +- **THEN** the imported waypoints have their `isDayBreak` / `overnight` flag set in Yjs +- **AND** the day breakdown appears in the sidebar + +#### Scenario: Import GPX with POI metadata +- **WHEN** a GPX file contains waypoints imported from POI snap (with name) +- **THEN** the waypoint name is preserved on import diff --git a/openspec/specs/route-coloring/spec.md b/openspec/specs/route-coloring/spec.md index be460ea..dfb2c07 100644 --- a/openspec/specs/route-coloring/spec.md +++ b/openspec/specs/route-coloring/spec.md @@ -1,6 +1,6 @@ ## Purpose -Multi-mode route visualization (plain, elevation gradient, surface type) with session-synced color mode selection. +Multi-mode route visualization (plain, elevation gradient, surface type, grade) with session-synced color mode selection. Both the route polyline on the map and the elevation chart reflect the selected color mode. ## Requirements @@ -9,7 +9,7 @@ The Planner SHALL support multiple route color modes that visualize per-point da #### Scenario: Default plain mode - **WHEN** a route is first displayed -- **THEN** it renders as a single-color blue polyline (current behavior) +- **THEN** it renders as a single-color blue polyline #### Scenario: Elevation color mode - **WHEN** a user selects the "Elevation" color mode @@ -23,24 +23,62 @@ The Planner SHALL support multiple route color modes that visualize per-point da - **WHEN** a user selects "Surface" color mode but BRouter did not return surface data - **THEN** the route falls back to plain color mode +#### Scenario: Grade color mode +- **WHEN** a user selects the "Grade" color mode +- **THEN** the route polyline is colored by steepness: green (<3%), yellow (<6%), orange (<10%), red (<15%), dark red (15%+) + ### Requirement: Color mode toggle The Planner SHALL provide a UI control to switch between route color modes. #### Scenario: Toggle control location - **WHEN** a route is displayed -- **THEN** a color mode select dropdown is visible in the session header +- **THEN** a color mode select dropdown is visible inline with the elevation chart title #### Scenario: Color mode persists in session - **WHEN** a user changes the color mode - **THEN** the selection is stored in the Yjs routeData map and synced to all participants ### Requirement: Elevation chart color sync -The elevation profile chart SHALL use the same color gradient as the route when in elevation mode. +The elevation profile chart SHALL use the same coloring as the route for each color mode. #### Scenario: Elevation mode chart coloring - **WHEN** the color mode is set to "Elevation" - **THEN** the elevation chart line and fill use the same green→yellow→red gradient as the route polyline +#### Scenario: Surface mode chart coloring +- **WHEN** the color mode is set to "Surface" and surface data is available +- **THEN** the elevation chart segments are colored by surface type, matching the route + +#### Scenario: Grade mode chart coloring +- **WHEN** the color mode is set to "Grade" +- **THEN** the elevation chart segments are colored by steepness, matching the route + #### Scenario: Plain mode chart coloring -- **WHEN** the color mode is "Plain" or "Surface" +- **WHEN** the color mode is "Plain" - **THEN** the elevation chart uses the default blue color + +### Requirement: Color legends +The elevation chart SHALL display a legend matching the active color mode. + +#### Scenario: Grade legend +- **WHEN** the color mode is "Grade" +- **THEN** the legend shows colored swatches with percentage thresholds (<3%, <6%, <10%, <15%, 15%+) + +#### Scenario: Elevation legend +- **WHEN** the color mode is "Elevation" +- **THEN** the legend shows a gradient bar with the route's minimum and maximum elevation in meters + +#### Scenario: Surface legend +- **WHEN** the color mode is "Surface" +- **THEN** the legend shows the surface types present in the route with colored swatches + +### Requirement: Contextual hover information +The elevation chart hover label SHALL show mode-specific information. + +#### Scenario: Grade hover +- **WHEN** hovering the chart in "Grade" mode +- **THEN** the label shows elevation, distance, and grade percentage (e.g. "340m · 12.3km · +4.2%") + +#### Scenario: Surface hover +- **WHEN** hovering the chart in "Surface" mode +- **THEN** the label shows elevation, distance, and surface type name (e.g. "340m · 12.3km · asphalt") diff --git a/openspec/specs/session-notes/spec.md b/openspec/specs/session-notes/spec.md index 1c206c2..9399e89 100644 --- a/openspec/specs/session-notes/spec.md +++ b/openspec/specs/session-notes/spec.md @@ -1,16 +1,36 @@ ## Purpose -Collaborative text notes in Planner sessions, synced in real-time via Yjs. +Collaborative rich text notes in Planner sessions, powered by CodeMirror 6 with Yjs CRDT sync and real-time cursor awareness. ## Requirements ### Requirement: Collaborative session notes -Planner sessions SHALL have a shared text area for participants to write notes. +Planner sessions SHALL have a shared text editor for participants to write notes, with character-level real-time sync. #### Scenario: Write notes -- **WHEN** a user types in the notes area -- **THEN** the text syncs in real-time to all other participants via Yjs +- **WHEN** a user types in the notes editor +- **THEN** the text syncs character-by-character to all other participants via Yjs Y.Text -#### Scenario: Notes persist +#### Scenario: Remote cursor awareness +- **WHEN** multiple participants are editing notes +- **THEN** each participant sees the others' cursor positions and selections highlighted in their assigned color with their name label + +#### Scenario: Notes persist across reload +- **WHEN** a participant reloads the session page +- **THEN** the notes content is restored from the Yjs document +- **AND** the editor displays the existing text immediately + +#### Scenario: Notes persist across reconnect - **WHEN** a user leaves and rejoins a session -- **THEN** the notes are still there (stored in Yjs doc) +- **THEN** the notes are still there (stored in Yjs doc and crash recovery) + +### Requirement: Editor implementation +The notes editor SHALL use CodeMirror 6 with y-codemirror.next for Yjs binding. + +#### Scenario: Undo/redo +- **WHEN** a user presses Ctrl+Z / Ctrl+Shift+Z in the notes editor +- **THEN** undo/redo applies to notes only (separate Y.UndoManager from waypoint undo) + +#### Scenario: Awareness field isolation +- **WHEN** the notes editor sets cursor awareness state +- **THEN** it does not conflict with map cursor awareness (uses separate awareness fields)