Archive the monolithic route-features spec and replace with 9 focused OpenSpec changes: multi-day-routes, waypoint-notes (with POI snapping), undo-redo, local-dev-stack, route-sharing, route-discovery, activity-photos, osm-overlays, plus the existing changelog and komoot-import. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2.9 KiB
Context
The architecture doc defines a rich route model with permissions, multi-day support, spatial queries, and photos. Currently routes are owner-only, flat (no days), and have no photos or spatial search. This change adds the route and activity features needed before federation makes them visible to others.
Goals / Non-Goals
Goals:
- Route visibility (private/public) and sharing with specific users
- Fork public routes
- Multi-day route support with day-break waypoints
- Map-based route discovery via PostGIS
- Photo attachments on activities
- Contributor tracking on route versions
Non-Goals:
- Federation of routes (separate change)
- Real-time collaborative permission changes
- Photo editing or filters
- Route recommendations based on preferences
- Activity collections (multi-day trip grouping — future)
Decisions
D1: Visibility as enum column on routes and activities
Add visibility column (public, private, default private) to both
routes and activities. followers_only added later when following exists.
Public routes appear in spatial search. Private routes are owner-only.
D2: Route shares table for explicit sharing
journal.route_shares (routeId, userId, permission: 'view' | 'edit')
Owner can share with specific users. Shared users see the route in their "Shared with me" section. Edit permission allows starting Planner sessions.
D3: Day breaks as waypoint property
The Planner's Yjs waypoint Y.Map gets an optional isDayBreak: true field.
The sidebar and elevation chart show day boundaries. GPX export uses one
track segment per day. The Journal stores day-break indices in route metadata.
D4: PostGIS spatial search
Routes already store geometry as PostGIS LineString. Add a /routes/explore
page with a map — as the user pans/zooms, query public routes within the
bounding box using ST_Intersects. Show route previews on the map.
D5: Photo storage via S3 (Garage)
Use the Garage S3-compatible storage already in the architecture. Upload flow:
server generates presigned PUT URL → client uploads directly to S3 → server
stores the S3 key in a journal.activity_photos table. Serve via presigned
GET URLs or a CDN path.
D6: Contributor tracking via array column
Add contributors text array to journal.route_versions. When a Planner
session saves back via callback, the JWT identifies the actor. The version
records the contributor's user ID (or ActivityPub URI for future federation).
Risks / Trade-offs
- S3 setup required → Garage needs to be enabled in docker-compose (currently commented out). Adds operational complexity.
- Spatial search performance → PostGIS bounding box queries are fast with spatial indexes. Already have the geometry column.
- Multi-day in Planner requires Yjs changes → Adding
isDayBreakto waypoints is backward-compatible (optional field). Existing sessions unaffected.