Architecture
Saves website leads and puts them on Monday.Replaces Tally and Zapier.
A patient's answers post from an iframe on our websites to forms-public, which saves them and their delivery jobs in one Firestore write. A private worker, woken at once by Cloud Tasks and every minute by Cloud Scheduler, puts the lead on Monday and sends the email copies.
1 min
longest a lead waits for the backup sweep when the instant wake fails
0
answers, names, emails or phones in any log line
14 days
from the first commit to Elmwood's contact form running on it, Oct 14
67 leads
backfilled on Monday with every UTM, the GCLID and the landing page
New York --:-- simulated
Hover a part to trace what it touches. Click it for its notes.
- Built by me
- Managed by Google
- Outside system
- Main data path
- On demand
- Credentials cross
When it breaks
What each failure does, and what it does not do.
-
Firestore is down
The inquiry goes to a private bucket, the patient still sees sent, and the 2 AM job moves it in.
packages/core/src/submit.ts:164
-
Both stores are down
The server answers 503. The browser retries for about 15 seconds with the same id, then keeps the answers on the device with a Try again button.
docs/security.md:59
-
Monday refuses a lead
The delivery retries after 1 minute, 10 minutes and 1 hour, then stops and alerts the developers. The inquiry was saved first, so nothing is lost.
packages/core/src/delivery/jobs.ts:15
What I tuned
Small choices that keep it fast and cheap.
-
Wake now, sweep as backup
A Cloud Tasks wake sends a lead right after the save. The minute sweep stays as the safety net and the retry clock.
packages/core/src/delivery/wake.ts:1
-
Answers and jobs, one write
The inquiry and its delivery jobs are created together, create only, so a retried send makes neither twice.
packages/core/src/submit.ts:151
-
One warm public instance
forms-public keeps one instance running, so the first patient of the morning never waits on a cold start. It is $7.14 of the $8.62 measured in October.
scripts/deploy.sh:794
Guards
Rules the code enforces, not rules people remember.
-
Answers never reach logs
The logger drops 18 field names, answers, email, phone, name and ip among them, and any value that is not plain text, a number or a boolean. Cloud Run request logs for both apps are excluded.
packages/core/src/log.ts:24
-
Public side cannot send
forms-public holds neither the Monday token nor the right to send email. Only the private worker does, and only two accounts may call it.
docs/security.md:52
-
Browsers never reach data
Firestore rules deny every read and write from a browser or phone. A patient's address is stored only as a salted hash.
firestore.rules:8
What it costs
Measured from the Google Cloud billing export, October 1 to 28, net of credits. A partial month: the first cost landed October 6. One warm public instance is $7.14 of it.
$9in October
- $7.74 Cloud Run, one warm instance plus requests
- $0.51 Cloud Build
- $0.23 Secret Manager
- $0.14 Scheduler, Firestore, storage, registry
