Read the story

Architecture

Syncs Denticon into the planner every minute.Read only, on Cloud Run and Postgres.

A minute sync pulls changed appointments from the CDF mirror into Postgres. One pure engine does all the planning math, the same code on the server and in the browser, so a what if and the real board can never disagree.

60 s

from a booking in Denticon to the board

0

write methods toward Denticon, held by a type test

17 days

from the first commit to v0.1.0 in production

$1.29

for Cloud Run in October, a sync every minute included

New York --:-- simulated

Next sync
Hybridge Capacity Planner A minute sync pulls changed appointments from the CDF mirror into Postgres. One pure engine does all the planning math, the same code on the server and in the browser, so a what if and the real board can never disagree. Cloud Scheduler sync every minute OIDC Google sign in NextAuth v5, 2 domains Denticon practice system CDF registry API mirror, holds the creds capacity-prod Cloud Run, Next.js 16 Planner board React 19, polls every 60 s Ops and directors 3 offices Google Workspace calendar read, 7 AM email Postgres 16 Cloud SQL, audit rows Planning engine pure TypeScript, zero IO API changed rows POST /tasks/sync SQL pages use sign in what if read + send GCP hybridge-capacity-planner, us-east1

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.

  1. Denticon or the CDF is slow

    The sync still answers 200, so the scheduler never retries into a storm. A pill on the board says how old the data is.

    docs/runbook/incidents.md

  2. A minute missed a change

    Most minutes read only changed rows. A full read at least once an hour heals anything a delta missed.

    STATUS.md:12

  3. A release goes bad

    Traffic flips back to the last revision in about ten seconds. Migrations only ever add, so the old code still runs.

    docs/runbook/operations.md:60

What I tuned

Small choices that keep it fast and cheap.

  1. One engine, two places

    The same pure package runs in the sync and in the browser. There is no second copy of a rule to drift.

    docs/architecture/0001-stack-decisions.md

  2. Deltas, not dumps

    The first full read was about 12,300 rows. After that, most minutes move only what changed.

    STATUS.md:12

  3. Poll the version, not the data

    Open boards ask a tiny endpoint whether anything changed, then offer a refresh. No hot swapping under someone's cursor.

    docs/architecture/0001-stack-decisions.md

Guards

Rules the code enforces, not rules people remember.

  1. Zero write methods

    A type level test fails the build if anything shaped like create, update, cancel or book appears on the Denticon contract.

    packages/engine/test/types.test.ts:14

  2. No Denticon credential here

    Only the CDF holds one. This project could not write to Denticon even if it tried.

    docs/runbook/README.md

  3. Patient names stay out of logs

    The logger redacts patient fields and the query logger is off everywhere. Fixture tests print counts, never values.

    docs/architecture/SECURITY.md:59

What it costs

Measured from the Google Cloud billing export, October 1 to 28, net of credits. The always on database is nine tenths of it. A sync every minute, all month, costs $1.29.

$27in October

  • $24.98 Cloud SQL, always on
  • $1.29 Cloud Run, per request
  • $0.64 Secret Manager
  • $0.15 Scheduler and image registry