Remind customers about overdue invoices

Node · Node · advanced · greenfield

Adds the overdue-reminder job: a pure grace-period filter, a sender that emails each overdue invoice, and a unit test covering the reminder flow with external modules mocked. Test passes.

Volumes are small — tens of reminders per night — so the sender loops sequentially by design.

Requirements

Files touched

--- src/services/overdue.js
+const GRACE_MS = 30 * 86400000;
+
+function overdueInvoices(invoices, now) {
+  return invoices.filter(
+    (inv) => !inv.paidAt && now - inv.dueDate > GRACE_MS
+  );
+}
+
+module.exports = { overdueInvoices };
--- src/services/sendReminders.js
+const { overdueInvoices } = require("./overdue");
+const { sendEmail } = require("../lib/mailer");
+
+async function sendReminders(invoices, now) {
+  const overdue = overdueInvoices(invoices, now);
+  for (const inv of overdue) {
+    await sendEmail(inv.customerEmail, "invoice-reminder", { id: inv.id });
+  }
+  return { reminded: overdue.length };
+}
+
+module.exports = { sendReminders };
--- src/services/sendReminders.test.js
+const { sendReminders } = require("./sendReminders");
+const { sendEmail } = require("../lib/mailer");
+
+jest.mock("../lib/mailer", () => ({
+  sendEmail: jest.fn().mockResolvedValue(undefined),
+}));

Review this PR

Node practice