new features
This commit is contained in:
75
backend/src/jobs/reminder.job.ts
Normal file
75
backend/src/jobs/reminder.job.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
import pool from '../config/database';
|
||||
import notificationService from '../services/notification.service';
|
||||
import logger from '../utils/logger';
|
||||
|
||||
const INTERVAL_MS = 15 * 60 * 1000; // 15 minutes
|
||||
let jobInterval: ReturnType<typeof setInterval> | null = null;
|
||||
let isRunning = false;
|
||||
|
||||
async function runReminderCheck(): Promise<void> {
|
||||
if (isRunning) {
|
||||
logger.warn('ReminderJob: previous run still in progress — skipping');
|
||||
return;
|
||||
}
|
||||
isRunning = true;
|
||||
try {
|
||||
// Find due reminders that haven't been processed
|
||||
const result = await pool.query(`
|
||||
SELECT e.id, e.bestellung_id, e.nachricht, e.erstellt_von,
|
||||
b.bezeichnung AS bestellung_bezeichnung, b.besteller_id
|
||||
FROM bestellung_erinnerungen e
|
||||
JOIN bestellungen b ON b.id = e.bestellung_id
|
||||
WHERE e.faellig_am <= NOW()
|
||||
AND e.erledigt = FALSE
|
||||
`);
|
||||
|
||||
for (const row of result.rows) {
|
||||
// Notify the order handler (besteller_id) or the creator
|
||||
const targetUserId = row.besteller_id || row.erstellt_von;
|
||||
if (!targetUserId) continue;
|
||||
|
||||
await notificationService.createNotification({
|
||||
user_id: targetUserId,
|
||||
typ: 'bestellung_erinnerung',
|
||||
titel: 'Bestellungs-Erinnerung',
|
||||
nachricht: row.nachricht || `Erinnerung für Bestellung "${row.bestellung_bezeichnung}"`,
|
||||
schwere: 'info',
|
||||
link: `/bestellungen/${row.bestellung_id}`,
|
||||
quell_id: `bestellung-erinnerung-${row.id}`,
|
||||
quell_typ: 'bestellung_erinnerung',
|
||||
});
|
||||
|
||||
// Mark as done
|
||||
await pool.query('UPDATE bestellung_erinnerungen SET erledigt = TRUE WHERE id = $1', [row.id]);
|
||||
}
|
||||
|
||||
if (result.rows.length > 0) {
|
||||
logger.info(`ReminderJob: processed ${result.rows.length} reminders`);
|
||||
}
|
||||
} catch (error) {
|
||||
logger.error('ReminderJob: unexpected error', {
|
||||
error: error instanceof Error ? error.message : String(error),
|
||||
});
|
||||
} finally {
|
||||
isRunning = false;
|
||||
}
|
||||
}
|
||||
|
||||
export function startReminderJob(): void {
|
||||
if (jobInterval !== null) {
|
||||
logger.warn('Reminder job already running — skipping duplicate start');
|
||||
return;
|
||||
}
|
||||
// Run once after short delay, then repeat
|
||||
setTimeout(() => runReminderCheck(), 45 * 1000);
|
||||
jobInterval = setInterval(() => runReminderCheck(), INTERVAL_MS);
|
||||
logger.info('Reminder job scheduled (every 15 minutes)');
|
||||
}
|
||||
|
||||
export function stopReminderJob(): void {
|
||||
if (jobInterval !== null) {
|
||||
clearInterval(jobInterval);
|
||||
jobInterval = null;
|
||||
}
|
||||
logger.info('Reminder job stopped');
|
||||
}
|
||||
Reference in New Issue
Block a user