Repository navigation
fix: honour SMS opt-outs in the live sender and close prospect races - #43
Open
Mcgyver-ai wants to merge 5 commits into
Open
Mcgyver-ai wants to merge 5 commits into
Mcgyver-ai wants to merge 5 commits into
Conversation
The Firebase function is the only live reminder sender and never read smsSuppressed, so leads who replied STOP kept getting texts.
…ransactional A double-clicked booked update fired reminders, webhooks and GHL appointments twice; concurrent inbound webhooks created duplicate prospects. deleteProspect uses recursiveDelete instead of a 500-write batch.
A comma-separated to slipped unsubscribed addresses past the suppression check, which hashes the whole string.
Contributor
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Follow-ups from a full-repo audit of
main(e493421), covering findings 1–4 and 6. Branched frommain, so it's independent of #39–#42.sendRemindersfunction has been the only live reminder sender since July, and it never readsmsSuppressed, so leads who replied STOP kept getting texts. #41 fixes only the disabled Vercel cron route. The function now normalizes the number to E.164, marks non-E.164 numbersfailed: invalid number, and marks opted-out leadsskipped(functions/smsGuard.js, CommonJS, sincefunctions/can't importlib/).lib/__tests__/smsGuard.test.js: suppressed lead stopped, local-format number failed without a lookup, valid number allowed.updateProspectreads, decides and writes in onerunTransaction, so the second of two concurrent booked updates sees the first one's write and fires no webhooks, reminders or GHL appointment.prospectService.test.js: a transaction reading an already-booked prospect fires nothing; normal transition still fires; missing prospect → 404.ingestInboundReplymatches-or-creates inside a transaction (tx.get(query)+tx.set). Firestore server transactions are serializable, so concurrent Meta webhooks for one sender can't both create a prospect.prospectService.test.js: creates inside the transaction when there's no match, reuses the match otherwise.tomust be exactly one address. nodemailer sends to every address in a comma list, and the unsubscribe check hashed the whole string, so"unsub@x.com, new@y.com"reached an unsubscribed address. NewoutreachRecipientSchema(single trimmed email); anything else → 400.schemas.test.js: comma, semicolon and display-name forms rejected.deleteProspectused one batch, which caps at 500 writes. It now usesdb.recursiveDelete, the same asaccountService.prospectService.test.jsupdated.Manual step after merge: the Cloud Function is deployed separately from Vercel. Run
firebase deploy --only functions:sendReminders, otherwise fix 1 isn't live.Not in this PR (logged in TASKS.md):
onProspectBookedstill storesprospect.phoneas typed. Those reminders now fail visibly instead of sending. Normalizing at save time should wait for fix: UK GDPR/PECR erasure, deletion callback and SMS opt-out #41'snormalizeE164.functions/lockfiles and the in-memory rate-limit growth (audit Fixsend-remindersworkflow auth header for cron endpoint #7, Install Vercel Web Analytics #8).Test plan
yarn test:Test Files 21 passed (21)/Tests 150 passed (150)yarn buildpasses (CI placeholder env):✓ Compiled successfully/✓ Generating static pages using 7 workers (75/75)node --check functions/index.js functions/smsGuard.js