Client SaaS
TypeScript
Pull Request Opened
PR #192 opened: feat: extend SMS to time-sensitive notifications (opt-in) (PR3)
Adds an opt-in SMS channel for a small, deliberately-tight set of time-sensitive alerts. SMS is strictly opt-in (default off, verified mobile required) — stricter than our soft-opt-in marketing email, per PECR.
Which notifications send SMS
Only when the recipient has opted in and verified their mobile:
- Direct booking request → cleaner (losing work if missed)
- Booking reminder → day-of
- Payment needed / unpaid → client (ties into the remind-to-pay work)
- Payout paid → cleaner
How it works
users.sms_opt_in(default false) +User::wantsSms()=sms_opt_in && hasVerifiedPhone().- Custom
SmsChannelrouted through the existing VonageSmsService, registered viaNotification::resolved. Each notification addssmstovia()only whenwantsSms(), and exposes a shorttoSms(). - Every text carries "manage texts in your account settings" — we settled on in-app opt-out (no STOP number / inbound webhook) for now.
- Settings → Notifications gains a Text messages section: a toggle when the mobile is verified, otherwise a prompt to verify (links to profile). Reassurance copy: we never sell the number.
sms_opt_inflows through the sharedUpdateNotificationPreferencesaction as an optional param, so the admin prefs form (PR4c) is unaffected.
Tests
wantsSms()truth table (opt-in × verified).SmsChannelsends viaSmsServiceonly when opted-in + verified; not otherwise.via()includessmsonly for opted-in verified users.- Settings page exposes
smsOptIn/hasVerifiedPhone; a verified user can opt in. - Full notifications + settings suites green.
Browser-verified both states (toggle when verified; verify-prompt when not) and confirmed an opt-in persists end-to-end.
+325
additions
-7
deletions
16
files changed