← back to AbramsOS
routes/reminders.js
59 lines
const express = require('express');
const db = require('../lib/db');
const audit = require('../lib/audit');
const engine = require('../lib/reminder-engine');
const router = express.Router();
const DEV_USER_ID = 'user_steve';
// Unified Deadlines page — regenerates from all owner tables (purchases, bills,
// reorders, warranties, recalls) then renders everything due in the next 120 days.
router.get('/deadlines', async (req, res) => {
try {
await engine.generateForUser(DEV_USER_ID);
} catch (err) {
console.error('[deadlines] regenerate failed', err.message);
}
const days = parseInt(req.query.days || '120', 10);
const rows = await engine.upcomingForUser(DEV_USER_ID, { days });
const now = Date.now();
const deadlines = rows.map((r) => ({
...r,
days_until: Math.round((new Date(r.due_at).getTime() - now) / 86400000),
}));
res.render('deadlines', { deadlines });
});
// Manual recompute trigger (cheap; idempotent because of the dedupe unique index)
router.post('/api/reminders/regenerate', async (_req, res) => {
try {
const inserted = await engine.generateForUser(DEV_USER_ID);
res.json({ ok: true, inserted });
} catch (err) {
res.status(500).json({ error: err.message });
}
});
router.get('/api/reminders/upcoming', async (req, res) => {
const days = parseInt(req.query.days || '30', 10);
const rows = await engine.upcomingForUser(DEV_USER_ID, { days });
res.json(rows);
});
router.post('/api/reminders/:id/dismiss', async (req, res) => {
await db.query(
`UPDATE calendar_reminder SET state = 'dismissed', reviewed_at = now() WHERE id = $1 AND user_id = $2`,
[req.params.id, DEV_USER_ID]
);
await audit.log({
actorType: 'user',
actorId: DEV_USER_ID,
objectType: 'calendar_reminder',
objectId: req.params.id,
eventType: 'reminder_dismissed',
});
res.json({ ok: true });
});
module.exports = router;