Stu Mason
Stu Mason

Activity

StuMason/cleanconnect
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 SmsChannel routed through the existing Vonage SmsService, registered via Notification::resolved. Each notification adds sms to via() only when wantsSms(), and exposes a short toSms().
  • 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_in flows through the shared UpdateNotificationPreferences action as an optional param, so the admin prefs form (PR4c) is unaffected.

Tests

  • wantsSms() truth table (opt-in × verified).
  • SmsChannel sends via SmsService only when opted-in + verified; not otherwise.
  • via() includes sms only 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