360 Zeilen
9.7 KiB
JavaScript
360 Zeilen
9.7 KiB
JavaScript
/**
|
|
* 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; |