Aller au contenu

Tâches Cron

Rebase inclut un planificateur de tâches cron intégré pour l’exécution de tâches d’arrière-plan récurrentes — nettoyage de données, génération de rapports, vérifications de santé, synchronisations d’API externes, et plus encore.

Les tâches cron suivent le même modèle de découverte basée sur les fichiers que les fonctions personnalisées : déposez un fichier TypeScript dans votre répertoire crons/, et Rebase l’enregistre et le planifie automatiquement.

  • Zéro dépendance — Aucune bibliothèque de planificateur externe requise
  • API d’administration — Points de terminaison REST pour lister, déclencher, activer/désactiver et visualiser les journaux
  • Tableau de bord Studio — Surveiller toutes les tâches, visualiser l’historique d’exécution et déclencher des exécutions manuellement
  • Persistance de la base de données — Journaux d’exécution stockés dans PostgreSQL, survivant aux redémarrages
  • Cache en mémoire — Buffer circulaire rapide (50 dernières exécutions) pour le tableau de bord, supporté par la BD

Créez un fichier dans votre répertoire backend/crons/ qui exporte par défaut une CronJobDefinition :

// backend/crons/health-check.ts
import type { CronJobDefinition } from "@rebasepro/types";
const job: CronJobDefinition = {
schedule: "*/5 * * * *", // every 5 minutes
name: "System Health Check",
description: "Monitors uptime and memory usage",
async handler(ctx) {
ctx.log("Running health check...");
const uptime = process.uptime();
const mem = process.memoryUsage();
ctx.log(`Uptime: ${Math.round(uptime)}s`);
ctx.log(`Heap: ${Math.round(mem.heapUsed / 1024 / 1024)}MB`);
return {
uptimeSeconds: Math.round(uptime),
heapUsedMB: Math.round(mem.heapUsed / 1024 / 1024),
};
},
};
export default job;

Le nom du fichier (sans extension) devient l’ID unique de la tâche — par exemple, health-check.

Activez les tâches cron en ajoutant cronsDir à votre configuration de backend :

const instance = await initializeRebaseBackend({
// ... other config
functionsDir: path.resolve(__dirname, "../functions"),
cronsDir: path.resolve(__dirname, "../crons"), // ← add this
});

C’est tout. Rebase va :

  1. Analyser le répertoire pour les fichiers .ts / .js
  2. Enregistrer chaque exportation par défaut comme une tâche cron
  3. Créer automatiquement la table rebase.cron_logs dans PostgreSQL (si le pilote supporte SQL)
  4. Démarrer le planificateur et initialiser les compteurs à partir des journaux de BD existants
  5. Monter les routes REST d’administration à /api/cron

Les expressions cron utilisent le format standard à 5 champs :

┌───────────── minute (0–59)
│ ┌─────────── hour (0–23)
│ │ ┌───────── day of month (1–31)
│ │ │ ┌─────── month (1–12)
│ │ │ │ ┌───── day of week (0–6, Sunday = 0)
│ │ │ │ │
* * * * *
ExpressionSignification
* * * * *Chaque minute
0 * * * *Chaque heure
0 3 * * *Tous les jours à 3h00 du matin
0 0 * * 1Tous les lundis à minuit
0 9 1 * *Premier jour de chaque mois à 9h00 du matin
0,30 * * * *Toutes les 30 minutes (aux :00 et :30)
0 9-17 * * 1-5Toutes les heures, de 9h à 17h, uniquement les jours de semaine

Les valeurs de pas (*/n), les plages (a-b) et les listes (a,b,c) sont toutes supportées.

interface CronJobDefinition {
// Cron schedule expression (5-field format)
schedule: string;
// Human-readable name shown in Studio
name: string;
// Optional description shown in Studio
description?: string;
// Whether the job starts enabled (default: true)
enabled?: boolean;
// Max execution time in seconds (default: 300)
timeoutSeconds?: number;
// The function to run on each tick
handler: (ctx: CronJobContext) => Promise<unknown> | unknown;
}

Chaque gestionnaire reçoit un CronJobContext :

interface CronJobContext {
// The job's unique ID (derived from filename)
jobId: string;
// The scheduled tick timestamp
scheduledAt: Date;
// Logger — captured lines appear in Studio and the logs API
log: (...args: unknown[]) => void;
}

Utilisez ctx.log() pour émettre une sortie structurée. Ces lignes sont capturées dans le journal d’exécution et visibles dans Studio et via l’API REST.

Toutes les routes cron nécessitent une authentification administrateur (requireAuth + requireAdmin).

MéthodeCheminDescription
GET/api/cronLister toutes les tâches cron enregistrées
GET/api/cron/:idObtenir le statut d’une tâche unique
POST/api/cron/:id/triggerDéclencher manuellement une tâche
GET/api/cron/:id/logsObtenir l’historique d’exécution (?limit=N)
PUT/api/cron/:idActiver/désactiver une tâche ({ "enabled": true })
curl -H "Authorization: Bearer $TOKEN" http://localhost:3001/api/cron
{
"jobs": [
{
"id": "health-check",
"name": "System Health Check",
"schedule": "*/5 * * * *",
"enabled": true,
"state": "idle",
"totalRuns": 12,
"totalFailures": 0,
"lastRunAt": "2026-04-24T08:15:00.000Z",
"nextRunAt": "2026-04-24T08:20:00.000Z",
"lastDurationMs": 3
}
]
}
curl -X POST -H "Authorization: Bearer $TOKEN" \
http://localhost:3001/api/cron/health-check/trigger

Le SDK client Rebase expose un espace de noms cron pour toutes les opérations :

import { createRebaseClient } from "@rebasepro/client";
const client = createRebaseClient({ baseUrl: "http://localhost:3001" });
// Lister toutes les tâches
const { jobs } = await client.cron.listJobs();
// Obtenir une tâche unique
const { job } = await client.cron.getJob("health-check");
// Déclencher manuellement
const { log, job: updated } = await client.cron.triggerJob("health-check");
// Voir l'historique d'exécution
const { logs } = await client.cron.getJobLogs("health-check", { limit: 10 });
// Activer ou désactiver
await client.cron.toggleJob("health-check", false); // pause
await client.cron.toggleJob("health-check", true); // reprendre

Lorsque les tâches cron sont configurées, un outil Tâches Cron apparaît dans Rebase Studio sous la section Automatisation. Le tableau de bord offre :

  • Liste des tâches — Toutes les tâches enregistrées avec des indicateurs de statut en direct
  • Panneau de détails — Planification, prochaine/dernière exécution, durée et informations d’erreur
  • Historique d’exécution — Entrées de journal extensibles avec sortie capturée et résultats
  • Déclenchement manuel — Exécuter n’importe quelle tâche à la demande en un seul clic
  • Activer/désactiver — Mettre en pause et reprendre des tâches sans redémarrer le serveur

Le tableau de bord se rafraîchit automatiquement toutes les 15 secondes.

Lorsque le pilote de base de données prend en charge SQL (par exemple, PostgreSQL), les journaux d’exécution sont automatiquement persistés dans une table rebase.cron_logs. Cela signifie :

  • L’historique d’exécution survit aux redémarrages du serveur et aux déploiements
  • Les compteurs totalRuns et totalFailures sont initialisés à partir de la base de données au démarrage
  • Le point de terminaison /api/cron/:id/logs interroge la base de données, pas seulement la mémoire
  • Plusieurs instances de serveur partagent le même historique d’exécution

La table est créée automatiquement lors du premier démarrage — aucune migration n’est nécessaire.

  • Si un gestionnaire lève une erreur, l’erreur est capturée dans l’entrée du journal et l’état de la tâche est défini sur "error". Le planificateur continue de fonctionner — le prochain déclenchement planifié aura toujours lieu.
  • Si un gestionnaire dépasse timeoutSeconds (par défaut : 300), il est terminé avec une erreur de dépassement de délai.
  • Toutes les métriques d’exécution (nombre de succès, nombre d’échecs, dernière erreur) sont suivies par tâche et accessibles via l’API.
  • Les échecs d’écriture persistante sont journalisés mais ne font jamais planter le planificateur.
// backend/crons/cleanup-sessions.ts
import type { CronJobDefinition } from "@rebasepro/types";
import { rebase } from "@rebasepro/server-core";
const job: CronJobDefinition = {
schedule: "0 3 * * *", // daily at 3 AM
name: "Cleanup Expired Sessions",
description: "Removes user sessions older than 30 days",
async handler(ctx) {
ctx.log("Starting session cleanup...");
// Use the rebase singleton for admin-level database access
// const { data: expired } = await rebase.data.findMany("sessions", { ... });
const count = Math.floor(Math.random() * 50); // placeholder
ctx.log(`Cleaned up ${count} expired sessions`);
return { deletedSessions: count };
},
};
export default job;