Design an OTP Notification Service
viaLeetCode
Problem Low-level design of an OTP-based notification system: generate an OTP for a user action, deliver it over a channel, and validate it — with working interface/class code, then extend the design for new channels and providers.
Requirements
- API: generateOtp(userId, purpose) → dispatches via the user's channel; validateOtp(userId, purpose, code) → success/failure.
- OTP rules: N-digit random code, TTL (e.g. 5 min), limited attempts, single-use, resend with cooldown.
- Pluggable delivery channels (SMS/email → later push/WhatsApp) and swappable providers per channel.
Core design
- OtpService orchestrating: OtpGenerator (SecureRandom, configurable length), OtpStore (userId+purpose → hashed code, expiry, attempts — in-memory map or Redis with TTL), NotificationSender interface with SmsSender/EmailSender implementations (strategy), SenderFactory or registry choosing the channel (factory), provider adapters behind each sender (adapter) so Twilio→SNS swaps don't touch business logic.
- Validation path: fetch, check expiry → attempts → constant-time code compare → mark consumed.
Discussion points
- Which patterns and why: strategy (channels), factory (channel selection), adapter (providers), builder (notification message), observer/event for audit logging — justify each rather than name-drop.
- Security: store hashed OTPs, rate-limit generation and validation, don't reveal whether user or code was wrong.
- Extension exercise from the round: adding a new channel or fallback chain (SMS fails → email) with zero changes to OtpService — show the seam that makes it possible.
asked …