Checkpoint: Suppression du cron RSS indépendant. La lecture des flux RSS est désormais intégrée dans le cron d'import quotidien (import_time dans Paramètres). Le panneau de planification RSS dans RssFeeds affiche maintenant l'heure configurée et redirige vers Paramètres pour la modifier. 0 erreur TypeScript.

This commit is contained in:
Manus
2026-06-26 10:38:49 -04:00
parent 6b8b3ce9d7
commit 9eb5849504
3 changed files with 34 additions and 182 deletions

View File

@@ -12,7 +12,7 @@ import { runFullImport } from "../importer";
import uploadRoutes from "../uploadRoutes";
import scheduledRoutes from "../scheduledRoutes";
import { ensureAdminExists } from "../localAuth";
import { getSetting, getRssSettings } from "../db";
import { getSetting } from "../db";
import { runRssFetch } from "../rssEngine";
function isPortAvailable(port: number): Promise<boolean> {
@@ -30,7 +30,7 @@ async function findAvailablePort(startPort: number = 3000): Promise<number> {
throw new Error(`No available port found starting from ${startPort}`);
}
// ─── Tâche d'import quotidien ─────────────────────────────────────────────────
// ─── Tâche d'import quotidien + lecture RSS ──────────────────────────────────
let cronJob: ReturnType<typeof cron.schedule> | null = null;
async function scheduleDailyImport() {
@@ -45,85 +45,34 @@ async function scheduleDailyImport() {
cronJob = cron.schedule(cronExpr, async () => {
console.log(`[Cron] Import automatique démarré à ${new Date().toISOString()}`);
try {
// 1. Import des fichiers Excel (Veille + AAP)
const result = await runFullImport();
console.log(`[Cron] Import terminé — Veille: +${result.veille.newRows} | AAP: +${result.aap.newRows}`);
console.log(`[Cron] Import Excel terminé — Veille: +${result.veille.newRows} | AAP: +${result.aap.newRows}`);
} catch (e) {
console.error("[Cron] Erreur lors de l'import:", e);
console.error("[Cron] Erreur lors de l'import Excel:", e);
}
});
console.log(`[Cron] Import quotidien planifié à ${importTime} (${cronExpr})`);
}
// ─── Planificateur RSS natif ──────────────────────────────────────────────────
let rssCronJob: ReturnType<typeof cron.schedule> | null = null;
/**
* Démarre (ou redémarre) le planificateur RSS en lisant la configuration
* depuis la table rss_settings. Peut être appelé au démarrage et à chaque
* modification des paramètres RSS via l'interface d'administration.
*/
export async function scheduleRssFetch() {
// Arrêter le cron existant s'il y en a un
if (rssCronJob) {
rssCronJob.stop();
rssCronJob = null;
console.log("[RSS Cron] Planificateur RSS arrêté.");
}
let settings = null;
try {
settings = await getRssSettings();
} catch (e) {
// En cas d'erreur (ex: colonne manquante lors d'une migration),
// utiliser les valeurs par défaut et planifier un retry dans 2 minutes
console.warn("[RSS Cron] Impossible de lire les paramètres RSS, utilisation des valeurs par défaut:", (e as Error).message);
setTimeout(() => scheduleRssFetch(), 2 * 60 * 1000);
// Démarrer quand même avec les valeurs par défaut
settings = { autoFetchEnabled: true, fetchMode: "interval" as const, fetchIntervalMinutes: 60, scheduledTime: "06:00" };
}
if (!settings || !settings.autoFetchEnabled) {
console.log("[RSS Cron] Lecture automatique des flux RSS désactivée.");
return;
}
let cronExpr: string;
if (settings.fetchMode === "interval") {
// Mode intervalle : toutes les N minutes
const intervalMin = Math.max(5, settings.fetchIntervalMinutes ?? 60);
if (intervalMin < 60) {
cronExpr = `*/${intervalMin} * * * *`;
} else if (intervalMin % 60 === 0) {
const hours = intervalMin / 60;
cronExpr = `0 */${hours} * * *`;
} else {
cronExpr = `*/${intervalMin} * * * *`;
}
console.log(`[RSS Cron] Mode intervalle — toutes les ${intervalMin} minutes (${cronExpr})`);
} else {
// Mode planifié : heure fixe quotidienne
const scheduledTime = settings.scheduledTime ?? "06:00";
const [hour, minute] = scheduledTime.split(":").map(Number);
cronExpr = `0 ${minute ?? 0} ${hour ?? 6} * * *`;
console.log(`[RSS Cron] Mode planifié — tous les jours à ${scheduledTime} (${cronExpr})`);
}
rssCronJob = cron.schedule(cronExpr, async () => {
console.log(`[RSS Cron] Lecture des flux RSS démarrée à ${new Date().toISOString()}`);
try {
const summary = await runRssFetch();
// 2. Lecture des flux RSS
const rssSummary = await runRssFetch();
console.log(
`[RSS Cron] Lecture terminée — ${summary.totalFeeds} flux, ` +
`+${summary.totalNewItems} nouveaux articles, ` +
`${summary.errorFeeds} erreur(s)`
`[Cron] Lecture RSS terminée — ${rssSummary.totalFeeds} flux, ` +
`+${rssSummary.totalNewItems} nouveaux articles, ` +
`${rssSummary.errorFeeds} erreur(s)`
);
} catch (e) {
console.error("[RSS Cron] Erreur lors de la lecture des flux:", e);
console.error("[Cron] Erreur lors de la lecture RSS:", e);
}
});
console.log(`[Cron] Import quotidien + lecture RSS planifiés à ${importTime} (${cronExpr})`);
}
console.log("[RSS Cron] Planificateur RSS démarré.");
/**
* Stub conservé pour compatibilité avec les imports existants dans routers.ts.
* La lecture RSS est désormais intégrée dans scheduleDailyImport().
*/
export async function scheduleRssFetch() {
// No-op : la lecture RSS est pilotée par le cron d'import quotidien (import_time)
console.log("[RSS Cron] Planificateur RSS indépendant désactivé — la lecture est pilotée par le cron d'import quotidien.");
}
async function startServer() {
@@ -159,7 +108,6 @@ async function startServer() {
try {
await ensureAdminExists();
await scheduleDailyImport();
await scheduleRssFetch();
} catch (e) {
console.error("[Init] Erreur d'initialisation:", e);
}