From ee2b625ed55aa4450ee9f303eeedd0b1f936249a Mon Sep 17 00:00:00 2001 From: Dicken Date: Thu, 28 May 2026 19:11:05 +0200 Subject: [PATCH] Push-Erinnerungen: Widget, Backend-Scheduler, Pushover-Versand jede Minute --- backend/src/index.js | 11 +++++++---- backend/src/routes/dashboard.js | 7 +++++-- frontend/src/App.jsx | 5 +++-- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/backend/src/index.js b/backend/src/index.js index 7d941c7..5f0153f 100644 --- a/backend/src/index.js +++ b/backend/src/index.js @@ -84,17 +84,20 @@ async function sendPushoverMsg(userKey, appToken, message) { setInterval(async () => { try { + const now = db.prepare("SELECT datetime('now','localtime') as t").get().t; const due = db.prepare(` SELECT s.*, p.user_key, p.app_token FROM push_schedules s JOIN pushover_settings p ON p.user_id = s.user_id - WHERE s.sent = 0 AND s.scheduled_at <= datetime('now','localtime') - `).all(); + WHERE s.sent = 0 AND s.scheduled_at <= ? + `).all(now); for (const row of due) { await sendPushoverMsg(row.user_key, row.app_token, row.message); db.prepare('UPDATE push_schedules SET sent=1 WHERE id=?').run(row.id); - console.log(`✓ Push gesendet an user ${row.user_id}: ${row.message}`); + console.log(`✓ Push gesendet an user ${row.user_id}: "${row.message}" (fällig: ${row.scheduled_at})`); } } catch(e) { console.error('Push-Job Fehler:', e.message); } -}, 60 * 1000); // jede Minute +}, 60 * 1000); + +console.log('⏰ Push-Scheduler aktiv (jede Minute)'); diff --git a/backend/src/routes/dashboard.js b/backend/src/routes/dashboard.js index d492d43..e089694 100644 --- a/backend/src/routes/dashboard.js +++ b/backend/src/routes/dashboard.js @@ -219,10 +219,12 @@ router.get('/push-schedules', authenticate, (req, res) => { router.post('/push-schedules', authenticate, (req, res) => { const { message, scheduled_at } = req.body; if (!message?.trim() || !scheduled_at) return res.status(400).json({ error: 'Nachricht und Zeitpunkt erforderlich' }); + // Normalisieren: T→Leerzeichen, Sekunden ergänzen + const normalized = scheduled_at.replace('T',' ') + (scheduled_at.length <= 16 ? ':00' : ''); const r = db.prepare(` INSERT INTO push_schedules (user_id, message, scheduled_at, created_at) VALUES (?, ?, ?, datetime('now','localtime')) - `).run(uid(req), message.trim(), scheduled_at); + `).run(uid(req), message.trim(), normalized); res.json(db.prepare('SELECT * FROM push_schedules WHERE id=?').get(r.lastInsertRowid)); }); @@ -230,8 +232,9 @@ router.put('/push-schedules/:id', authenticate, (req, res) => { const row = db.prepare('SELECT * FROM push_schedules WHERE id=? AND user_id=?').get(req.params.id, uid(req)); if (!row) return res.status(404).json({ error: 'Nicht gefunden' }); const { message, scheduled_at } = req.body; + const normalized = scheduled_at ? scheduled_at.replace('T',' ') + (scheduled_at.length <= 16 ? ':00' : '') : row.scheduled_at; db.prepare('UPDATE push_schedules SET message=?, scheduled_at=?, sent=0 WHERE id=?') - .run(message ?? row.message, scheduled_at ?? row.scheduled_at, row.id); + .run(message ?? row.message, normalized, row.id); res.json(db.prepare('SELECT * FROM push_schedules WHERE id=?').get(row.id)); }); diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 8a32dbc..50b1600 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1008,10 +1008,11 @@ function PushScheduler({ toast }) { api('/tools/nachrichten/pushover').then(d=>setHasPushover(!!(d.user_key&&d.app_token))).catch(()=>{}); }, [isOpen]); - // Vorauswahl: jetzt + 1 Stunde + // Vorauswahl: jetzt + 1 Stunde in Lokalzeit const defaultDt = () => { const d = new Date(Date.now() + 60*60*1000); - return d.toISOString().slice(0,16); + const p = n => String(n).padStart(2,'0'); + return `${d.getFullYear()}-${p(d.getMonth()+1)}-${p(d.getDate())}T${p(d.getHours())}:${p(d.getMinutes())}`; }; const fmtDt = s => { if (!s) return ''; const d = new Date(s.replace(' ','T')); return isNaN(d)?s:d.toLocaleString('de-DE',{day:'2-digit',month:'2-digit',hour:'2-digit',minute:'2-digit'}); };