Boom Media
Boom Labs · Session Log

Session log

What changed, when, and why — newest first. Every entry records what shipped, what broke, what was decided, and what was left open, so nothing depends on remembering a conversation.

How to keep this. Add a new <div class="entry"> at the top of the timeline after each session. Keep the four headings — Shipped, Found & fixed, Decided, Open — because the value is in the last two: decisions you would otherwise re-litigate, and loose ends that would otherwise be lost.
29 July 2026

Twilio approval, an exposed database, and Rankee's site-wide audit

12 commits across 4 repos · 4 Labs docs · one live security exposure closed.

Shipped

RepoCommitWhat
Rankeec72c4e2Site-wide audit + Google Optimization — audits only ever read the homepage
265299aRetry transient DataForSEO failures instead of failing the whole batch
90c76b5Stop discarding keywords when the SERP fetch fails
1344edbPick a tracked keyword when running a Local Falcon scan
2eae64aTie Local Falcon scans to clients; locations sync button
9dc4074Show unrun migrations in Admin before they look like broken features
bm-vercel70506d6SMS consent checkbox — the A2P 10DLC rejection fix
922f09cStop crawlers hitting protected preview deployments (the GSC 401)
5cc88c0Replyee chat lead webhook receiver → SureContact
baf8d76Homepage headline widened beyond restaurants
Replyeed33211cPer-bot Quick Questions chips in the chat widget
Bloggybbf3ab4Stop bot spam on the waitlist endpoint

Found & fixed

Closed  Twilio A2P 10DLC campaign approved

Rejected on error 30896 — the contact form had no SMS opt-in checkbox. Added a dedicated, unchecked, optional checkbox with full disclosures plus proof-of-consent storage (verbatim language, version, URL, timestamp, server-side IP and user agent). Approved the same day; campaign CM9fc0398… is registered with the carriers.

Critical  The shared database was readable by anyone

Supabase linter output turned out to be an active, exploitable exposure. The anon key is public by design and Replyee's /api/bot-config hands it to every visitor of every client site. Verified with that key: email_verifications (10 rows) and loyalty_transactions (4 rows) were readable by anyone. password_reset_tokens was equally unprotected — empty at that moment, but world-readable the instant anyone requested a reset.

Closed via staged RLS SQL. Re-verified afterwards with the same key: zero rows. BOO's menu API still returned 15 categories / 154 items, so ordering never broke. Storage buckets fh-media, client-documents, cmd-lead-photos and backups made private; 25 functions had search_path locked.

Rankee audits only ever read the homepage

boommedia.us scored 100/100 with zero issues because its homepage genuinely is clean — while 14 of its other 29 pages had truncated titles, 10 had over-long descriptions, one served no H1, and 31 pages were missing from the sitemap. Built a real site-wide crawler plus 16 site-level checks.

Keywords were being silently discarded

A transient DataForSEO 40101 meant the keyword was never registered for tracking at all — you would have re-entered those nine forever with nothing indicating they had been lost.

Bloggy: removing a form does not remove the endpoint

The waitlist form was gone from the page but /api/waitlist was still live and unprotected, so bots kept posting. It also interpolated user input unescaped into the notification email. Added a honeypot, validation, escaping and a gibberish heuristic — verified against both real spam samples and 17 legitimate business names.

Decided

Open

Corrections made to my own work

Recorded because they are the kind of thing that quietly becomes folklore:
  • Said Rankee was on Coolify needing manual deploys — wrong, it is on Vercel and auto-deploys.
  • Reported 4 orphan pages in the SEO audit — actually 31; I had read static routes only and missed services/[slug].
  • Called fh-media an active resident-data breach — it is empty; unprotected but unpopulated.
  • Put DataForSEO 40102 and 40200 in the retry set — one is a real answer, the other an empty balance.
  • Said the Bloggy folder was broken — it is not; it tracks master while production deploys from an unrelated main.
  • Corrupted a file with a NUL byte from my own heredoc; caught and fixed before commit.

Docs added to Labs

Housekeeping

.md/ reorganised into ecosystem/ boo/ infrastructure/ integrations/ builds/; new SaaS/README.md maps the workspace. A drift check across all 17 repos confirmed nothing is unpushed — and surfaced that Bloggy has two unrelated histories on GitHub, with the local folder tracking the branch that is not deployed.