Commit Graph

302 Commits

Author SHA1 Message Date
46524077a0 fix: collapse ping section by default, expand on click
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 10:39:18 +03:00
a443ec9d28 fix: hide reconnect button when agent is online; add printer encoding/paper_width settings
- WorkstationCard: show RefreshCw reconnect only when agentId set but offline
- DeviceForm: add encoding (utf8/cp866) and paper_width fields for network printers
- Backend: pass device.config in test_device command to agent

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 10:31:17 +03:00
11300bccbf feat: ping through agent — send ICMP ping from workstation via agent
Adds a ping tool in the Equipment page workstation card (visible when
agent is online). User enters an IP/hostname, the request goes through
the PMS backend → WebSocket → agent → executes ping -n 4, returns
raw output displayed in a monospace block.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-29 10:08:38 +03:00
7f546d809e feat: terminate agent socket and send unpair on workstation delete
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 17:10:09 +03:00
ad01bc7f4d feat: auto-close pair modal on agent connect, center close button
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 17:07:50 +03:00
d47bab977d fix: CI — correct nginx config path, add volumes to API container
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 16:46:24 +03:00
7b64580a0b fix: add X-Real-IP header to /ws nginx location for correct agent IP
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 16:41:46 +03:00
471fc17ce8 fix: equipment buttons uniform height, trustProxy for real client IP
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 16:35:04 +03:00
c04318e577 docs: full README — modules, API, architecture, deploy, DB schema
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-28 16:04:04 +03:00
fa32da8034 fix: hide COM-port selector for KKT devices (uses DTO web service, not COM)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 23:34:59 +03:00
0dfcd7f33f fix: read camelCase config keys from API response (dto_pass, dto_user, etc.)
transformKeys converts all nested JSONB keys to camelCase, so reading
dto_pass from config returned undefined, falling back to default '30'.
Now reads dtoPass (camelCase) with dto_pass as fallback for compatibility.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 23:31:58 +03:00
bf785b763f fix: hide NetUP server URL field in agent mode, derive from device config
- TvWelcomePage: hide server URL input when connection_type=agent
- Test button enabled in agent mode without serverUrl
- Backend test endpoint: derive server_url from workstation netup device
- getNetupCfg: resolve URL from netup device in agent mode

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 21:06:33 +03:00
30257a6079 fix: send sync message with workstation name after hello
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 20:54:39 +03:00
ccd366a5ad fix: equipment name refresh, hostname sync from agent hello
- WorkstationCard: useEffect to sync name state when ws.name prop changes
- agent-ws: update hostname column on hello message

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 20:29:27 +03:00
83eff2b0c6 fix: reset is_online on server start, reduce heartbeat to 20s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 20:08:43 +03:00
0e51f8326a fix: COM ports stale closure bug, remove USB printer option
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 18:41:46 +03:00
1358dda7f9 feat: Equipment page — KKT hides connection, Windows printer, COM retry; agent update banner
- EquipmentPage: KKT hides USB/COM/Network buttons (DTO handles connection)
- EquipmentPage: Printer adds Windows connection type — lists installed printers from agent
- EquipmentPage: COM port section has retry button (↺)
- api.ts: add listPrinters, extend connection type
- workstations.ts: add /printers endpoint (list_printers command)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 18:30:06 +03:00
13dac3f227 fix: EquipmentPage TS errors — stray bracket and testDevice return type
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 18:08:47 +03:00
20815ae21f fix: agent download URL — return absolute api.hotelsync.ru URL
Relative /agent-updates/ path was resolving to app.hotelsync.ru
(frontend) instead of api.hotelsync.ru, returning HTML instead of .exe

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 17:50:11 +03:00
69f0a051a7 feat: KKT dto_device_id — multiple KKTs per DTO instance
- EquipmentPage: added "ID устройства в ДТО" field (config.dto_device_id),
  shown on device card as #1
- api.ts: typed config.dto_device_id in WorkstationDevice

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 17:29:26 +03:00
c081ab5c74 feat: configurable DTO login/password per KKT device
- Equipment page: add login/password fields in KKT fiscal mode form
- Stored in device config JSON (dto_user, dto_pass)
- Backend passes credentials to agent in test_device command
- Agent uses per-device credentials for all ATOL DTO API calls

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 16:20:36 +03:00
8eb83a5189 fix: NetUp device form — hide purpose/USB/COM, auto-select network
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 15:03:09 +03:00
be311a2b30 fix: download button always visible; KKT test shows DTO setup instructions
- Download button shows even without latest release (grayed out state)
- KKT test error "ДТО не запущен" now shows 3-step setup guide with atol.ru link

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 14:39:00 +03:00
f882cb2481 feat: KKT fiscal/non-fiscal mode, multi-KKT per workstation, DTO port per device
- 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>
2026-03-27 14:06:44 +03:00
2caf717131 feat: NetUP via agent — proxy HTTP requests through Windows workstation
- Migration 044: add connection_type + agent_workstation_id to netup_settings
- Backend: netupReqViaCfg routes requests via agent WebSocket when connection_type=agent
- Agent: add netup_request command handler (proxies HTTP to local NetUP server)
- TvWelcomePage: add connection mode toggle (direct / via agent) + workstation selector
- Hint changes: URL placeholder shows local IP when agent mode selected

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 13:53:55 +03:00
c410ef8ba4 fix: pass device name to agent test_device command
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 13:18:47 +03:00
0cce5f566f feat: agent version tracking, update button, device test, COM port list
- Migration 043: agent_version in workstations, netup device type
- agent-ws: sendCommandAndWait for async commands, save version on hello
- workstations route: list-ports, test-device, update, update-all endpoints
- agent-release route: GET /api/agents/latest-release reads latest.yml
- app.ts: serve /agent-updates/ static files
- api.ts: fix camelCase→snake_case for outgoing requests (fixes null:null)
- api.ts: new methods testDevice, sendUpdate, updateAll, listPorts
- EquipmentPage: version badge, update button, test (zap) button per device
- EquipmentPage: COM-port dropdown loaded from agent when online

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 13:05:23 +03:00
b2b2034f4c feat: COM-port support for workstation devices + agent UI fixes
- 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>
2026-03-27 12:41:31 +03:00
c5413566dd fix: register @fastify/websocket globally so /ws/agent route works
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>
2026-03-27 12:20:28 +03:00
ee7ee78c5d fix: pair code modal — auto-regenerate on expiry
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 11:28:25 +03:00
72f8582e97 fix: pair code timer — expiresAt camelCase after snake→camel transform
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 11:11:41 +03:00
4cfa98d7f0 fix: EquipmentPage — input class, code modal layout (no wrapping)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-27 10:47:08 +03:00
cd5b5e4c4e fix: backend TS errors — agent role type, WebSocket SocketStream, jwt.sign cast
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 23:22:20 +03:00
239846c077 fix: TS errors — EquipmentPage purpose cast, PosPage NodeJS.Timeout
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 23:18:51 +03:00
fbb06265f9 feat: касса — полная переработка PosPage + интеграция с агентом
- 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>
2026-03-26 18:55:12 +03:00
b5974ff97f feat: страница Оборудование — рабочие места, агенты, ККТ и принтеры
- EquipmentPage: CRUD рабочих мест, генерация кода сопряжения с таймером,
  добавление устройств (ККТ/принтер, USB/сеть), онлайн-статус агентов
- api.ts: интерфейсы Workstation, WorkstationDevice + api.workstations.*
- Sidebar: пункт «Оборудование» в группе Настройки

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 18:35:49 +03:00
439be33c55 feat: workstations API + agent WebSocket — паркинг агентов и управление оборудованием
- migration 041: таблицы workstations, agent_pair_codes, workstation_devices
- routes/workstations: CRUD рабочих мест, генерация 6-значного кода, CRUD устройств
- POST /api/agent/pair: сопряжение агента по коду → JWT токен
- agent-ws.ts: WebSocket /ws/agent для постоянного соединения агентов,
  heartbeat 30s, онлайн/оффлайн статус в БД

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 18:27:24 +03:00
be58b16365 fix: migration 040 — run UPDATE before ADD CONSTRAINT (correct order)
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>
2026-03-26 11:12:47 +03:00
214a11ec9d fix: migration 040 — drop old loyalty_tier check constraint before renaming standard→bronze
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>
2026-03-26 11:06:44 +03:00
5128957d7c fix: loyalty tier crash, chat duplicate rooms, sidebar defaults
- 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>
2026-03-26 10:58:47 +03:00
15fec905e1 feat: collapsible sidebar groups + favorites, chat hide setting, billing page, module route guards 2026-03-26 10:47:54 +03:00
cbddbe6027 feat: collapsible sidebar groups with favorites + chat visibility toggle
- 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>
2026-03-26 10:39:33 +03:00
7f906cb0a3 fix: loyalty route — use request.user.sub instead of userId 2026-03-26 10:19:01 +03:00
113971f854 feat: wire up loyalty + chat — register routes, API types, connect LoyaltyPage, add ChatWidget to layout 2026-03-26 10:15:29 +03:00
8ede920e5d feat: monthly view for staff schedule + week/month toggle
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.
2026-03-26 01:28:32 +03:00
5d5efecd9e feat: staff work schedule — weekly grid for all roles, shift assignment, day off marking
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-03-26 01:18:02 +03:00
17012ae3ca fix: migration 036 — delete old channels before altering constraint + remove TravelLine refs + hide hotel_admin from roles tab 2026-03-26 01:10:48 +03:00
566c6a5e41 feat: Russian market channels — Яндекс, Островок, Суточно, Авито, Bronevik, 101hotels + role-based sidebar 2026-03-26 00:56:53 +03:00
18358b64b3 feat: role-based sidebar menu visibility — each role sees only permitted sections 2026-03-26 00:52:29 +03:00
a59f9189ed fix: Role type — add hotel_admin/manager/all roles, fix hotel_manager typo 2026-03-26 00:46:03 +03:00