diff --git a/openspec/changes/activity-photos/specs/activity-photos/spec.md b/openspec/changes/activity-photos/specs/activity-photos/spec.md new file mode 100644 index 0000000..aa24477 --- /dev/null +++ b/openspec/changes/activity-photos/specs/activity-photos/spec.md @@ -0,0 +1,52 @@ +## ADDED Requirements + +### Requirement: Photo upload via presigned URLs +Users SHALL be able to upload photos to an activity using presigned PUT URLs, with client-side image processing before upload. + +#### Scenario: Upload photo +- **WHEN** a user selects a photo on the activity detail page +- **THEN** the client resizes the image (max 2048px long edge), strips EXIF data, converts to WebP +- **AND** requests a presigned PUT URL from `POST /api/activities/:id/photos` +- **AND** uploads directly to Garage (S3-compatible storage) +- **AND** confirms the upload via `PATCH /api/activities/:id/photos/:photoId` + +#### Scenario: Size limit enforced +- **WHEN** a processed photo exceeds 5 MB +- **THEN** the presigned URL rejects the upload via content-length condition + +#### Scenario: Per-activity photo limit +- **WHEN** an activity already has 20 photos +- **THEN** the server rejects new presigned URL requests + +### Requirement: Photo gallery display +The activity detail page SHALL display uploaded photos in a responsive grid with lightbox viewing. + +#### Scenario: Gallery grid +- **WHEN** a user views an activity with photos +- **THEN** photos are displayed in a responsive grid (1 column mobile, 2 tablet, 3 desktop) with lazy loading + +#### Scenario: Lightbox view +- **WHEN** a user clicks a photo in the gallery +- **THEN** a full-size lightbox overlay opens with left/right navigation and close on escape + +### Requirement: Photo deletion +Activity owners SHALL be able to delete photos with soft delete and background S3 cleanup. + +#### Scenario: Delete photo +- **WHEN** a user clicks the delete icon on a photo +- **THEN** the photo status is set to 'deleted' and it disappears from the UI +- **AND** the S3 object is cleaned up on next page load or periodic cleanup + +### Requirement: Photo storage infrastructure +Photos SHALL be stored in Garage (S3-compatible, self-hosted) running as a Docker container. + +#### Scenario: Garage container +- **WHEN** docker compose starts +- **THEN** a Garage container is running with an `activity-photos` bucket + +### Requirement: Photo privacy disclosure +Photo storage and EXIF handling SHALL be documented in the privacy manifest. + +#### Scenario: Privacy page updated +- **WHEN** a user visits the privacy page +- **THEN** it documents photo storage location, EXIF stripping, and deletion behavior diff --git a/openspec/changes/local-dev-stack/specs/local-dev-environment/spec.md b/openspec/changes/local-dev-stack/specs/local-dev-environment/spec.md new file mode 100644 index 0000000..af699e6 --- /dev/null +++ b/openspec/changes/local-dev-stack/specs/local-dev-environment/spec.md @@ -0,0 +1,29 @@ +## MODIFIED Requirements + +### Requirement: Optional local monitoring stack +The dev environment SHALL support an optional monitoring profile matching the production stack. + +#### Scenario: Start with monitoring +- **WHEN** a developer runs `pnpm dev:full` with `--profile monitoring` +- **THEN** Prometheus, Grafana, and Loki start alongside the app services + +### Requirement: Production-aligned PostgreSQL config +The dev PostgreSQL SHALL match production configuration including pg_stat_statements. + +#### Scenario: pg_stat_statements available +- **WHEN** the dev PostgreSQL container starts +- **THEN** pg_stat_statements is enabled via initialization scripts + +### Requirement: Database seed script +The dev environment SHALL provide a seed script for consistent test data. + +#### Scenario: Seed database +- **WHEN** a developer runs the seed script +- **THEN** test users, routes, and activities are created in the local database + +### Requirement: Dev environment reset +The dev environment SHALL provide a command to tear down and recreate the local stack. + +#### Scenario: Reset dev environment +- **WHEN** a developer runs `pnpm dev:reset` +- **THEN** all Docker volumes are removed, containers are recreated, and the database is re-seeded diff --git a/openspec/changes/multi-day-routes/specs/multi-day-routes/spec.md b/openspec/changes/multi-day-routes/specs/multi-day-routes/spec.md new file mode 100644 index 0000000..45c50a4 --- /dev/null +++ b/openspec/changes/multi-day-routes/specs/multi-day-routes/spec.md @@ -0,0 +1,50 @@ +## ADDED Requirements + +### Requirement: Overnight waypoint markers +Any waypoint SHALL be toggleable as an overnight stop, creating day boundaries in the route. + +#### Scenario: Toggle overnight +- **WHEN** a user toggles the overnight flag on a waypoint +- **THEN** the waypoint's `overnight: true` flag is set in the Yjs document +- **AND** the route is visually divided into days at that point + +#### Scenario: Implicit day boundaries +- **WHEN** overnight stops are set +- **THEN** the first waypoint is the implicit start of Day 1 and the last waypoint is the implicit end of the final day + +### Requirement: Per-day statistics +The Planner SHALL compute and display distance, ascent, and estimated duration for each day. + +#### Scenario: Day stats computed +- **WHEN** a route has overnight waypoints +- **THEN** per-day distance, total ascent, and estimated duration are derived from segment boundaries and coordinates + +### Requirement: Day-aware sidebar +The sidebar SHALL group waypoints by day with collapsible sections and per-day stats. + +#### Scenario: Day breakdown +- **WHEN** a route has multiple days +- **THEN** waypoints are grouped under "Day 1", "Day 2", etc. with collapsible sections +- **AND** each section header shows day distance and ascent + +### Requirement: Elevation chart day dividers +The elevation chart SHALL show day boundaries as dashed vertical lines. + +#### Scenario: Day dividers on chart +- **WHEN** a route has multiple days +- **THEN** dashed vertical lines with "Day N" labels appear at each overnight waypoint position + +### Requirement: Map day labels +The map SHALL display day summary labels at day boundary waypoints. + +#### Scenario: Day labels on map +- **WHEN** a route has multiple days +- **THEN** white pill markers at day boundaries show "Day N . X km" + +### Requirement: Multi-day GPX export +Day structure SHALL be preserved in GPX exports via waypoint type elements. + +#### Scenario: Export multi-day route +- **WHEN** a user exports a plan with overnight waypoints +- **THEN** overnight waypoints include a `overnight` element in the GPX +- **AND** reimporting the GPX restores the day structure diff --git a/openspec/changes/route-discovery/specs/route-discovery/spec.md b/openspec/changes/route-discovery/specs/route-discovery/spec.md new file mode 100644 index 0000000..93264b9 --- /dev/null +++ b/openspec/changes/route-discovery/specs/route-discovery/spec.md @@ -0,0 +1,28 @@ +## ADDED Requirements + +### Requirement: Map-based route exploration +The Journal SHALL provide an explore page with a full-page map for browsing public routes by location. + +#### Scenario: Browse public routes +- **WHEN** a user visits `/routes/explore` +- **THEN** a full-page Leaflet map is displayed +- **AND** public routes within the current viewport are shown as clickable polylines + +#### Scenario: Route popup +- **WHEN** a user clicks a route polyline on the explore map +- **THEN** a popup shows the route name, distance, elevation gain, author, and a link to the detail page + +### Requirement: Bounding box spatial query +The Journal SHALL provide an API endpoint for querying public routes by map viewport bounds. + +#### Scenario: Viewport query +- **WHEN** the map viewport changes +- **THEN** the client requests routes intersecting the current bounds via PostGIS `ST_Intersects` +- **AND** results are limited to 50 routes with simplified geometries + +### Requirement: Spatial index +The routes table SHALL have a GiST index on the geometry column for fast bounding box queries. + +#### Scenario: Index exists +- **WHEN** the database is set up +- **THEN** a GiST index on `journal.routes.geom` supports efficient spatial queries diff --git a/openspec/changes/route-sharing/specs/route-sharing/spec.md b/openspec/changes/route-sharing/specs/route-sharing/spec.md new file mode 100644 index 0000000..bd8fddf --- /dev/null +++ b/openspec/changes/route-sharing/specs/route-sharing/spec.md @@ -0,0 +1,38 @@ +## ADDED Requirements + +### Requirement: Route visibility +Routes and activities SHALL support private (default) and public visibility levels. + +#### Scenario: Set route public +- **WHEN** a route owner toggles visibility to "public" +- **THEN** the route is viewable by anyone with the link + +#### Scenario: Default private +- **WHEN** a new route is created +- **THEN** its visibility is "private" (owner-only) + +### Requirement: Per-user route sharing +Route owners SHALL be able to share routes with specific users at view or edit permission levels. + +#### Scenario: Share with user +- **WHEN** a route owner shares a route with another user at "view" level +- **THEN** the shared user sees the route in their collection and can view it + +#### Scenario: Edit permission +- **WHEN** a route owner shares a route with "edit" permission +- **THEN** the shared user can update the route name, description, and GPX + +### Requirement: Route forking +Logged-in users SHALL be able to fork any public route into their own collection. + +#### Scenario: Fork public route +- **WHEN** a user clicks "Fork" on a public route +- **THEN** a copy of the route metadata and latest GPX is created in their collection +- **AND** a `forkedFromId` link references the original route + +### Requirement: Contributor tracking +Route versions SHALL record the identity of the contributor who saved them. + +#### Scenario: Planner callback contributor +- **WHEN** the Planner saves back to the Journal via JWT callback +- **THEN** the contributor's identity is recorded on the new route version diff --git a/openspec/changes/visual-redesign/specs/design-system/spec.md b/openspec/changes/visual-redesign/specs/design-system/spec.md new file mode 100644 index 0000000..e01a1b8 --- /dev/null +++ b/openspec/changes/visual-redesign/specs/design-system/spec.md @@ -0,0 +1,40 @@ +## ADDED Requirements + +### Requirement: Design token system +The Planner SHALL use CSS custom properties for colors, typography, and spacing with Tailwind config extensions. + +#### Scenario: Consistent styling +- **WHEN** a component is styled +- **THEN** it uses project design tokens (warm off-whites, sage green accent, earthy tones) via Tailwind classes + +#### Scenario: Typography +- **WHEN** text is rendered +- **THEN** body text uses Outfit font and statistics use Geist Mono + +### Requirement: Redesigned topbar +The Planner topbar SHALL include a logo, segmented color mode toggle, participant avatars, and export controls. + +#### Scenario: Topbar layout +- **WHEN** a user is in a planning session +- **THEN** the topbar shows: logo with mountain mark, color mode toggle, participant avatars with names, and Export GPX button + +### Requirement: Redesigned sidebar +The Planner sidebar SHALL display a route summary header with stats, collapsible day breakdown, and waypoints nested inside days. + +#### Scenario: Route summary +- **WHEN** a route is computed +- **THEN** the sidebar header shows route name, distance, ascent, and estimated duration + +### Requirement: Redesigned map markers +Map waypoint markers SHALL use olive/dark numbered circles with overnight badges on stop waypoints. + +#### Scenario: Marker styling +- **WHEN** waypoints are displayed on the map +- **THEN** they appear as dark numbered circles instead of default blue markers + +### Requirement: Mobile responsive layout +The Planner SHALL use a bottom sheet pattern on mobile instead of a hidden sidebar. + +#### Scenario: Mobile view +- **WHEN** the Planner is viewed on a mobile device +- **THEN** a bottom sheet replaces the sidebar with swipeable tabs (Days/Waypoints/Notes) diff --git a/openspec/changes/waypoint-notes/specs/waypoint-notes/spec.md b/openspec/changes/waypoint-notes/specs/waypoint-notes/spec.md new file mode 100644 index 0000000..1a8e3d5 --- /dev/null +++ b/openspec/changes/waypoint-notes/specs/waypoint-notes/spec.md @@ -0,0 +1,46 @@ +## ADDED Requirements + +### Requirement: Per-waypoint text notes +Each waypoint SHALL support an optional plain-text note synced via Yjs. + +#### Scenario: Add note to waypoint +- **WHEN** a user clicks the note area under a waypoint in the sidebar and types text +- **THEN** the note is stored in the waypoint's Y.Map as a `note` string field +- **AND** auto-saves on blur + +#### Scenario: Note syncs to participants +- **WHEN** a user adds or edits a waypoint note +- **THEN** all other participants see the update in real-time via Yjs + +### Requirement: Map note indicators +Waypoint markers with notes SHALL show a visual indicator on the map. + +#### Scenario: Note icon on marker +- **WHEN** a waypoint has a note +- **THEN** its map marker shows a small note icon + +#### Scenario: Note tooltip +- **WHEN** a user hovers or taps a marker with a note +- **THEN** the note text appears in a tooltip + +### Requirement: Notes in GPX export +Waypoint notes SHALL be exported as `` elements in GPX output. + +#### Scenario: Export notes +- **WHEN** a user exports a plan with waypoint notes +- **THEN** each waypoint's note appears as a `` element in the GPX file + +### Requirement: Nearby POI display +When a waypoint is selected, nearby POIs from OpenStreetMap SHALL be shown on the map and in the sidebar. + +#### Scenario: POI lookup +- **WHEN** a user selects a waypoint +- **THEN** nearby POIs are fetched from the Overpass API and displayed as small markers on the map and as a list in the sidebar + +### Requirement: Snap waypoint to POI +Users SHALL be able to move a waypoint to a nearby POI's exact coordinates. + +#### Scenario: Snap to POI +- **WHEN** a user clicks a nearby POI +- **THEN** the waypoint moves to the POI's coordinates +- **AND** the POI's name and type are added as a note prefix (e.g., "Campsite - Waldcamp Fichtelberg") diff --git a/openspec/specs/account-settings/spec.md b/openspec/specs/account-settings/spec.md index e323676..385c578 100644 --- a/openspec/specs/account-settings/spec.md +++ b/openspec/specs/account-settings/spec.md @@ -1,4 +1,8 @@ -## MODIFIED Requirements +## Purpose + +User account settings page with connected services management, profile editing, and security controls. + +## Requirements ### Requirement: Connected Services section The settings page SHALL include a "Connected Services" section for managing external integrations. diff --git a/openspec/specs/activity-feed/spec.md b/openspec/specs/activity-feed/spec.md index aed90e4..21f2c7b 100644 --- a/openspec/specs/activity-feed/spec.md +++ b/openspec/specs/activity-feed/spec.md @@ -1,4 +1,8 @@ -## ADDED Requirements +## Purpose + +Activity creation, chronological feed, detail views, and route linking in the Journal app. + +## Requirements ### Requirement: Create activity The Journal SHALL allow authenticated users to create an activity by uploading a GPX trace and adding a description. diff --git a/openspec/specs/brouter-integration/spec.md b/openspec/specs/brouter-integration/spec.md index 6757712..3ccf4fa 100644 --- a/openspec/specs/brouter-integration/spec.md +++ b/openspec/specs/brouter-integration/spec.md @@ -1,4 +1,8 @@ -## ADDED Requirements +## Purpose + +Route computation between waypoints via the BRouter HTTP API, including routing host election, result broadcasting via Yjs, profile selection, and rate-limited proxying. + +## Requirements ### Requirement: Route computation from waypoints The Planner SHALL compute a route between ordered waypoints by calling the BRouter HTTP API with tiledesc enabled and returning the result as an EnrichedRoute, preserving per-point elevation, surface data, and segment boundary indices. diff --git a/openspec/specs/crash-recovery/spec.md b/openspec/specs/crash-recovery/spec.md index 20de3f4..d760b38 100644 --- a/openspec/specs/crash-recovery/spec.md +++ b/openspec/specs/crash-recovery/spec.md @@ -1,3 +1,7 @@ +## Purpose + +Browser crash resilience via localStorage-based Yjs state persistence and recovery on reconnect. + ## Requirements ### Requirement: localStorage crash recovery diff --git a/openspec/specs/gpx-import/spec.md b/openspec/specs/gpx-import/spec.md index 2666e02..f066bff 100644 --- a/openspec/specs/gpx-import/spec.md +++ b/openspec/specs/gpx-import/spec.md @@ -1,4 +1,8 @@ -## ADDED Requirements +## Purpose + +GPX file import in the Planner via home page file picker and in-session drag-and-drop, with client-side parsing and waypoint extraction. + +## Requirements ### Requirement: Import GPX from home page Users SHALL be able to import a GPX file from the planner home page to start a new planning session. @@ -30,7 +34,9 @@ Users SHALL be able to drag a GPX file onto the map in an existing session. - **WHEN** a user drops a GPX file and the confirmation dialog appears - **THEN** clicking "Cancel" leaves the session unchanged -### Requirement: Non-GPX files are rejected +### Requirement: Non-GPX file rejection +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 diff --git a/openspec/specs/infrastructure/spec.md b/openspec/specs/infrastructure/spec.md index b37dfe6..b708a26 100644 --- a/openspec/specs/infrastructure/spec.md +++ b/openspec/specs/infrastructure/spec.md @@ -1,4 +1,8 @@ -## ADDED Requirements +## Purpose + +Server provisioning on Hetzner, Docker Compose deployment, CI/CD pipelines, database and BRouter management, TLS, Sentry, Grafana, and monitoring stack for the flagship instance. + +## Requirements ### Requirement: Terraform Hetzner provisioning Infrastructure SHALL be provisioned on Hetzner Cloud using Terraform with the Hetzner provider. diff --git a/openspec/specs/journal-auth/spec.md b/openspec/specs/journal-auth/spec.md index 4d8a60e..ffd4d34 100644 --- a/openspec/specs/journal-auth/spec.md +++ b/openspec/specs/journal-auth/spec.md @@ -1,4 +1,8 @@ -## MODIFIED Requirements +## Purpose + +Authentication for the Journal app, including OAuth token storage for external services in the sync_connections table. + +## Requirements ### Requirement: Store external service tokens The journal auth system SHALL store OAuth tokens for external services alongside user credentials. diff --git a/openspec/specs/local-dev-environment/spec.md b/openspec/specs/local-dev-environment/spec.md index d943ad8..e9de720 100644 --- a/openspec/specs/local-dev-environment/spec.md +++ b/openspec/specs/local-dev-environment/spec.md @@ -1,4 +1,8 @@ -## ADDED Requirements +## Purpose + +One-command local development setup with PostgreSQL, BRouter, automatic schema migration, and segment downloading. + +## Requirements ### Requirement: One-command dev startup The project SHALL provide a single command that starts all services needed for local development. diff --git a/openspec/specs/map-display/spec.md b/openspec/specs/map-display/spec.md index f9c7760..bdbb97e 100644 --- a/openspec/specs/map-display/spec.md +++ b/openspec/specs/map-display/spec.md @@ -1,4 +1,8 @@ -## ADDED Requirements +## Purpose + +Interactive map rendering with Leaflet and OSM tiles, waypoint editing, route visualization, elevation profiles, multiplayer cursors, and polygon drawing for both Planner and Journal apps. + +## Requirements ### Requirement: Map rendering with OSM tiles The Planner and Journal SHALL render interactive maps using Leaflet with OpenStreetMap tiles as the default base layer. diff --git a/openspec/specs/no-go-areas/spec.md b/openspec/specs/no-go-areas/spec.md index 5c4c60d..d60a68f 100644 --- a/openspec/specs/no-go-areas/spec.md +++ b/openspec/specs/no-go-areas/spec.md @@ -1,3 +1,7 @@ +## Purpose + +Polygon-based route avoidance areas drawn on the map, synced via Yjs, sent to BRouter as constraints, and persisted in GPX extensions. + ## Requirements ### Requirement: Draw no-go areas @@ -35,22 +39,16 @@ No-go areas SHALL be preserved when saving to the journal or exporting a plan. - **AND** the file is compatible with any GPX-consuming application ### Requirement: GPX extensions format -No-go areas are stored in GPX using a custom XML namespace: +No-go areas SHALL be stored in GPX using the `trails:planning` custom XML namespace with point-based polygon representation. -```xml - - - - - - - - - - - -``` +#### Scenario: Valid no-go area in GPX +- **WHEN** a GPX file contains a `` element with 3+ `` child elements +- **THEN** the parser creates a no-go area polygon from the point coordinates -- Each `` element contains 3+ `` elements -- Parser accepts both namespaced (`trails:nogo`) and non-namespaced (`nogo`) elements -- Areas with fewer than 3 points are rejected on parse +#### Scenario: Namespace-agnostic parsing +- **WHEN** a GPX file contains non-namespaced `` elements instead of `` +- **THEN** the parser accepts them identically + +#### Scenario: Invalid no-go area rejected +- **WHEN** a GPX file contains a no-go area with fewer than 3 points +- **THEN** the parser rejects it diff --git a/openspec/specs/observability/spec.md b/openspec/specs/observability/spec.md index 88ae7ca..ae48ccc 100644 --- a/openspec/specs/observability/spec.md +++ b/openspec/specs/observability/spec.md @@ -1,3 +1,7 @@ +## Purpose + +Health endpoints, Prometheus metrics, structured logging, Grafana dashboards, and alerting for both apps and the flagship instance. + ## Requirements ### Requirement: Health endpoints diff --git a/openspec/specs/planner-journal-handoff/spec.md b/openspec/specs/planner-journal-handoff/spec.md index 900a2a0..ec2bf29 100644 --- a/openspec/specs/planner-journal-handoff/spec.md +++ b/openspec/specs/planner-journal-handoff/spec.md @@ -1,7 +1,11 @@ -## MODIFIED Requirements +## Purpose + +Round-trip GPX exchange between Planner and Journal, including JWT-scoped callbacks for saving routes and GPX reimport in the Planner. + +## Requirements ### Requirement: Export Plan reimport -The "Export Plan" GPX can now be reimported directly in the planner via the file upload UI, completing the round-trip without needing the journal. +The Planner SHALL support reimporting an exported plan GPX via the file upload UI, completing the round-trip without needing the journal. #### Scenario: Reimport exported plan - **WHEN** a user exports a plan and later imports it via the planner's GPX upload diff --git a/openspec/specs/planner-session/spec.md b/openspec/specs/planner-session/spec.md index 9026a2b..e839e41 100644 --- a/openspec/specs/planner-session/spec.md +++ b/openspec/specs/planner-session/spec.md @@ -1,7 +1,11 @@ -## MODIFIED Requirements +## Purpose -### Requirement: Session initialization -Sessions can now be initialized from a GPX file upload in addition to URL parameters and the journal handoff. +Collaborative planning session management with Yjs CRDT synchronization, supporting initialization from URL parameters, journal handoff, and GPX file upload. + +## Requirements + +### Requirement: Session initialization from GPX +The Planner SHALL support initializing sessions from a GPX file upload in addition to URL parameters and the journal handoff. #### Scenario: Session created from GPX upload - **WHEN** a session is created via GPX file upload on the home page diff --git a/openspec/specs/rate-limiting/spec.md b/openspec/specs/rate-limiting/spec.md index d9e8681..0e81957 100644 --- a/openspec/specs/rate-limiting/spec.md +++ b/openspec/specs/rate-limiting/spec.md @@ -1,3 +1,7 @@ +## Purpose + +Request rate limiting for Planner session creation and BRouter API calls to prevent abuse. + ## Requirements ### Requirement: Session creation rate limit diff --git a/openspec/specs/route-coloring/spec.md b/openspec/specs/route-coloring/spec.md index a837197..be460ea 100644 --- a/openspec/specs/route-coloring/spec.md +++ b/openspec/specs/route-coloring/spec.md @@ -1,3 +1,7 @@ +## Purpose + +Multi-mode route visualization (plain, elevation gradient, surface type) with session-synced color mode selection. + ## Requirements ### Requirement: Route color modes diff --git a/openspec/specs/route-drag-reshape/spec.md b/openspec/specs/route-drag-reshape/spec.md index 676ecb5..a5002c7 100644 --- a/openspec/specs/route-drag-reshape/spec.md +++ b/openspec/specs/route-drag-reshape/spec.md @@ -1,3 +1,7 @@ +## Purpose + +Ghost marker drag interaction for reshaping routes by inserting new waypoints mid-segment. + ## Requirements ### Requirement: Ghost marker on route hover diff --git a/openspec/specs/route-management/spec.md b/openspec/specs/route-management/spec.md index b911f1e..df14b4b 100644 --- a/openspec/specs/route-management/spec.md +++ b/openspec/specs/route-management/spec.md @@ -1,4 +1,8 @@ -## ADDED Requirements +## Purpose + +Route CRUD operations, GPX import/export, sequential versioning, PostGIS spatial storage, and route metadata in the Journal app. + +## Requirements ### Requirement: Create route The Journal SHALL allow authenticated users to create a new route with a name and optional description. diff --git a/openspec/specs/route-preview/spec.md b/openspec/specs/route-preview/spec.md index 6b4a297..52c6bcf 100644 --- a/openspec/specs/route-preview/spec.md +++ b/openspec/specs/route-preview/spec.md @@ -1,4 +1,8 @@ -## ADDED Requirements +## Purpose + +Map thumbnails on route and activity list pages, and interactive maps with zoom and layer switching on detail pages. + +## Requirements ### Requirement: Route map preview on list pages Route and activity list pages SHALL show a small map thumbnail for each item that has geometry. diff --git a/openspec/specs/route-splitting/spec.md b/openspec/specs/route-splitting/spec.md index 95cb2f1..54e1556 100644 --- a/openspec/specs/route-splitting/spec.md +++ b/openspec/specs/route-splitting/spec.md @@ -1,3 +1,7 @@ +## Purpose + +Waypoint insertion by clicking the ghost marker on the route polyline, splitting a segment into two. + ## Requirements ### Requirement: Insert waypoint by clicking on route diff --git a/openspec/specs/secret-management/spec.md b/openspec/specs/secret-management/spec.md index 3d64bb1..d31b9c2 100644 --- a/openspec/specs/secret-management/spec.md +++ b/openspec/specs/secret-management/spec.md @@ -1,3 +1,7 @@ +## Purpose + +SOPS-encrypted secrets stored in the repository, split into app and infra files, decryptable with a single age key at deploy time. + ## Requirements ### Requirement: Encrypted secrets in repository diff --git a/openspec/specs/security-hardening/spec.md b/openspec/specs/security-hardening/spec.md index 874ec46..35b4e7e 100644 --- a/openspec/specs/security-hardening/spec.md +++ b/openspec/specs/security-hardening/spec.md @@ -1,3 +1,7 @@ +## Purpose + +Security headers, scanner path blocking, secret scanning, dependency auditing, non-root containers, and vulnerability disclosure policy. + ## Requirements ### Requirement: Security response headers diff --git a/openspec/specs/session-notes/spec.md b/openspec/specs/session-notes/spec.md index dac0808..1c206c2 100644 --- a/openspec/specs/session-notes/spec.md +++ b/openspec/specs/session-notes/spec.md @@ -1,3 +1,7 @@ +## Purpose + +Collaborative text notes in Planner sessions, synced in real-time via Yjs. + ## Requirements ### Requirement: Collaborative session notes diff --git a/openspec/specs/shared-packages/spec.md b/openspec/specs/shared-packages/spec.md index ec7aa45..960cc45 100644 --- a/openspec/specs/shared-packages/spec.md +++ b/openspec/specs/shared-packages/spec.md @@ -1,4 +1,8 @@ -## ADDED Requirements +## Purpose + +Shared TypeScript packages (@trails-cool/types, gpx, map, ui, i18n) used by both Planner and Journal apps. + +## Requirements ### Requirement: Shared types package The `@trails-cool/types` package SHALL export TypeScript interfaces for Route, Activity, Waypoint, RouteVersion, and RouteMetadata used by both apps. diff --git a/openspec/specs/transactional-emails/spec.md b/openspec/specs/transactional-emails/spec.md index 4e50bee..3edd696 100644 --- a/openspec/specs/transactional-emails/spec.md +++ b/openspec/specs/transactional-emails/spec.md @@ -1,3 +1,7 @@ +## Purpose + +Transactional email sending with HTML and plain-text templates for magic links and welcome messages, using SMTP in production and console logging in dev. + ## Requirements ### Requirement: Email sending interface diff --git a/openspec/specs/wahoo-import/spec.md b/openspec/specs/wahoo-import/spec.md index 2b34eff..881905f 100644 --- a/openspec/specs/wahoo-import/spec.md +++ b/openspec/specs/wahoo-import/spec.md @@ -1,4 +1,8 @@ -## ADDED Requirements +## Purpose + +Provider-agnostic activity sync framework with Wahoo as the first provider, supporting OAuth connection, webhook-based automatic sync, manual import, and FIT-to-GPX conversion. + +## Requirements ### Requirement: Provider-agnostic sync framework The system SHALL provide a common interface for external activity sync providers.