A shared lead pipeline
2026 · Serverless backend
One Edge Function behind eight sites, built so the public key in the browser bundle is worthless to an attacker.
- Supabase
- Deno
- PostgreSQL
- Cloudflare Turnstile
- Resend
Live
The problem
Eight sites all need to capture enquiries. The tempting shortcut is inserting straight from the browser with the anon key — but that key ships in the bundle, is trivially scraped, and a bot would fill the database and the notification inbox overnight.
What I built
- A single Deno Edge Function every site posts to: origin allowlist, hidden honeypot field, a minimum dwell-time check, then Cloudflare Turnstile verification before anything is written.
- Row-level security enabled with zero policies. The anon key can do literally nothing — only the service role writes, and only from inside the function.
- Phone numbers normalised to E.164 on the way in, with the display formatting done at read time.
- Notification failures are swallowed on purpose. The lead is already saved by that point, and telling a real prospect 'error' after capturing them is the worse bug.
- Attribution — landing path, referrer, UTM — captured on the row, so per-site performance is answerable without a separate analytics build.
What I took from it
The design rule was fail closed. If the captcha secret is missing, every submission is rejected — loud and fixable — rather than quietly accepting bot traffic. The one place that inverts is the notification, because there the safe failure is the opposite direction.