Files
noteflow/routes/recurring-todos.routes.js
T

214 lines
7.9 KiB
JavaScript

// Routes de gestion des tâches récurrentes
const express = require('express');
const router = express.Router();
const { body, validationResult } = require('express-validator');
const { getAll, getOne, runQuery } = require('../config/database');
const { authenticateToken } = require('../middleware/auth');
const logger = require('../config/logger');
// Toutes les routes nécessitent authentification
router.use(authenticateToken);
/**
* GET /api/recurring-todos
* Liste toutes les tâches récurrentes de l'utilisateur
*/
router.get('/', async (req, res) => {
try {
const todos = await getAll(
`SELECT * FROM recurring_todos WHERE user_id = $1 ORDER BY next_occurrence ASC`,
[req.user.id]
);
res.json(todos);
} catch (error) {
logger.error('Erreur lors de la récupération des tâches récurrentes:', error);
res.status(500).json({ error: 'Erreur serveur' });
}
});
/**
* POST /api/recurring-todos
* Créer une nouvelle tâche récurrente
*/
router.post('/',
[
body('text').trim().notEmpty().withMessage('Le texte est requis'),
body('recurrence_type').isIn(['daily', 'weekly', 'biweekly', 'monthly', 'yearly']).withMessage('Type de récurrence invalide'),
body('recurrence_interval').optional().isInt({ min: 1 }).withMessage('Intervalle invalide'),
body('day_of_week').optional().isInt({ min: 0, max: 6 }),
body('day_of_month').optional().isInt({ min: 1, max: 31 }),
body('priority').optional().isBoolean(),
body('next_occurrence').notEmpty().withMessage('Date de prochaine occurrence requise')
],
async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ error: 'Données invalides', details: errors.array() });
}
const { text, recurrence_type, recurrence_interval, day_of_week, day_of_month, priority, next_occurrence } = req.body;
const result = await runQuery(
`INSERT INTO recurring_todos (user_id, text, recurrence_type, recurrence_interval, day_of_week, day_of_month, priority, next_occurrence)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING id`,
[req.user.id, text, recurrence_type, recurrence_interval || 1, day_of_week, day_of_month, priority || false, next_occurrence]
);
res.status(201).json({
id: result.id,
text,
recurrence_type,
recurrence_interval: recurrence_interval || 1,
day_of_week,
day_of_month,
priority: priority || false,
next_occurrence,
enabled: true,
created_at: new Date().toISOString()
});
} catch (error) {
logger.error('Erreur lors de la création de la tâche récurrente:', error);
res.status(500).json({ error: 'Erreur serveur' });
}
}
);
/**
* PUT /api/recurring-todos/:id
* Modifier une tâche récurrente
*/
router.put('/:id',
[
body('text').optional().trim().notEmpty(),
body('recurrence_type').optional().isIn(['daily', 'weekly', 'biweekly', 'monthly', 'yearly']),
body('recurrence_interval').optional().isInt({ min: 1 }),
body('day_of_week').optional().isInt({ min: 0, max: 6 }),
body('day_of_month').optional().isInt({ min: 1, max: 31 }),
body('priority').optional().isBoolean(),
body('enabled').optional().isBoolean(),
body('next_occurrence').optional()
],
async (req, res) => {
try {
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ error: 'Données invalides', details: errors.array() });
}
// Vérifier que la tâche appartient à l'utilisateur
const existing = await getOne(
'SELECT id FROM recurring_todos WHERE id = $1 AND user_id = $2',
[req.params.id, req.user.id]
);
if (!existing) {
return res.status(404).json({ error: 'Tâche récurrente non trouvée' });
}
const { text, recurrence_type, recurrence_interval, day_of_week, day_of_month, priority, enabled, next_occurrence } = req.body;
const updates = [];
const params = [];
let paramCount = 0;
if (text !== undefined) {
paramCount++;
updates.push(`text = $${paramCount}`);
params.push(text);
}
if (recurrence_type !== undefined) {
paramCount++;
updates.push(`recurrence_type = $${paramCount}`);
params.push(recurrence_type);
}
if (recurrence_interval !== undefined) {
paramCount++;
updates.push(`recurrence_interval = $${paramCount}`);
params.push(recurrence_interval);
}
if (day_of_week !== undefined) {
paramCount++;
updates.push(`day_of_week = $${paramCount}`);
params.push(day_of_week);
}
if (day_of_month !== undefined) {
paramCount++;
updates.push(`day_of_month = $${paramCount}`);
params.push(day_of_month);
}
if (priority !== undefined) {
paramCount++;
updates.push(`priority = $${paramCount}`);
params.push(priority);
}
if (enabled !== undefined) {
paramCount++;
updates.push(`enabled = $${paramCount}`);
params.push(enabled);
}
if (next_occurrence !== undefined) {
paramCount++;
updates.push(`next_occurrence = $${paramCount}`);
params.push(next_occurrence);
}
if (updates.length > 0) {
paramCount++;
params.push(req.params.id);
await runQuery(`UPDATE recurring_todos SET ${updates.join(', ')} WHERE id = $${paramCount}`, params);
}
res.json({ message: 'Tâche récurrente modifiée avec succès' });
} catch (error) {
logger.error('Erreur lors de la modification de la tâche récurrente:', error);
res.status(500).json({ error: 'Erreur serveur' });
}
}
);
/**
* DELETE /api/recurring-todos/:id
* Supprimer une tâche récurrente
*/
router.delete('/:id', async (req, res) => {
try {
// Vérifier que la tâche appartient à l'utilisateur
const existing = await getOne(
'SELECT id FROM recurring_todos WHERE id = $1 AND user_id = $2',
[req.params.id, req.user.id]
);
if (!existing) {
return res.status(404).json({ error: 'Tâche récurrente non trouvée' });
}
await runQuery('DELETE FROM recurring_todos WHERE id = $1', [req.params.id]);
res.json({ message: 'Tâche récurrente supprimée avec succès' });
} catch (error) {
logger.error('Erreur lors de la suppression de la tâche récurrente:', error);
res.status(500).json({ error: 'Erreur serveur' });
}
});
/**
* POST /api/recurring-todos/generate
* Générer les todos du jour à partir des tâches récurrentes
*/
router.post('/generate', async (req, res) => {
try {
const recurringTodosController = require('../controllers/recurringTodosController');
const result = await recurringTodosController.generateTodos(req.user.id);
res.json({
message: `${result.generated} tâche(s) générée(s)`,
generated: result.generated
});
} catch (error) {
// Le logger est déjà appelé dans le controller
res.status(500).json({ error: 'Erreur serveur' });
}
});
module.exports = router;