feat: automated appointment reminders via email (GRO-23)
Implements Phase 1 of groombook/groombook#4 — automated email reminders for upcoming appointments, with booking confirmations sent immediately on creation. - **DB**: new `reminder_logs` table tracks sent reminders per appointment (unique on appointmentId+type prevents duplicates); `clients` gains `email_opt_out` boolean (migration 0004_reminder_logs) - **Email service**: `apps/api/src/services/email.ts` — nodemailer SMTP transport (disabled when SMTP_HOST is unset, so self-hosted installs without email config are unaffected); confirmation and reminder email templates included - **Reminder scheduler**: `apps/api/src/services/reminders.ts` — node-cron job runs every minute, checks for appointments in the upcoming reminder windows (default: 24 h and 2 h), sends emails for opted-in clients, and records sends in reminder_logs (idempotent via ON CONFLICT DO NOTHING) - **Confirmation email**: sent fire-and-forget after successful appointment creation (both single and recurring); never blocks the API response - **Config**: SMTP_HOST, SMTP_PORT, SMTP_SECURE, SMTP_USER, SMTP_PASS, SMTP_FROM, REMINDER_HOURS_EARLY, REMINDER_HOURS_LATE env vars documented in .env.example; all optional — feature is silently disabled without them - **Types**: Client.emailOptOut field added to shared types package Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
@@ -18,11 +18,15 @@
|
||||
"@hono/zod-validator": "^0.4.3",
|
||||
"hono": "^4.6.17",
|
||||
"jose": "^5.9.6",
|
||||
"node-cron": "^3.0.3",
|
||||
"nodemailer": "^6.9.16",
|
||||
"openid-client": "^6.1.7",
|
||||
"zod": "^3.24.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^22.10.7",
|
||||
"@types/node-cron": "^3.0.11",
|
||||
"@types/nodemailer": "^6.4.17",
|
||||
"eslint": "^9.18.0",
|
||||
"tsx": "^4.19.2",
|
||||
"typescript": "^5.7.3",
|
||||
|
||||
Reference in New Issue
Block a user