← back to AbramsOS

lib/vitals-reminders.js

45 lines

// vitals-reminders.js — gentle "time for a BP check" reminders.
//
// Design rule (don't nag about an unadopted feature): a reminder fires ONLY for a person
// who has logged blood pressure BEFORE but not in the last N days (a lapsed habit). If they
// have never logged a reading, no reminder. Deduped by the reminder engine, so it can't spam.
const db = require('./db');

const REMIND_AFTER_DAYS = 14;

async function generateReadingReminders(userId, tryInsert) {
  let inserted = 0;
  const rows = (await db.query(
    `SELECT person_id, max(measured_at) AS last, count(*)::int AS n
       FROM health_reading WHERE user_id = $1 AND metric = 'blood_pressure'
       GROUP BY person_id`,
    [userId]
  )).rows;

  for (const r of rows) {
    if (!r.n) continue;                       // never logged → don't nudge
    const days = (Date.now() - new Date(r.last).getTime()) / 86400e3;
    if (days < REMIND_AFTER_DAYS) continue;   // logged recently → fine

    let personName = null;
    if (r.person_id) {
      const p = await db.query(`SELECT full_name FROM person WHERE id = $1`, [r.person_id]);
      personName = p.rows[0] && p.rows[0].full_name;
    }
    const rr = await tryInsert({
      userId,
      ownerTable: 'health_reading',
      ownerId: `bp-${r.person_id || 'self'}`,
      dueAt: new Date(),
      reasonCode: 'bp_reading_due',
      title: personName ? `Time for ${personName}'s blood-pressure check` : 'Time for a blood-pressure check',
      body: `It's been ${Math.floor(days)} days since the last reading. A quick check keeps the trend meaningful.`,
      metadata: { medical: true, person_id: r.person_id || null },
    });
    if (rr) inserted += 1;
  }
  return inserted;
}

module.exports = { generateReadingReminders, REMIND_AFTER_DAYS };