Escape HTML entities before dangerouslySetInnerHTML in release notes
renderer to prevent stored XSS via malicious GitHub release bodies.
Fix RouteCalculator ignoring the profile parameter (was hardcoded to
'driving').
https://claude.ai/code/session_01SoQKcF5Rz9Y8Nzo4PzkxY8
- Category filter is now a multi-select dropdown with checkboxes
- PlaceAvatar: replace 200ms polling intervals with event-based
notification + React.memo for major performance improvement
- Map photo fetches: concurrency limited to 3 + lazy loading on images
- PlacesSidebar: content-visibility + useMemo for smooth scrolling
- Accommodation labels: check-out now appears before check-in on same day
- Timed places auto-sort chronologically when time is added
Live location:
- Crosshair button on the map toggles GPS tracking
- Blue dot shows live position with accuracy circle (<500m)
- Uses watchPosition for continuous updates
- Button turns blue when active, click again to stop
Auto-sort:
- Places with a time now auto-sort chronologically among other
timed items (transports, other timed places)
- Adding a time to a place immediately moves it to the correct
position in the timeline
- Untimed places keep their manual order_index
- Add reservation_end_time field (DB migration, API, UI)
- Split reservation form: separate date, start time, end time, status fields
- Fix DateTimePicker forcing 00:00 when no time selected
- Show end time across all reservation displays
- Link-to-assignment and date on same row (50/50 layout)
- Assignment search now shows day headers for filtered results
- Auto-fill date when selecting a day assignment
- Route segments: single OSRM request instead of N separate calls (~6s → ~1s)
- Route labels visible from zoom level 12 (was 16)
- Fix stale route labels after place deletion (useEffect triggers recalc)
- AbortController cancels outdated route calculations
## Collab — Complete Redesign
- iMessage-style live chat with blue bubbles, grouped messages, date separators
- Emoji reactions via right-click (desktop) or double-tap (mobile)
- Twemoji (Apple-style) emoji picker with categories
- Link previews with OG image/title/description
- Soft-delete messages with "deleted a message" placeholder
- Message reactions with real-time WebSocket sync
- Chat timestamps respect 12h/24h setting and timezone
## Collab Notes
- Redesigned note cards with colored header bar (booking-card style)
- 2-column grid layout (desktop), 1-column (mobile)
- Category settings modal for managing categories with colors
- File/image attachments on notes with mini-preview thumbnails
- Website links with OG image preview on note cards
- File preview portal (lightbox for images, inline viewer for PDF/TXT)
- Note files appear in Files tab with "From Collab Notes" badge
- Pin highlighting with tinted background
- Author avatar chip in header bar with custom tooltip
## Collab Polls
- Complete rewrite — clean Apple-style poll cards
- Animated progress bars with vote percentages
- Blue check circles for own votes, voter avatars
- Create poll modal with multi-choice toggle
- Active/closed poll sections
- Custom tooltips on voter chips
## What's Next Widget
- New widget showing upcoming trip activities
- Time display with "until" separator
- Participant chips per activity
- Day grouping (Today, Tomorrow, dates)
- Respects 12h/24h and locale settings
## Route Travel Times
- Auto-calculated walking + driving times via OSRM (free, no API key)
- Floating badge on each route segment between places
- Walking person icon + car icon with times
- Hides when zoomed out (< zoom 16)
- Toggle in Settings > Display to enable/disable
## Other Improvements
- Collab addon enabled by default for new installations
- Coming Soon removed from Collab in admin settings
- Tab state persisted across page reloads (sessionStorage)
- Day sidebar expanded/collapsed state persisted
- File preview with extension badges (PDF, TXT, etc.) in Files tab
- Collab Notes filter tab in Files
- Reservations section in Day Detail view
- Dark mode fix for invite button text color
- Chat scroll hidden (no visible scrollbar)
- Mobile: tab icons removed for space, touch-friendly UI
- Fixed 6 backend data structure bugs in Collab (polls, chat, notes)
- Soft-delete for chat messages (persists in history)
- Message reactions table (migration 28)
- Note attachments via trip_files with note_id (migration 30)
## Database Migrations
- Migration 27: budget_item_members table
- Migration 28: collab_message_reactions table
- Migration 29: soft-delete column on collab_messages
- Migration 30: note_id on trip_files, website on collab_notes
BREAKING: Reservations have been completely rebuilt. Existing place-level
reservations are no longer used. All reservations must be re-created via
the Bookings tab. Your trips, places, and other data are unaffected.
Reservation System (rebuilt from scratch):
- Reservations now link to specific day assignments instead of places
- Same place on different days can have independent reservations
- New assignment picker in booking modal (grouped by day, searchable)
- Removed day/place dropdowns from booking form
- Reservation badges in day plan sidebar with type-specific icons
- Reservation details in place inspector (only for selected assignment)
- Reservation summary in day detail panel
Day Detail Panel (new):
- Opens on day click in the sidebar
- Detailed weather: hourly forecast, precipitation, wind, sunrise/sunset
- Historical climate averages for dates beyond 16 days
- Accommodation management with check-in/check-out, confirmation number
- Hotel assignment across multiple days with day range picker
- Reservation overview for the day
Places:
- Places can now be assigned to the same day multiple times
- Start time + end time fields (replaces single time field)
- Map badges show multiple position numbers (e.g. "1 · 4")
- Route optimization fixed for duplicate places
- File attachments during place editing (not just creation)
- Cover image upload during trip creation (not just editing)
- Paste support (Ctrl+V) for images in trip, place, and file forms
Internationalization:
- 200+ hardcoded German strings translated to i18n (EN + DE)
- Server error messages in English
- Category seeds in English for new installations
- All planner, register, photo, packing components translated
UI/UX:
- Auto dark mode (follows system preference, configurable in settings)
- Navbar toggle switches light/dark (overrides auto)
- Sidebar minimize buttons z-index fixed
- Transport mode selector removed from day plan
- CustomSelect supports grouped headers (isHeader option)
- Optimistic updates for day notes (instant feedback)
- Booking cards redesigned with type-colored headers and structured details
Weather:
- Wind speed in mph when using Fahrenheit setting
- Weather description language matches app language
Admin:
- Weather info panel replaces OpenWeatherMap key input
- "Recommended" badge styling updated
- Replace OpenWeatherMap with Open-Meteo (no API key needed)
- 16-day forecast (up from 5 days)
- Historical climate averages as fallback beyond 16 days
- Auto-upgrade from climate to real forecast when available
- Fix Vacay WebSocket sync across devices (socket-ID exclusion instead of user-ID)
- Add GitHub release history tab in admin panel
- Show cluster count "1" for single map markers when zoomed out
- Add weather info panel in admin settings (replaces OpenWeatherMap key input)
- Update i18n translations (DE + EN)
- Map auto-fits to day places when selecting a day or place
- Dynamic padding accounts for sidebars and place inspector overlay
- Place-based reservations now show linked files in the bookings tab
- Increased max zoom to 16 for closer detail on nearby places
- Route line auto-updates on day select, reorder, assign, remove (no manual button)
- Remove manual route calculation button (keep optimize + Google Maps)
- Lock places at their position during route optimization (click avatar to toggle)
- Locked places shown with red background, border and lock overlay
- Custom tooltip for lock feature (DE/EN, dark mode)
- Fix map zoom: panTo instead of setView keeps current zoom level
- Fix fitBounds only on actual day change, not on place click
- Missing translations: needTwoPlaces, routeOptimized, noGeoPlaces
- Fix backup restore: try/finally ensures DB always reopens after closeDb
- Fix EBUSY on uploads during restore (in-place overwrite instead of rmSync)
- Add DB proxy null guard for clearer errors during restore window
- Add red warning modal before backup restore (DE/EN, dark mode support)
- JWT secret: empty docker-compose default so auto-generation kicks in
- OIDC: pass token via URL fragment instead of query param (no server logs)
- Block SVG uploads on photos, files and covers (stored XSS prevention)
- Add helmet for security headers (HSTS, X-Frame, nosniff, etc.)
- Explicit express.json body size limit (100kb)
- Fix XSS in Leaflet map markers (escape image_url in HTML)
- Remove verbose WebSocket debug logging from client
Real-Time Collaboration (WebSocket):
- WebSocket server with JWT auth and trip-based rooms
- Live sync for all CRUD operations (places, assignments, days, notes, budget, packing, reservations, files)
- Socket-based exclusion to prevent duplicate updates
- Auto-reconnect with exponential backoff
- Assignment move sync between days
Performance:
- 16 database indexes on all foreign key columns
- N+1 query fix in places, assignments and days endpoints
- Marker clustering (react-leaflet-cluster) with configurable radius
- List virtualization (react-window) for places sidebar
- useMemo for filtered places
- SQLite WAL mode + busy_timeout for concurrent writes
- Weather API: server-side cache (1h forecast, 15min current) + client sessionStorage
- Google Places photos: persisted to DB after first fetch
- Google Details: 3-tier cache (memory → sessionStorage → API)
Security:
- CORS auto-configuration (production: same-origin, dev: open)
- API keys removed from /auth/me response
- Admin-only endpoint for reading API keys
- Path traversal prevention in cover image deletion
- JWT secret persisted to file (survives restarts)
- Avatar upload file extension whitelist
- API key fallback: normal users use admin's key without exposure
- Case-insensitive email login
Dark Mode:
- Fixed hardcoded colors across PackingList, Budget, ReservationModal, ReservationsPanel
- Mobile map buttons and sidebar sheets respect dark mode
- Cluster markers always dark
UI/UX:
- Redesigned login page with animated planes, stars and feature cards
- Admin: create user functionality with CustomSelect
- Mobile: day-picker popup for assigning places to days
- Mobile: touch-friendly reorder buttons (32px targets)
- Mobile: responsive text (shorter labels on small screens)
- Packing list: index-based category colors
- i18n: translated date picker placeholder, fixed German labels
- Default map tile: CartoDB Light