Files
iistwin/server/routes/index.ts
Ильяс Султанов 66f4e5ef53 DI2: удаление старого модуля финансов — пул БД и аудит перенесены в finance-di2
- server/finance/ (19 файлов) удалён: пул финансовой БД перенесён в server/finance-di2/db-core.ts, db-client.ts теперь реэкспортирует из ./db-core
- Шедулер аудита перенесён в server/finance-di2/audit-scheduler.ts (03:00 МСК, setInterval, без node-cron), запуск из registerDi2Routes с защитой от повторного старта
- История аудита DI2 теперь персистентна: загрузка/запись data/finance-audit-history.json в audit-agent.ts (порт из удалённого server/finance/audit.ts)
- registerFinanceRoutes убран из server/routes/index.ts, registerDi2Routes остался на его месте
- Клиент: удалены pages/finance/, components/finance/, hooks/useFinance.ts, hooks/useColumnLabels.ts, lib/format.ts, pages/salary.tsx; роуты /finance*, /income*, /expenses*, /salary и lazy-импорты убраны из App.tsx
- Навигация: «Финансы» в Sidebar и MobileBottomNav ведёт на субапп /di2 (внешняя ссылка), гейт moduleAccess.finance + finance.view сохранён
- index.css: удалён блок .hover-elevate/.hover-elevate-2/.active-elevate (использовался только старым модульным DataTable)
- FinanceBottomNav.tsx сохранён как референс для этапа 3 (.superpowers/sdd/di2-restyle/FinanceBottomNav.reference.tsx)
- Не тронуто: client-di2/, сиды прав finance.view/manage, finance_access (module-access)
2026-09-06 21:53:47 +03:00

132 lines
4.8 KiB
TypeScript

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 { 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<Server> {
// 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 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;
}