Read the story

Architecture

Adds the Rx to the scanner's case.Live on sample data.

Hybridge staff sign in through Google IAP and click through one made up practice, as the doctor or as the lab, with every case kept as sample data in Firestore. Real lab data is planned in two steps: the lab's own server through a connector that only sends out, then the MagicTouch API once its license is bought.

3.7 hours

from the sync that made it top priority to a working live link

4

things still pretend, listed on every release note

9 min

from the revision that failed its first visit to the one that fixed it

1,664 uploads

doctors made in the old portal since March 27, about ten a business day

New York --:-- simulated

A new Rx
Hybridge Doctor Portal Hybridge staff sign in through Google IAP and click through one made up practice, as the doctor or as the lab, with every case kept as sample data in Firestore. Real lab data is planned in two steps: the lab's own server through a connector that only sends out, then the MagicTouch API once its license is bought. Intraoral scanners the case starts here Launchpad relay feature requests Google IAP Hybridge accounts only MagicTouch DLCPM the lab's case system Lab connector planned, sends out only doctor-portal Cloud Run, Next.js 16 Doctor and Lab views one switch in the bar Lab lead, reviewers doctors come later Digital Gateway planned, no license yet Firestore portal_ collections Sample practice reseeds by version scan, new case read only changes out cases API calls pages use signed in ID token documents fills GCP hybridge-case-intake, us-east1

Hover a part to trace what it touches. Click it for its notes.

  • Built by me
  • Managed by Google
  • Outside system
  • Planned, not live
  • Main data path
  • On demand
  • Credentials cross

When it breaks

What each failure does, and what it does not do.

  1. Firestore refuses a shape

    The laptop store took arrays inside arrays and Firestore did not, so the first revision failed its first visit. A codec wraps them now, and a live round trip test proves it.

    apps/portal/lib/store/firestoreCodec.ts

  2. The sample fill fails

    A failed fill is not cached. The next request tries again instead of serving an empty portal until a restart.

    apps/portal/lib/app.ts:73

  3. The IAP audience is wrong

    Every sign in would be refused. The deploy reads the setting back and stops with a plain message if it did not land.

    scripts/deploy-portal.sh:79

What I tuned

Small choices that keep it fast and cheap.

  1. Scale to zero

    No minimum instances, at most three, 512 MiB each. A portal on sample data should cost nothing while nobody looks.

    scripts/deploy-portal.sh:72

  2. One store, two homes

    Memory on a laptop, Firestore when deployed, behind one small interface. Screens never touch the store directly.

    apps/portal/lib/store/types.ts

  3. Uploads stream through

    Feature request files up to 25 MB pass to the relay as the stream they arrive as, never read into memory.

    apps/portal/lib/featureRequests/relay.ts

Guards

Rules the code enforces, not rules people remember.

  1. One domain, matched exactly

    The app verifies IAP's signed header on every request and compares the domain after the last @, never as a suffix.

    apps/portal/lib/auth/iap.ts:37

  2. No forged names to Launchpad

    The person comes from the verified IAP identity only. Authorization, cookies and relay headers from the browser are dropped.

    apps/portal/lib/featureRequests/relay.ts:39

  3. One Rx per scan case

    An Rx for a case that already has one, or that belongs to another practice, is refused with a sentence that says what to do instead.

    apps/portal/app/(app)/rx/actions.ts:36

What it costs

Measured from the Google Cloud billing export, October 1 to 28, net of credits: six cents for the whole project, which it shares with the parked duplicate list. The portal went live on the 28th, a day still loading when measured, so its own month is not measured yet. Firestore does not show up at all.

$0.06in October

  • $0.05 Secret Manager, the parked app's
  • $0.01 Image registry
  • $0.00 Cloud Run, per request