From c5413566ddacd292d99d84c6c169d803c60a491a Mon Sep 17 00:00:00 2001 From: HotelSync Date: Fri, 27 Mar 2026 12:20:28 +0300 Subject: [PATCH] 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 --- backend/src/agent-ws.ts | 4 ++-- backend/src/app.ts | 6 +++++- backend/src/routes/ws.ts | 3 --- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/backend/src/agent-ws.ts b/backend/src/agent-ws.ts index 7531310..0db839f 100644 --- a/backend/src/agent-ws.ts +++ b/backend/src/agent-ws.ts @@ -3,7 +3,7 @@ * Агенты подключаются по wss://api.hotelsync.ru/ws/agent * и остаются подключёнными для получения команд */ -import { FastifyInstance } from 'fastify' +import { FastifyInstance, FastifyPluginAsync } from 'fastify' import type { SocketStream } from '@fastify/websocket' import { WebSocket } from 'ws' import { db } from './db' @@ -71,7 +71,7 @@ async function markOnline(workstationId: string, ip?: string) { } // Регистрируем route для WebSocket агентов -export function setupAgentWsRoute(fastify: FastifyInstance) { +export const setupAgentWsRoute: FastifyPluginAsync = async (fastify) => { fastify.get('/ws/agent', { websocket: true }, async (connection: SocketStream, req) => { const socket = connection.socket as AgentSocket diff --git a/backend/src/app.ts b/backend/src/app.ts index 286a84e..a2c528d 100644 --- a/backend/src/app.ts +++ b/backend/src/app.ts @@ -10,6 +10,7 @@ import { join } from 'path' import { config } from './config' import './types' // side-effect: augments fastify types +import fastifyWebsocket from '@fastify/websocket' import wsRoutes from './routes/ws' import authRoutes from './routes/auth' import hotelsRoutes from './routes/hotels' @@ -53,6 +54,9 @@ export async function buildApp() { const uploadsDir = process.env.UPLOADS_DIR ?? join(process.cwd(), 'uploads') await fastify.register(staticFiles, { root: uploadsDir, prefix: '/uploads/' }) + // ── WebSocket ────────────────────────────────────────────────────────────── + await fastify.register(fastifyWebsocket) + // ── Security ─────────────────────────────────────────────────────────────── await fastify.register(helmet, { contentSecurityPolicy: false, crossOriginResourcePolicy: { policy: 'cross-origin' } }) @@ -114,7 +118,7 @@ export async function buildApp() { await fastify.register(loyaltyRoutes) await fastify.register(chatRoutes) await fastify.register(workstationRoutes) - setupAgentWsRoute(fastify) + await fastify.register(setupAgentWsRoute) startJobs() diff --git a/backend/src/routes/ws.ts b/backend/src/routes/ws.ts index b271429..b62041f 100644 --- a/backend/src/routes/ws.ts +++ b/backend/src/routes/ws.ts @@ -1,5 +1,4 @@ import { FastifyPluginAsync } from 'fastify' -import fastifyWebsocket from '@fastify/websocket' import type { SocketStream } from '@fastify/websocket' import type { RawData } from 'ws' @@ -18,8 +17,6 @@ export function broadcast(hotelSlug: string, message: object) { const PING_INTERVAL_MS = 25_000 // ping every 25s — keeps nginx proxy_read_timeout alive const ws: FastifyPluginAsync = async (fastify) => { - await fastify.register(fastifyWebsocket) - fastify.get<{ Querystring: { hotel?: string } }>( '/ws', { websocket: true },