import type { Express } from "express"; import { createServer, type Server } from "http"; import cors from 'cors'; import express from 'express'; import { pool } from "../db"; import { apiLimiter, publishNotificationSSE } from "./shared"; import authRouter from "./auth.routes"; import filesRouter from "./files.routes"; import taskRouter from "./task.routes"; import chatRouter from "./chat.routes"; import automationRouter from "./automation.routes"; import adminRouter from "./admin.routes"; import messengerRouter from "./messenger.routes"; import reactionsRouter from "./reactions.routes"; import pollsRouter from "./polls.routes"; import orgConnectionsRouter from "./org-connections.routes"; import rolesRouter from "./roles.routes"; import homeRouter from "./home.routes"; import taskInboxHiddenRouter from "./task-inbox-hidden.routes"; import taskBulkRouter from "./task-bulk.routes"; import ragRouter from "./rag.routes"; import llmProvidersRouter from "./llm-providers.routes"; import errorLogsRouter from "./error-logs.routes"; import { registerBotRoutes } from "./bots.routes"; import { registerExternalRoutes } from "./external.routes"; import { registerBotApiRoutes } from "./bot-api.routes"; import { registerDataTableRoutes } from "./data-tables.routes"; import { registerDataTableSyncRoutes } from "./data-tables-sync.routes"; import { registerContentRoutes } from "./content.routes"; import { registerPushRoutes } from "./push.routes"; import { registerMcpRagRoutes } from "./mcp-rag.routes"; import { registerFieldTemplateInsertRoutes } from "./field-template-insert.routes"; import { registerFinanceRoutes } from "../finance/routes"; import { registerDi2Routes } from "../finance-di2"; import { registerDocumentRoutes } from "../documents/routes"; import { registerDashboardRoutes } from "./dashboard.routes"; import formAccessRouter from "./form-access.routes"; import formOfflineRouter from "./form-offline.routes"; import { calendarRouter } from "./calendar.routes"; import { ganttRouter } from "./gantt.routes"; import organizationSkinsRouter from "./organization-skins.routes"; import { registerSyncRoutes } from "./sync.routes"; import { registerMedScheduleRoutes } from "../medschedule/routes"; import { registerMedScheduleBotRoutes } from "../medschedule/bot.routes"; import { registerGpsRoutes } from "../gps/routes"; import { registerVpnRoutes } from "../vpn"; import { FIELD_TYPE_DEFINITIONS } from "../../shared/field-types"; export { publishNotificationSSE }; export async function registerRoutes(app: Express): Promise { // CORS configuration app.use(cors({ origin: process.env.FRONTEND_URL || 'http://localhost:5000', credentials: true, methods: ['GET', 'POST', 'PUT', 'DELETE', 'PATCH'], allowedHeaders: ['Content-Type', 'Authorization'] })); // Apply rate limiting app.use('/api', apiLimiter); // Health check endpoint app.get('/api/health', async (_req, res) => { const uptime = process.uptime(); let dbStatus = 'ok'; try { await pool.query('SELECT 1'); } catch { dbStatus = 'error'; } const status = dbStatus === 'ok' ? 'ok' : 'degraded'; res.status(dbStatus === 'ok' ? 200 : 503).json({ status, uptime: Math.floor(uptime), db: dbStatus, timestamp: new Date().toISOString(), }); }); // Field types registry (used by frontend editors) app.get('/api/field-types', (_req, res) => { res.json({ success: true, fieldTypes: FIELD_TYPE_DEFINITIONS }); }); // Route modules app.use(filesRouter); app.use(authRouter); app.use(taskBulkRouter); app.use(taskRouter); app.use(chatRouter); app.use(automationRouter); app.use(adminRouter); app.use(messengerRouter); app.use(reactionsRouter); app.use(pollsRouter); app.use(orgConnectionsRouter); app.use(rolesRouter); app.use(homeRouter); app.use(taskInboxHiddenRouter); app.use(ragRouter); app.use(llmProvidersRouter); app.use(errorLogsRouter); // Domain route registrations registerBotRoutes(app); registerExternalRoutes(app); registerBotApiRoutes(app); registerDataTableRoutes(app); registerDataTableSyncRoutes(app); registerContentRoutes(app); registerPushRoutes(app); registerMcpRagRoutes(app); registerFieldTemplateInsertRoutes(app); // Data-Insight2 (финансы v2) — СТРОГО перед старым модулем финансов: при совпадении путей приоритет у DI2 await registerDi2Routes(app); await registerFinanceRoutes(app); await registerDocumentRoutes(app); registerDashboardRoutes(app); app.use(formAccessRouter); app.use(formOfflineRouter); app.use(calendarRouter); app.use(ganttRouter); app.use(organizationSkinsRouter); registerSyncRoutes(app); registerMedScheduleRoutes(app); registerMedScheduleBotRoutes(app); // GPS-модуль: публичный /api/gps/ingest регистрируется внутри до authenticateToken registerGpsRoutes(app); registerVpnRoutes(app); const httpServer = createServer(app); return httpServer; }