Architecture
Lists every Hybridge app on one board.On Cloud Run, behind IAP.
Anyone with a Hybridge Google account passes IAP and opens any app from one board of 38 projects grouped by status. Four leaders also see Work and History, and one editor changes the cards, each save writing the project and its history entry in a single Firestore transaction.
78 minutes
from the first commit to a working live board on Oct 22
1 editor
moves or edits a card. Four leaders read Work and History, and everyone else sees Apps
38 projects
on one board in panes by status, 22 of them live
21 edits
logged since launch, each with who, when, and every field's old and new value
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.
-
The bundle loses Firestore
A dynamic import in the Next production bundle exposed the Firestore class only under default, so every page failed with 'b is not a constructor'. The loader takes either shape now, and a test covers both.
lib/store/index.ts:70
-
The signed header fails
No valid IAP assertion means no email. The page still loads with the Apps tab, and Work, History and editing stay hidden.
lib/viewer.ts:75
-
Two instances seed at once
The seed uses create(), which fails when the document exists, so a second instance cannot overwrite an early edit.
lib/store/firestore.ts:56
What I tuned
Small choices that keep it fast and cheap.
-
Scale to zero
No minimum instances, at most two, 1 GiB each. Request time for all three services in the project came to under two cents in October.
scripts/deploy.ps1:263
-
One store, two homes
A JSON file on my laptop, Firestore when deployed, behind one small interface the tests fake.
lib/store/index.ts:36
-
History without an index
One project's history is short, so it is sorted in memory instead of with a composite Firestore index.
lib/store/firestore.ts:105
Guards
Rules the code enforces, not rules people remember.
-
Signed header, verified
The email comes only from IAP's signed assertion, checked against Google's keys and this service's audience. The unsigned header is ignored.
lib/viewer.ts:75
-
History is append only
Each save writes the project and its history entry in one transaction. Entries are only ever created.
lib/store/firestore.ts:87
-
Deploy refuses a dirty tree
Cloud Run builds the folder as it is, so the script stops on uncommitted files or any branch but main, then runs the tests and a build.
scripts/deploy.ps1:141
What it costs
Measured from the Google Cloud billing export, October 1 to 28, net of credits, for the whole project. It holds Launchpad, its request relay and the June board it replaced, whose daily sync job and secrets make up most of the bill. Firestore does not show up at all.
$0.32in October
- $0.20 Secret Manager, three secrets
- $0.04 Scheduler, the June sync job
- $0.04 Cloud Run, jobs and requests
- $0.04 Image registry
