- Migration 045: fiscal_mode + dto_port columns on workstation_devices
- Backend: pass fiscal_mode/dto_port to agent in test_device command
- Agent atol.ts: remove global DTO singleton, accept dtoPort per function call
- Agent test_device: returns real KKT info (model, serial, FN, shift status)
- Equipment page: fiscal/non-fiscal toggle + DTO port field when adding KKT
- Equipment page: show fiscal mode badge on device card, DTO port if non-default
- Equipment page: KKT test result shows model, serial, FN, shift status
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- EquipmentPage: add COM-port connection type with port field (COM1, /dev/ttyUSB0)
- api.ts: add comPort field to WorkstationDevice type
- workstations route: pass com_port to INSERT/PATCH
- migration 042: extend connection check constraint to include 'com', add com_port column
- agent index.html: highlight first cell on load, reset input on unpair
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
setupAgentWsRoute was called outside the encapsulated wsRoutes plugin
scope where @fastify/websocket was registered. Register the plugin at
the root level and convert setupAgentWsRoute to FastifyPluginAsync.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- PosPage.tsx: полный редизайн вокруг реальной кассовой работы
• Автодетект агента (localhost:9000), статус смены каждые 15с
• Экраны: агент не подключён / смена закрыта / смена истекла / касса
• Шапка смены: №, длительность, остаток наличных, статус ОФД
• Кнопки: X-отчёт, Внести/Изъять наличные, Закрыть смену
• Левая панель: гости с балансом + быстрые услуги
• Правая панель: чек с количеством, итого, выбор наличные/карта
• Экран успеха после пробития чека с номером ФД
- agent.ts: клиент localhost:9000 — identity + все kkt операции
- index.css: btn-danger класс
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
ALTER TABLE ADD CONSTRAINT validates existing rows immediately, so the
UPDATE must run first to migrate 'standard' → 'bronze' before the new
constraint is applied.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The guests table had CHECK (loyalty_tier IN ('standard','silver','gold','platinum'))
but the UI expects 'bronze' not 'standard'. Drop the old constraint, migrate
'standard' rows to 'bronze', then add the correct constraint.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- LoyaltyPage: levelBadge() now falls back to bronze for unknown tiers
(DB had loyalty_tier='standard' from old seed data)
- migration 040: deduplicate general chat rooms + add unique index,
normalize loyalty_tier to bronze for non-standard values
- chat.ts: ON CONFLICT clause now targets the new partial unique index
- Sidebar: DEFAULT_GROUPS only opens 'basics' by default; bump
localStorage key to sidebarGroups_v2 to clear stale stored state
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Sidebar: collapsible groups (Основное/Цены/Сервис/Управление/Настройки/Разработчикам) with chevron headers, state persisted in localStorage 'sidebarGroups'
- Sidebar: Избранное group at top, star icon on nav item hover to add/remove favorites, stored in localStorage 'sidebarFavorites'
- Sidebar: active route auto-opens its group on navigation
- SettingsPage: 'Скрыть чат' toggle in Внешний вид section, stored in localStorage 'chatHidden'
- AppLayout: conditionally renders ChatWidget based on chatHidden, listens for storage events for reactive updates
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add month view to SchedulePage — toggle between Неделя/Месяц, navigate
by month, compact 31-column grid with sticky employee names, weekend
highlighting, shift start time or В badge in each cell.
- Migration 035: extend role constraint to include hotel_admin and technician; migrate existing manager users to hotel_admin
- auth.ts: registration now assigns hotel_admin (not manager) to hotel owner
- seed.ts: demo user manager@grand-palace.ru seeded as hotel_admin
- types.ts: expand JwtPayload role union with all roles
- users.ts: hotel_admin included in access checks; role creation/edit/delete rules enforced; hotel_admin users are undeletable and uneditable (non-super_admin); role cannot be set to hotel_admin via PATCH
- rooms.ts / channels.ts: hotel_admin added to write-access checks
- UsersPage.tsx: hotel_admin and technician added to StaffRole, ROLE_META, DEFAULT_POSITIONS, mapRole, backendRoleMap, INITIAL_ROLE_PERMISSIONS; delete button hidden for hotel_admin; role selector locked for hotel_admin users; hotel_admin excluded from new-user role selector
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Migration 034: extend users table with phone, position, active columns; add new roles (receptionist, accountant, security)
- Backend users.ts: accept phone/position on create, accept phone/position/active/role on update; managers can now assign all non-admin roles
- types/index.ts + api.ts: add phone, position, active to User type and users create/update payload types
- UsersPage: fix mapRole to handle all 5 roles, fix toStaffUser to use real phone/position/active from API, fix handleSave to pass all fields
- SettingsPage: load SMTP settings from hotelSettings API on mount, save SMTP on handleSave when section === 'notify'
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add hourly_price column to rate_overrides, base_price/allow_hourly/hourly_base_price to room_categories (migration 033)
- Update categories and rate-overrides backend routes to handle new fields
- AvailabilityPage: hourly/nightly mode toggle, period prices auto-applied to grid with 'П' indicator, confirmation dialog when overriding period prices
- BookingModal: nightly/hourly toggle at top, pricing hierarchy (override → category base → room rate)
- RoomCategoriesPage: base_price/allow_hourly/hourly_base_price fields in category form; inline rooms panel
- CalendarPage + BookingCalendar: pass hourlyPriceOverrides and categoryBasePrices down to BookingModal
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1. BookingModal: move Посуточно/Почасово toggle to top (before dates)
when room has hourly rate enabled
2. RoomCategoriesPage: Номера > button now expands inline panel
showing rooms belonging to that category
3. AvailabilityPage:
- Period prices auto-applied to grid (base → periods → overrides),
cells from periods show violet П badge
- П legend item added
- Hourly rate settings shown in Periods tab for hourly-enabled rooms
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
DB constraint only allowed pending/in_progress/done/skipped, causing
500 error when trying to cancel a maintenance task.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- 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>
Tasks now get status 'cancelled' when deleted — they remain in history.
Confirmation dialog updated to reflect this behaviour.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- RoomContextMenu: separate TECH_PRIORITY_ITEMS with 'Экстренно!' label for urgent
- Tech task form uses 3-column grid (all priorities visible at once)
- Red highlight when Экстренно! is selected
- Show "🔒 Номер будет закрыт для бронирования" warning under priority selector
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- TechnicalPage: redesign task cards with separate "Задача" and "Решение" sections
- "Задача": problem description + problem photos (editable before done)
- "Решение": technician resolution comment + resolution photos (green section)
- Resolution comment in CompletionModal now saves to resolution_notes field
- Resolution photos save to resolution_photos (no longer mixed with problem photos)
- RoomModal history tab: maintenance entries show separate problem/resolution sections
- Backend: add resolution_notes, resolution_photos to PATCH allowed fields
- Migration 029: resolution_notes TEXT + resolution_photos TEXT[] columns
- RoomsPage: load active maintenance tasks, show 🔧 неисправность badge on room cards
- CalendarPage: load active maintenance tasks, show 🔧 неиспр. label in calendar row
- BookingCalendar: activeMaintenance prop, WS handler updates maintenance set on task changes
- CalendarPage WS: handle housekeeping_task_created to update activeMaintenance set
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- RoomModal: new "История" tab showing all housekeeping and maintenance tasks for the room
- Groups tasks by date (newest first), expandable cards
- Shows: assignee, start time, end time, duration (started_at → completed_at)
- For maintenance: description, problem/solution photos with lightbox viewer
- Timing grid: start / completion timestamps
- Backend GET /housekeeping: add room_id filter param
- TechnicalPage CompletionModal: add resolution comment field saved to task notes
- api.ts: housekeeping.list() accepts roomId param
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Backend POST housekeeping: include photos in INSERT, return task with room JOIN
- Backend PATCH housekeeping: set started_at on in_progress, return task with room JOIN
- WS broadcasts now include room_number/assignee_name from JOIN
- Frontend: normalizeTask() helper maps snake_case WS fields to camelCase
- TechnicalPage: fix room number display (roomNumber || room_number)
- TechnicalPage: show time spent (started_at → completed_at) on task cards
- HousekeepingPage: history tab now includes maintenance reports (no category filter)
- HousekeepingPage: HistoryCard shows photos, notes, time spent, maintenance styling
- Migration 028: started_at TIMESTAMPTZ column on housekeeping_tasks
- types: add startedAt? to HousekeepingTask
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Calendar: hover tooltip on '🧹 убирается' shows who is cleaning (assignee name)
fetched from active HK tasks on mount, updated via WS housekeeping_updated events
- HousekeepingPage: 'Сообщить о неисправности' now creates a real maintenance task
in the DB (category=maintenance) + sends WS so TechnicalPage receives it instantly;
photo upload added to the report form
- RoomContextMenu: photo upload added to tech task creation form (camera button,
preview thumbnails); photos passed through to API on task creation
- TechnicalPage: selecting 'Выполнено' now opens CompletionModal with photo upload;
technician can attach completion photos before confirming; if require_completion_photo
setting is on — at least one photo is required
- Settings (HousekeepingPage plans tab): new toggle 'Обязательное фото при завершении
тех. задачи' saved to housekeeping_settings.require_completion_photo (migration 027)
- Backend: housekeeping-settings updated with require_completion_photo field
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Fix root cause: CalendarPage created tasks with type='regular' which violated DB CHECK constraint (allowed: cleaning/turnover/inspection/maintenance/amenities) → INSERT silently failed. Fixed to type='cleaning'.
- Fix: HousekeepingPage now loads ALL active tasks (status=active = pending+in_progress) without date filter — tasks appear regardless of when they were created
- Backend: support ?status=active filter (translates to IN ('pending','in_progress'))
- Add "История" tab in HousekeepingPage: shows completed tasks for a selected date with prev/next navigation, assignee and completion time displayed
- WS handler: when task becomes done, move it from active list instead of keeping in place
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Remove 'Убирается' (cleaning) from manually selectable HK statuses in calendar context menu — it now only shows automatically when a task is in_progress
- Reduce priorities from 4 to 3: remove 'high', keep urgent/medium/low across context menu, tech tasks modal, and HousekeepingTask type
- Add photo upload to technical tasks: upload via camera button per task, display thumbnails with hover-to-remove, stored as TEXT[] in DB (migration 026)
- Fix HousekeepingPage WS handler to filter by category — no longer adds maintenance tasks to housekeeping board
- Add 'tasks' folder support to upload route
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>