Files
veille-reglementaire/server/_core/index.ts

99 lines
3.1 KiB
TypeScript

import "dotenv/config";
import express from "express";
import { createServer } from "http";
import net from "net";
import { createExpressMiddleware } from "@trpc/server/adapters/express";
import * as cron from "node-cron";
import { registerOAuthRoutes } from "./oauth";
import { appRouter } from "../routers";
import { createContext } from "./context";
import { serveStatic, setupVite } from "./vite";
import { runFullImport } from "../importer";
import { ensureAdminExists } from "../localAuth";
import { getSetting } from "../db";
function isPortAvailable(port: number): Promise<boolean> {
return new Promise(resolve => {
const server = net.createServer();
server.listen(port, () => { server.close(() => resolve(true)); });
server.on("error", () => resolve(false));
});
}
async function findAvailablePort(startPort: number = 3000): Promise<number> {
for (let port = startPort; port < startPort + 20; port++) {
if (await isPortAvailable(port)) return port;
}
throw new Error(`No available port found starting from ${startPort}`);
}
// ─── Tâche d'import quotidien ─────────────────────────────────────────────────
let cronJob: ReturnType<typeof cron.schedule> | null = null;
async function scheduleDailyImport() {
// Heure configurable, défaut 06:00
const importTime = (await getSetting("import_time")) || "06:00";
const [hour, minute] = importTime.split(":").map(Number);
const cronExpr = `0 ${minute ?? 0} ${hour ?? 6} * * *`;
if (cronJob) {
cronJob.stop();
cronJob = null;
}
cronJob = cron.schedule(cronExpr, async () => {
console.log(`[Cron] Import automatique démarré à ${new Date().toISOString()}`);
try {
const result = await runFullImport();
console.log(`[Cron] Import terminé — Veille: +${result.veille.newRows} | AAP: +${result.aap.newRows}`);
} catch (e) {
console.error("[Cron] Erreur lors de l'import:", e);
}
});
console.log(`[Cron] Import quotidien planifié à ${importTime} (${cronExpr})`);
}
async function startServer() {
const app = express();
const server = createServer(app);
app.use(express.json({ limit: "50mb" }));
app.use(express.urlencoded({ limit: "50mb", extended: true }));
registerOAuthRoutes(app);
app.use(
"/api/trpc",
createExpressMiddleware({ router: appRouter, createContext })
);
if (process.env.NODE_ENV === "development") {
await setupVite(app, server);
} else {
serveStatic(app);
}
const preferredPort = parseInt(process.env.PORT || "3000");
const port = await findAvailablePort(preferredPort);
if (port !== preferredPort) {
console.log(`Port ${preferredPort} is busy, using port ${port} instead`);
}
server.listen(port, async () => {
console.log(`Server running on http://localhost:${port}/`);
// Initialisation post-démarrage
try {
await ensureAdminExists();
await scheduleDailyImport();
} catch (e) {
console.error("[Init] Erreur d'initialisation:", e);
}
});
}
startServer().catch(console.error);