Commit Graph

3 Commits (bc140fc54c04c0c32b327b6a2ce1fc774237a827)

Author SHA1 Message Date
Thomas Joise bc140fc54c feat(documents): invoice due dates — terms default + override, honest overdue chase (Phase 1, D18)
- document.due_date additive column; billing.payment_terms_days seeded (15)
- issueDocument stamps doc_date+terms on INVOICE when absent — covers manual
  issue, convert-and-send and recurring generation in one place
- drafts accept dueDate (INVOICE only, validated); composer date field
  auto-filled from GET /settings/billing; invoice PDF prints Due Date
- overdue scan + reminder anchor on COALESCE(due_date, doc_date); email says
  'was due on X and is now N day(s) overdue' when a due date exists
- legacy fixtures pinned to due_date=NULL (sanctioned: they test the doc_date
  anchor); 9 new tests; suite 309/309 across 60 files

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5 days ago
Thomas Joise 4a1747958e feat(reminders): invoice dN milestone escalation from the dated schedule (Phase 9, spec §8)
- invoice_overdue scan: monthly bucket → d7/d15/d30 milestones resolved via
  resolveSchedule (dated config, rule 3); each fires once via the idempotency key
- F7 catch-up guard: scan gaps and the monthly→dN cutover enqueue only the
  highest crossed milestone, never the whole ladder
- ctx.daysOverdue populated in reminderContext (A7: anchored on doc_date) so the
  'N day(s) past due' template text renders; injectable today for determinism
- daysBetweenIso helper; 5 tests; suite green

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
5 days ago
Thomas Joise 2d3b1a52a9 feat(hq): daily scan detection rules with idempotent reminders
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2 weeks ago