Commit Graph

16 Commits

Author SHA1 Message Date
0e3a7347e0 fix: allow cross-origin image loading + hide legend on small screens
- 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>
2026-03-24 20:08:48 +03:00
b9116c427a feat: notifications API, auto-jobs, calendar housekeeping fixes
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>
2026-03-23 23:02:30 +03:00
9af11df1b0 feat: housekeeping automation — auto-task on checkout + room status on done
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>
2026-03-23 22:27:18 +03:00
e5daf91ed4 feat: persist rate overrides to DB when applying prices in AvailabilityPage
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-23 16:14:45 +03:00
c3a30be74e feat: calendar hover price tooltip + AvailabilityPage API integration
- 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>
2026-03-23 15:05:12 +03:00
3ef7f8265a feat: real file upload to /opt/hotelsync/uploads + serve via /uploads/ on API 2026-03-23 12:23:13 +03:00
5540d0cdfa fix: category form — async save with error display, drag-and-drop photos, 20MB body limit 2026-03-23 12:17:53 +03:00
5c40b154d0 feat: categories + tariffs — migration, API routes, frontend integration 2026-03-23 11:42:29 +03:00
b48e50e62b Rental: connect to API, improve cell UI; remove price from room labels
Backend:
- Migration 015_rental.sql: rental_objects + rental_bookings tables, seed demo data
- New routes: GET/POST/PATCH/DELETE rental-objects and rental-bookings per hotel
- Register rentalRoutes in app.ts

Frontend:
- api.ts: add rental.listObjects, listBookings, createBooking, updateBooking, deleteBooking
- CalendarPage: fetch rental objects + bookings from API instead of mock data
- BookingCalendar: rental cell UI redesigned — colored squares + working hours + time slots (matches design spec)
- BookingCalendar: remove base rate price from desktop room label column (irrelevant with dynamic pricing)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-21 15:46:01 +03:00
873a9a4fc4 Add multi-guest management: per-booking roster, docs, guest autocomplete
- Migration 010: booking_guests table (roster per booking with passport data)
- Backend: /bookings/:id/guests CRUD — auto-links/creates guest profiles by passport
- Backend: /hotel-settings GET/PATCH for key-value settings (require_guest_docs)
- BookingDetailPanel: Гости tab with multi-guest list, inline add/edit form,
  guest autocomplete (debounced search in guests table), child/main badges,
  passport fields for adults, scan stub, require-docs warning
- SettingsPage: toggle "Обязательное заполнение документов гостей"
- Pass slug prop through CalendarPage → BookingCalendar → BookingDetailPanel

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 20:53:07 +03:00
de4fb2126b Add Guests module: API integration + passport identification
- Migration 009: add passport_series, passport_number, rating to guests table
- Backend route /api/hotels/:slug/guests: list, get (with history), create/upsert by passport, update, delete
- Frontend GuestsPage: loads from API, passport tab in modal, add guest form, search by passport
- api.ts: add guests API methods and GuestApiType

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-19 14:03:04 +03:00
ed397dbcd9 Remove pull integration; persist push log to DB (last 50 per hotel)
- 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>
2026-03-19 12:55:39 +03:00
8350309645 Add TravelLine pull integration for NetUP: capture endpoint + tl_token
- 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>
2026-03-18 18:57:10 +03:00
61d25628ae Add NetUP IPTV integration module (TV Welcome settings page)
- DB: migrations/002_netup.sql — netup_settings + netup_room_mapping tables
- Backend: routes/netup.ts — GET/PATCH settings, POST test, GET/POST room
  mappings, POST send TV message; notifyNetupCheckin/Checkout helpers
- Backend: bookings PATCH — fire-and-forget NetUP check-in/out on status change
- Frontend: TvWelcomePage — connection settings tab + room mapping tab
- Frontend: sidebarItem added to tv-welcome module (shows in sidebar menu)
- Frontend: ModulesPage Settings button navigates to /tv-welcome
- Frontend: BookingModal — "Сообщение гостю на TV" panel for existing bookings

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-18 18:18:41 +03:00
3506105fc1 Add real-time booking collaboration via WebSocket
- Backend: /ws relay endpoint (@fastify/websocket)
- Frontend: useHotelSocket hook with lock/unlock/booking events
- Calendar: lock overlay with diagonal stripes shows other manager editing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-17 18:05:09 +03:00
c233590c4b Major UX improvements across multiple pages
Шахматка:
- Date/period picker dropdown on navigation button (choose start date + days window)
- Cancelled bookings fade out with animation after 1 second

Бронирования:
- Clickable column headers with sort asc/desc (Гость, Заезд, Выезд, Статус, Источник, Сумма)

Страница входа:
- Removed role-based account selector — just email + password
- System auto-detects role/hotel from credentials

Настройки:
- New "Бронирование" section with room assignment strategy (spread/together/sequential/manual)
- Notifications: SMTP email config + SMS provider config (SMSC, SMS.ru, МТС, etc.)

Модули:
- Added Housekeeping and Channel Manager as proper modules
- Channel Manager lists: Booking.com, Airbnb, Яндекс Путешествия, Островок, Суточно.ру, OneTwoTrip
- Housekeeping visible to all roles (including housekeeper) via module status
- Sidebar now uses module status to show/hide Уборка and Каналы

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-11 15:20:05 +03:00