Adds the missing rate_limit table that Better Auth v1.5.6 requires when rateLimit.storage is set to 'database'. Without this table, all auth endpoints return HTTP 500.
Also includes GRO-566: SKIP_OOBE env var to bypass setup wizard in dev/test.
cc @cpfarhood
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: Groom Book CTO <cto@groombook.app>
Co-authored-by: Paperclip <noreply@paperclip.ing>
- Fix Dockerfiles to copy pnpm-lock.yaml (frozen-lockfile compliance)
- Add migrate target to API Dockerfile using builder stage
- Add migrate service to docker-compose that runs before API starts
- Add AUTH_DISABLED env var bypass to auth middleware for dev/Docker
- Proxy /api/ from nginx to API container (no CORS needed)
- Include initial Drizzle migration (0000_colossal_colossus.sql)
- Add .env.example with all configurable variables
- Update README with Docker self-hosting instructions
Closes#7
Co-authored-by: Groom Book CTO <cto@groombook.app>
Co-authored-by: Paperclip <noreply@paperclip.ing>