feat: Add recurring tasks management (frontend, backend, automation)

This commit is contained in:
Michael committed 2026-01-06 21:14:17 +01:00
1 parent fcad96d1a9
commit a43910c01b
822 files changed
+133208 -787

No files matched your search

+77
View File
@@ -0,0 +1,77 @@
const { getAll, runQuery } = require('../config/database');
const logger = require('../config/logger');
class RecurringTodosController {
/**
* Génère les tâches à partir des modèles récurrents.
* @param {number|null} userId - ID de l'utilisateur pour filtrer (optionnel). Si null, traite tous les utilisateurs.
* @returns {Promise<{generated: number}>} Nombre de tâches générées
*/
async generateTodos(userId = null) {
try {
const today = new Date().toISOString().split('T')[0];
let recurringTodos;
if (userId) {
recurringTodos = await getAll(
`SELECT * FROM recurring_todos
WHERE enabled = true AND next_occurrence <= $1 AND user_id = $2`,
[today, userId]
);
} else {
recurringTodos = await getAll(
`SELECT * FROM recurring_todos
WHERE enabled = true AND next_occurrence <= $1`,
[today]
);
}
let generatedCount = 0;
for (const recurring of recurringTodos) {
// Créer le todo global
await runQuery(
`INSERT INTO global_todos (user_id, text, priority, completed)
VALUES ($1, $2, $3, false)`,
[recurring.user_id, recurring.text, recurring.priority]
);
// Calculer la prochaine occurrence
let nextDate = new Date(recurring.next_occurrence);
switch (recurring.recurrence_type) {
case 'daily':
nextDate.setDate(nextDate.getDate() + recurring.recurrence_interval);
break;
case 'weekly':
nextDate.setDate(nextDate.getDate() + (7 * recurring.recurrence_interval));
break;
case 'biweekly':
nextDate.setDate(nextDate.getDate() + 14);
break;
case 'monthly':
nextDate.setMonth(nextDate.getMonth() + recurring.recurrence_interval);
break;
case 'yearly':
nextDate.setFullYear(nextDate.getFullYear() + recurring.recurrence_interval);
break;
}
// Mettre à jour la tâche récurrente
await runQuery(
`UPDATE recurring_todos SET next_occurrence = $1, last_generated = $2 WHERE id = $3`,
[nextDate.toISOString().split('T')[0], today, recurring.id]
);
generatedCount++;
}
return { generated: generatedCount };
} catch (error) {
logger.error('Erreur dans RecurringTodosController.generateTodos:', error);
throw error;
}
}
}
module.exports = new RecurringTodosController();