- Set crossOriginResourcePolicy: cross-origin in helmet so browsers
can load uploaded images from api.hotelsync.ru when app runs on
app.hotelsync.ru (was blocked by same-origin CORP header)
- Hide booking status legend squares below lg breakpoint (hidden lg:flex)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend:
- notifications table (024 migration) — stores per-hotel notifications
- GET/PATCH/POST/DELETE /api/hotels/:slug/notifications endpoints
- createNotification() helper used by jobs + future hooks
- jobs.ts — background tasks every 10min: auto-cancel no-shows and
auto-checkout overdue stays based on hotel_settings, broadcasts WS
events and creates notifications for each automated action
Frontend:
- CalendarPage: handle housekeeping_done WS → update room status in
calendar in real-time (bug fix)
- CalendarPage: when manually setting room to dirty via context menu,
auto-create housekeeping task and broadcast via WS (bug fix)
- NotificationsContext: replaced mock data with real API integration,
polls every 60s, syncs markRead/delete to backend
- SettingsPage booking section: auto-cancel no-show toggle + hours
selector; auto-checkout toggle + hours selector
- api.ts: notifications API methods
- useHotelSocket: notification:new WS message type
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Backend:
- Migration 023: housekeeping_settings table (checkout_auto, checkout_priority, inspection_after_clean)
- New route: GET/PATCH /api/hotels/:slug/housekeeping-settings
- bookings.ts: on checked_out → auto-create turnover task + mark room dirty + broadcast WS
- housekeeping.ts: on task done → update room status (inspect|clean per setting) + broadcast WS
- ws.ts: export broadcast() for use in other routes
Frontend:
- HousekeepingPage: load/save settings to API, live Loader on save button
- useHotelSocket: add housekeeping WS message types
- HousekeepingPage: subscribe to WS — new tasks appear instantly without refresh
- BookingModal: show total section when room + nights selected (not just when total > 0)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Calendar cells: hold mouse 600ms to show price tooltip for that date/room (baseRate + hourly rate if enabled)
- AvailabilityPage: load real categories from API, derive basePrice from room baseRates, fall back to room types if no categories
- Rate periods: persisted to DB via new /api/hotels/:slug/rate-periods endpoint
- New backend migration 021_rate_periods.sql + rate-periods route
- Added api.ratePeriods.{list,create,update,delete} to frontend API client
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove TravelLine/netup-pms pull route (travelline.ts unused)
- Remove pull integration section from TvWelcomePage (token field, API URL, etc.)
- Migration 008: netup_push_log table (hotel_id, action, status, request/response body)
- recordPush() now writes to DB in addition to in-memory buffer
- getLog reads from DB so logs survive server restarts
- clearLog deletes from DB
- Limit enforced: 50 rows per hotel (oldest auto-deleted)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- New /travelline route: accepts all NetUP polls, logs them to in-memory
ring buffer (GET /travelline/_log to inspect), responds with active
reservations in a generic PMS format
- Migration 007: adds tl_token column to netup_settings
- PATCH netup/settings now saves tl_token; GET returns it
- TvWelcomePage: new TravelLine section with read-only API URL + copy
button and token input field
Setup in NetUP: Integration type = TravelLine,
API URL = https://api.hotelsync.ru/travelline, Token = <tl_token>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>