Archive journal-poi-details change; sync journal-route-detail spec

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Ullrich Schäfer 2026-05-17 23:33:37 +02:00
parent 861701e881
commit faf2227896
No known key found for this signature in database
GPG key ID: A32FF691A0F752D9
6 changed files with 20 additions and 0 deletions

View file

@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-04-11

View file

@ -0,0 +1,88 @@
# Design: Journal POI Details
## Data Flow
POI metadata already flows from Overpass → POI snap → Yjs Y.Map (`osmId`, `poiTags`). The gap is that neither GPX export nor the Journal save extracts these fields.
```
Yjs Y.Map
{ lat, lon, name, overnight, osmId, poiTags: { phone, website, ... } }
↓ (currently drops osmId + poiTags)
Waypoint type → generateGpx → GPX <wpt>
Journal DB → route.gpx
↓ (currently not parsed)
Journal route detail page
```
## Changes
### 1. `@trails-cool/types` — extend `Waypoint`
Add optional POI fields to the shared `Waypoint` interface:
```ts
export interface Waypoint {
lat: number;
lon: number;
name?: string;
isDayBreak?: boolean;
osmId?: number;
poiTags?: {
phone?: string;
website?: string;
opening_hours?: string;
"addr:street"?: string;
"addr:housenumber"?: string;
"addr:postcode"?: string;
"addr:city"?: string;
amenity?: string;
tourism?: string;
shop?: string;
};
}
```
### 2. Planner — extract `osmId` + `poiTags` from Yjs
In `ExportButton.tsx` and `SaveToJournalButton.tsx`, add the two fields to the waypoint mapping:
```ts
osmId: yMap.get("osmId") as number | undefined,
poiTags: yMap.get("poiTags") as Waypoint["poiTags"] | undefined,
```
### 3. GPX — encode/decode POI fields as `<extensions>`
**`generate.ts`**: When a waypoint has `osmId` or `poiTags`, emit a `<extensions><trails:poi ...>` block inside `<wpt>`. Always declare the `trails:` namespace on the root `<gpx>` element (already done for noGoAreas, just extend the condition).
```xml
<wpt lat="52.5" lon="13.4">
<name>Fahrradhändler Müller</name>
<extensions>
<trails:poi osmId="123456">
<trails:tag k="phone" v="+49 30 12345"/>
<trails:tag k="website" v="https://example.com"/>
<trails:tag k="opening_hours" v="Mo-Fr 09:00-18:00"/>
</trails:poi>
</extensions>
</wpt>
```
**`parse.ts`**: In `parseWaypoints`, query `trails:poi` (and unprefixed `poi`) extensions; read the `osmId` attribute and `trails:tag` children.
### 4. Journal route detail — display POI metadata
In `routes.$id.tsx`:
- Parse waypoints from `route.gpx` in the loader (already done for `dayStats`, can reuse that parse)
- Pass waypoints with POI data to the component
- Render a `WaypointList` section showing: waypoint name + coords, and if `poiTags` present: phone (tel: link), website (https: link), opening hours, address
No new DB columns needed — everything lives in the GPX string already stored in `routes.gpx`.
## Non-Goals
- No new DB columns for POI data
- No Overpass lookups in the Journal
- No display of `osmId` to the user (internal reference only)
- Opening hours parsing/formatting: display raw string as-is

View file

@ -0,0 +1,23 @@
## Why
Waypoints snapped to POIs in the Planner store OSM metadata (osmId, phone, address, website, opening hours) on the Yjs Y.Map. This data travels through GPX export and Journal save but is never displayed. When planning a multi-day bike tour, seeing campsite contact details, water point locations, or bike shop opening hours on the Journal route detail page would be valuable.
## What Changes
- **GPX export with POI metadata**: Include osmId and key tags as GPX waypoint extensions so they survive the GPX roundtrip
- **Journal route detail**: Show POI details (phone, address, website, opening hours) for waypoints that have POI metadata
- **Journal waypoint list**: Display POI icons and names alongside waypoint coordinates
## Capabilities
### Modified Capabilities
- `gpx-export`: Waypoint extensions for POI metadata
- `journal-route-detail`: POI details display for waypoints
- `route-management`: Store and retrieve POI metadata
## Impact
- `packages/gpx/src/generate.ts`: Add GPX extensions for POI tags
- `packages/gpx/src/parse.ts`: Parse POI extensions back
- `apps/journal/app/routes/routes.$id.tsx`: Display POI details per waypoint
- `@trails-cool/types`: Extend Waypoint type with optional POI fields

View file

@ -0,0 +1,16 @@
## MODIFIED Requirements
### Requirement: POI metadata on route detail waypoints
The Journal route detail page SHALL display POI metadata (phone, address, website, opening hours) for waypoints that have associated OpenStreetMap POI data.
#### Scenario: POI metadata displayed on waypoints
- **WHEN** a route detail page is loaded and a waypoint has POI metadata from the Planner
- **THEN** the waypoint displays the POI name, icon, and category alongside its coordinates
#### Scenario: Phone, address, and website shown
- **WHEN** a waypoint has POI metadata including phone, address, or website
- **THEN** those details are shown in the waypoint detail section with appropriate links (tel: for phone, mailto: or https: for website)
#### Scenario: Waypoints without POI data display normally
- **WHEN** a waypoint on the route detail page has no associated POI metadata
- **THEN** the waypoint displays as before with coordinates and name only, with no empty POI sections shown

View file

@ -0,0 +1,11 @@
# Tasks: Journal POI Details
- [x] Extend `Waypoint` type in `packages/types/src/index.ts` with `osmId` and `poiTags` fields
- [x] Extract `osmId` and `poiTags` from Yjs Y.Map in `apps/planner/app/components/ExportButton.tsx`
- [x] Extract `osmId` and `poiTags` from Yjs Y.Map in `apps/planner/app/components/SaveToJournalButton.tsx`
- [x] Encode POI fields as `<trails:poi>` extensions in `packages/gpx/src/generate.ts`
- [x] Parse `<trails:poi>` extensions back into waypoints in `packages/gpx/src/parse.ts`
- [x] Add unit tests for GPX POI encode/decode roundtrip in `packages/gpx/src/`
- [x] Pass parsed waypoints with POI data from the loader in `apps/journal/app/routes/routes.$id.tsx`
- [x] Render POI details (phone, website, opening hours, address) for waypoints in the Journal route detail page
- [x] Add i18n keys for POI section labels (phone, website, opening hours, address)