Checkpoint: Ajout du paramétrage de fréquence des mises à jour dans Paramètres → Import & Planification : choix entre mode heure fixe (cron quotidien) et mode intervalle (1h, 2h, 4h, 6h, 12h, 24h). Le cron est rechargé immédiatement après sauvegarde sans redémarrage serveur.
This commit is contained in:
@@ -33,11 +33,29 @@ async function findAvailablePort(startPort: number = 3000): Promise<number> {
|
||||
// ─── Tâche d'import quotidien + lecture RSS ──────────────────────────────────
|
||||
let cronJob: ReturnType<typeof cron.schedule> | null = null;
|
||||
|
||||
async function scheduleDailyImport() {
|
||||
// Heure configurable, défaut 06:00
|
||||
export async function scheduleDailyImport() {
|
||||
const importTime = (await getSetting("import_time")) || "06:00";
|
||||
const [hour, minute] = importTime.split(":").map(Number);
|
||||
const cronExpr = `0 ${minute ?? 0} ${hour ?? 6} * * *`;
|
||||
const fetchMode = (await getSetting("fetch_mode")) || "scheduled";
|
||||
const fetchIntervalMinutes = parseInt((await getSetting("fetch_interval_minutes")) || "1440", 10);
|
||||
|
||||
let cronExpr: string;
|
||||
if (fetchMode === "interval") {
|
||||
const intervalMin = Math.max(60, fetchIntervalMinutes);
|
||||
if (intervalMin < 60) {
|
||||
cronExpr = `*/${intervalMin} * * * *`;
|
||||
} else if (intervalMin % 60 === 0) {
|
||||
const hours = intervalMin / 60;
|
||||
cronExpr = hours === 24 ? `0 0 * * *` : `0 */${hours} * * *`;
|
||||
} else {
|
||||
cronExpr = `*/${intervalMin} * * * *`;
|
||||
}
|
||||
console.log(`[Cron] Mode intervalle — toutes les ${intervalMin} minutes (${cronExpr})`);
|
||||
} else {
|
||||
const [hour, minute] = importTime.split(":").map(Number);
|
||||
cronExpr = `0 ${minute ?? 0} ${hour ?? 6} * * *`;
|
||||
console.log(`[Cron] Mode heure fixe — tous les jours à ${importTime} (${cronExpr})`);
|
||||
}
|
||||
|
||||
if (cronJob) {
|
||||
cronJob.stop();
|
||||
cronJob = null;
|
||||
@@ -63,7 +81,6 @@ async function scheduleDailyImport() {
|
||||
console.error("[Cron] Erreur lors de la lecture RSS:", e);
|
||||
}
|
||||
});
|
||||
console.log(`[Cron] Import quotidien + lecture RSS planifiés à ${importTime} (${cronExpr})`);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -33,7 +33,7 @@ import {
|
||||
saveRssSettings,
|
||||
} from "./db";
|
||||
import { importVeille, importAAP, runFullImport, getImportConfig } from "./importer";
|
||||
import { scheduleRssFetch } from "./_core/index";
|
||||
import { scheduleDailyImport } from "./_core/index";
|
||||
import { loginLocalUser, hashPassword, ensureAdminExists } from "./localAuth";
|
||||
import { classifyArticle } from "./aiClassifier";
|
||||
import { getDb } from "./db";
|
||||
@@ -372,6 +372,8 @@ export const appRouter = router({
|
||||
sharepoint_token: z.string().optional(),
|
||||
auth_mode: z.enum(["local", "free"]).optional(),
|
||||
import_time: z.string().optional(),
|
||||
fetch_mode: z.enum(["scheduled", "interval"]).optional(),
|
||||
fetch_interval_minutes: z.string().optional(),
|
||||
})
|
||||
)
|
||||
.mutation(async ({ input }) => {
|
||||
@@ -380,6 +382,10 @@ export const appRouter = router({
|
||||
if (v !== undefined && v !== "••••••••") toSave[k] = v;
|
||||
}
|
||||
await setSettings(toSave);
|
||||
// Recharger le cron si la planification a changé
|
||||
if (toSave.import_time || toSave.fetch_mode || toSave.fetch_interval_minutes) {
|
||||
await scheduleDailyImport();
|
||||
}
|
||||
return { success: true };
|
||||
}),
|
||||
}),
|
||||
@@ -592,8 +598,8 @@ export const appRouter = router({
|
||||
}))
|
||||
.mutation(async ({ input }) => {
|
||||
await saveRssSettings(input);
|
||||
// Recharger le planificateur RSS avec les nouveaux paramètres
|
||||
await scheduleRssFetch();
|
||||
// Recharger le planificateur (la lecture RSS est intégrée dans scheduleDailyImport)
|
||||
await scheduleDailyImport();
|
||||
return { success: true };
|
||||
}),
|
||||
}),
|
||||
|
||||
Reference in New Issue
Block a user