Admins can create one-time registration links (1–5× or unlimited uses)
with optional expiry (1d–14d or never). Recipients can register even
when public registration is disabled. Atomic usage counting prevents
race conditions, all endpoints are rate-limited.
- New budget_item_members junction table (migration 27)
- Assign trip members to budget items via avatar chips in Persons column
- Per-person split auto-calculated from assigned member count
- Per-person summary integrated into total budget card
- Member chips rendered via portal dropdown (no overflow clipping)
- Mobile: larger touch-friendly chips (30px) under item name
- Desktop: compact chips (20px) in Persons column
- Custom NOMAD-style tooltips on chips
- WebSocket live sync for all member operations
- Fix invite button text color in dark mode
- Widen budget layout to 1800px max-width
- Shorten "Per Person/Day" column header
- Times are now per-assignment instead of per-place, so the same place
on different days can have different times
- Migration 26 adds assignment_time/assignment_end_time columns
- New endpoint PUT /assignments/:id/time for updating assignment times
- Time picker removed from place creation (only shown when editing)
- End-before-start validation disables save button
- Time collision warning shows overlapping activities on the same day
- Fix participant avatars using avatar_url instead of avatar filename
- Rename "Add Place" to "Add Place/Activity" (DE + EN)
- Improve README update instructions with docker inspect tip
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
The biggest NOMAD update yet. Introduces a modular addon architecture and three major new features.
Addon System:
- Admin panel addon management with enable/disable toggles
- Trip addons (Packing List, Budget, Documents) dynamically show/hide in trip tabs
- Global addons appear in the main navigation for all users
Vacay — Vacation Day Planner (Global Addon):
- Monthly calendar view with international public holidays (100+ countries via Nager.Date API)
- Company holidays with auto-cleanup of conflicting entries
- User-based system: each NOMAD user is a person in the calendar
- Fusion system: invite other users to share a combined calendar with real-time WebSocket sync
- Vacation entitlement tracking with automatic carry-over to next year
- Full settings: block weekends, public holidays, company holidays, carry-over toggle
- Invite/accept/decline flow with forced confirmation modal
- Color management per user with collision detection on fusion
- Dissolve fusion with preserved entries
Atlas — Travel World Map (Global Addon):
- Fullscreen Leaflet world map with colored country polygons (GeoJSON)
- Glass-effect bottom panel with stats, continent breakdown, streak tracking
- Country tooltips with trip count, places visited, first/last visit dates
- Liquid glass hover effect on the stats panel
- Canvas renderer with tile preloading for maximum performance
- Responsive: mobile stats bars, no zoom controls on touch
Dashboard Widgets:
- Currency converter with 50 currencies, CustomSelect dropdowns, localStorage persistence
- Timezone widget with customizable city list, live updating clock
- Per-user toggle via settings button, bottom sheet on mobile
Admin Panel:
- Consistent dark mode across all tabs (CSS variable overrides)
- Online/offline status badges on user list via WebSocket
- Unified heading sizes and subtitles across all sections
- Responsive tab grid on mobile
Mobile Improvements:
- Vacay: slide-in sidebar drawer, floating toolbar, responsive calendar grid
- Atlas: top/bottom glass stat bars, no popups
- Trip Planner: fixed position content container prevents overscroll, portal-based sidebar buttons
- Dashboard: fixed viewport container, mobile widget bottom sheet
- Admin: responsive tab grid, compact buttons
- Global: overscroll-behavior fixes, modal scroll containment
Other:
- Trip tab labels: Planung→Karte, Packliste→Liste, Buchungen→Buchung (DE mobile)
- Reservation form responsive layout
- Backup panel responsive buttons
Features:
- Single Sign-On (OIDC) — login with Google, Apple, Authentik, Keycloak
- OpenStreetMap place search as free fallback when no Google API key
- Change password in user settings
- Delete own account (with last-admin protection)
- Last login column in admin user management
- SSO badge and provider info in user settings
- Google API key "Recommended" badge in admin panel
Improvements:
- API keys load correctly after page reload
- Validate auto-saves keys before testing
- Time format respects 12h/24h setting everywhere
- Dark mode fixes for popups and backup buttons
- Admin stats: removed photos, 4-column layout
- Profile picture upload button on avatar overlay
- TravelStats duplicate key fix
- Backup panel dark mode support
DEMO_MODE=true enables: auto-seeded admin + demo user, 3 example trips
(Tokyo, Barcelona, Wien), hourly reset of demo user data, one-click
demo login, visible banner with feature info. Zero behavior change
when DEMO_MODE is not set.
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