/** * TASKMATE - Reminders API * ======================== * API endpoints für Erinnerungen */ const express = require('express'); const router = express.Router(); const { getDb } = require('../database'); const reminderService = require('../services/reminderService'); // GET /api/reminders - Alle Erinnerungen für ein Projekt abrufen router.get('/', (req, res) => { try { const { project_id } = req.query; const db = getDb(); if (!project_id) { return res.status(400).json({ success: false, error: 'project_id ist erforderlich' }); } const reminders = db.prepare(` SELECT r.*, u.display_name as creator_name FROM reminders r LEFT JOIN users u ON r.created_by = u.id WHERE r.project_id = ? AND r.is_active = 1 ORDER BY r.reminder_date ASC, r.reminder_time ASC `).all(project_id); // Advance days von String zu Array konvertieren reminders.forEach(reminder => { reminder.advance_days = reminder.advance_days ? reminder.advance_days.split(',') : ['1']; }); res.json({ success: true, data: reminders }); } catch (error) { console.error('Error fetching reminders:', error); res.status(500).json({ success: false, error: 'Interner Server-Fehler' }); } }); // GET /api/reminders/:id - Einzelne Erinnerung abrufen router.get('/:id', (req, res) => { try { const db = getDb(); const reminder = db.prepare(` SELECT r.*, u.display_name as creator_name FROM reminders r LEFT JOIN users u ON r.created_by = u.id WHERE r.id = ? `).get(req.params.id); if (!reminder) { return res.status(404).json({ success: false, error: 'Erinnerung nicht gefunden' }); } // Advance days von String zu Array konvertieren reminder.advance_days = reminder.advance_days ? reminder.advance_days.split(',') : ['1']; res.json({ success: true, data: reminder }); } catch (error) { console.error('Error fetching reminder:', error); res.status(500).json({ success: false, error: 'Interner Server-Fehler' }); } }); // POST /api/reminders - Neue Erinnerung erstellen router.post('/', (req, res) => { try { const { project_id, title, description, reminder_date, reminder_time, color, advance_days, repeat_type, repeat_interval } = req.body; if (!project_id || !title || !reminder_date) { return res.status(400).json({ success: false, error: 'project_id, title und reminder_date sind erforderlich' }); } const db = getDb(); // Advance days Array zu String konvertieren const advanceDaysStr = Array.isArray(advance_days) ? advance_days.join(',') : '1'; const result = db.prepare(` INSERT INTO reminders ( project_id, title, description, reminder_date, reminder_time, color, advance_days, repeat_type, repeat_interval, created_by ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `).run( project_id, title, description || null, reminder_date, reminder_time || '09:00', color || '#F59E0B', advanceDaysStr, repeat_type || 'none', repeat_interval || 1, req.user.id ); // Benachrichtigungs-Termine mit ReminderService erstellen if (advance_days && Array.isArray(advance_days)) { const serviceInstance = reminderService.getInstance(); serviceInstance.createNotificationSchedule(result.lastInsertRowid, reminder_date, advance_days); } // Neue Erinnerung abrufen const newReminder = db.prepare(` SELECT r.*, u.display_name as creator_name FROM reminders r LEFT JOIN users u ON r.created_by = u.id WHERE r.id = ? `).get(result.lastInsertRowid); newReminder.advance_days = newReminder.advance_days ? newReminder.advance_days.split(',') : ['1']; res.status(201).json({ success: true, data: newReminder }); } catch (error) { console.error('Error creating reminder:', error); res.status(500).json({ success: false, error: 'Interner Server-Fehler' }); } }); // PUT /api/reminders/:id - Erinnerung bearbeiten router.put('/:id', (req, res) => { try { const { title, description, reminder_date, reminder_time, color, advance_days, repeat_type, repeat_interval, is_active } = req.body; const db = getDb(); // Prüfen ob Erinnerung existiert const existing = db.prepare('SELECT * FROM reminders WHERE id = ?').get(req.params.id); if (!existing) { return res.status(404).json({ success: false, error: 'Erinnerung nicht gefunden' }); } // Advance days Array zu String konvertieren const advanceDaysStr = Array.isArray(advance_days) ? advance_days.join(',') : existing.advance_days; db.prepare(` UPDATE reminders SET title = ?, description = ?, reminder_date = ?, reminder_time = ?, color = ?, advance_days = ?, repeat_type = ?, repeat_interval = ?, is_active = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ? `).run( title || existing.title, description !== undefined ? description : existing.description, reminder_date || existing.reminder_date, reminder_time || existing.reminder_time, color || existing.color, advanceDaysStr, repeat_type || existing.repeat_type, repeat_interval || existing.repeat_interval, is_active !== undefined ? is_active : existing.is_active, req.params.id ); // Benachrichtigungs-Termine neu berechnen wenn sich das Datum geändert hat if (reminder_date || advance_days) { const finalAdvanceDays = advance_days || existing.advance_days.split(','); const finalReminderDate = reminder_date || existing.reminder_date; const serviceInstance = reminderService.getInstance(); serviceInstance.createNotificationSchedule(req.params.id, finalReminderDate, finalAdvanceDays); } // Aktualisierte Erinnerung abrufen const updatedReminder = db.prepare(` SELECT r.*, u.display_name as creator_name FROM reminders r LEFT JOIN users u ON r.created_by = u.id WHERE r.id = ? `).get(req.params.id); updatedReminder.advance_days = updatedReminder.advance_days ? updatedReminder.advance_days.split(',') : ['1']; res.json({ success: true, data: updatedReminder }); } catch (error) { console.error('Error updating reminder:', error); res.status(500).json({ success: false, error: 'Interner Server-Fehler' }); } }); // DELETE /api/reminders/:id - Erinnerung löschen router.delete('/:id', (req, res) => { try { const db = getDb(); const result = db.prepare('DELETE FROM reminders WHERE id = ?').run(req.params.id); if (result.changes === 0) { return res.status(404).json({ success: false, error: 'Erinnerung nicht gefunden' }); } res.json({ success: true, message: 'Erinnerung erfolgreich gelöscht' }); } catch (error) { console.error('Error deleting reminder:', error); res.status(500).json({ success: false, error: 'Interner Server-Fehler' }); } }); // GET /api/reminders/due/check - Fällige Erinnerungen prüfen (für Cron-Job) router.get('/due/check', (req, res) => { try { const db = getDb(); const today = new Date().toISOString().split('T')[0]; // Fällige Benachrichtigungen finden const dueNotifications = db.prepare(` SELECT rn.*, r.title, r.description, r.project_id, r.created_by, r.reminder_date, r.color FROM reminder_notifications rn JOIN reminders r ON rn.reminder_id = r.id WHERE rn.notification_date <= ? AND rn.sent = 0 AND r.is_active = 1 ORDER BY rn.notification_date ASC `).all(today); res.json({ success: true, data: dueNotifications }); } catch (error) { console.error('Error checking due reminders:', error); res.status(500).json({ success: false, error: 'Interner Server-Fehler' }); } }); // POST /api/reminders/due/mark-sent - Benachrichtigung als gesendet markieren router.post('/due/mark-sent', (req, res) => { try { const { notification_id } = req.body; const db = getDb(); db.prepare('UPDATE reminder_notifications SET sent = 1 WHERE id = ?').run(notification_id); res.json({ success: true, message: 'Benachrichtigung als gesendet markiert' }); } catch (error) { console.error('Error marking notification as sent:', error); res.status(500).json({ success: false, error: 'Interner Server-Fehler' }); } }); // GET /api/reminders/stats - Debug-Statistiken für Reminder Service router.get('/stats', (req, res) => { try { const serviceInstance = reminderService.getInstance(); const stats = serviceInstance.getStats(); res.json({ success: true, data: stats }); } catch (error) { console.error('Error getting reminder stats:', error); res.status(500).json({ success: false, error: 'Interner Server-Fehler' }); } }); // POST /api/reminders/check-now - Manuelle Prüfung fälliger Erinnerungen router.post('/check-now', async (req, res) => { try { const serviceInstance = reminderService.getInstance(); await serviceInstance.manualCheck(); res.json({ success: true, message: 'Manuelle Reminder-Prüfung durchgeführt' }); } catch (error) { console.error('Error during manual reminder check:', error); res.status(500).json({ success: false, error: 'Interner Server-Fehler' }); } }); module.exports = router;