Read the story

Architecture

Runs our controller's nine accounting scripts from one page.Built in one evening on Cloud Run.

Our controller uploads an export from Denticon, Paychex, Ramp, the bank or the lab system, and the page names the script, asks its questions in one form and hands back a QuickBooks import or a clean workbook. Reference workbooks and run logs sit in a Cloud Storage bucket, and every script edit is tested before it is committed to GitHub.

62 minutes

from the first commit to the first live revision on May 20

2 bugs

in the old scripts, fixed in the move: a missing comma and a misplaced line

3.7 hours

from the first commit to the browser editor our controller asked for, live at 7:56 PM

26 prompts

typed into a terminal across the nine old scripts, now asked up front in one form

New York --:-- simulated

An export uploaded
Accounting tools Our controller uploads an export from Denticon, Paychex, Ramp, the bank or the lab system, and the page names the script, asks its questions in one form and hands back a QuickBooks import or a clean workbook. Reference workbooks and run logs sit in a Cloud Storage bucket, and every script edit is tested before it is committed to GitHub. Our controller uploads, answers IAP Google sign in GitHub script history Exports Denticon, Paychex, bank Run page upload, one form Accounting tools FastAPI on Cloud Run Nine scripts prescan, then run Google Sheets cashflow, checks Cloud Storage inputs, outputs, refs Checks import own service, hourly Gmail labelled check sheets files upload signed header upload subprocess rows GCS Fuse publish checks import attachments GCP hybridge-accounting-tools, us-central1

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. A script crashes mid run

    It runs as its own process, so the server stays up and the page shows the exit code and the error output.

    app/runner.py:33

  2. A published edit is broken

    py_compile and the script's smoke test run in a copy first. On a failure the editor shows the error and nothing is committed.

    app/script_publish.py:20

  3. No git checkout at start

    The app starts anyway with the editor turned off, so running scripts still works.

    app/git_ops.py:34

What I tuned

Small choices that keep it fast and cheap.

  1. Scale to zero

    No minimum instances, at most three, one CPU and 1 GiB, with an hour allowed for a long run.

    .github/workflows/deploy.yml

  2. Excel stays Excel

    Reference data stayed in the three workbooks our controller already edits, on a GCS Fuse mount, instead of moving to a database.

    .github/workflows/deploy.yml:39

  3. The bucket cleans itself

    Uploads go after 7 days, outputs after 30, and old versions of reference files after 30.

    deploy/setup_gcp.sh:57

Guards

Rules the code enforces, not rules people remember.

  1. IAP header verified

    Every request carries IAP's signed header, and the app checks its signature, issuer and audience before it reads the email.

    app/auth.py:32

  2. Questions before writes

    Prescan never writes. Each Google Sheet tab gets its own confirm question before anything is written.

    scripts/cashflow_import.py:745

  3. The last admin stays

    The Access tab refuses to remove the last admin, and every access change goes to an append only audit log.

    app/routes/access.py:88