The DigiFX toolchain is built from small, single-purpose scripts rather than a framework. Every routine action — start, build, check, deploy — is one npm script, and every script is readable in a few minutes. This page covers what those tools are and what each one protects against.
01One command up, one command out
npm start brings up both local surfaces together: the application dev server and the release control console. They run as child processes of a single supervisor that shuts both down if either exits, so a Ctrl-C never leaves an orphaned server holding a port.
A production build is a chain, not a single step: stamp the calendar version, generate the environment file, compile, then run a post-build pass that injects preload hints into the home page. Deploys wrap that build with a deploy signal, publish the static sites, and then hand off to the Firebase CLI. Separate scripts exist for staging and for promoting a verified staging build, so "ship it" and "ship it to production" are different commands.
02Checks that run before a deploy
Several verification scripts exist independently of the test runner, each written because a specific class of mistake reached production once:
- A type check pass over the whole project, run through a signal wrapper so its result is recorded.
- A guard test suite executed in headless Chrome against the unit test runner, covering the
invariants that must never regress.
- An admin access-control check that validates the administrator allowlist against what the rules
actually grant.
- A route check that confirms a specific public route still resolves after a build.
- A diagnostics sync check that verifies the shared telemetry emitter is identical across every
function codebase, with a --write mode to repair drift.
03Environment pinning
A shell wrapper around the Firebase CLI — two lines of code under a comment block — exists because the deployed function runtime is Node 20, and running the CLI under a newer local Node caused its source-analysis step to crash inside a transitive dependency. The wrapper forces both the CLI binary and every process it spawns onto Node 20, so local analysis matches the deployed runtime. Every deploy path in the project goes through it.
04Guardrails inside the services
Some of the most important tooling is not in scripts/ at all — it is the constraint code inside the deployed functions. The AI proxy is the clearest example. It enforces a model allowlist so an arbitrary model string is rejected rather than forwarded, caps prompt length, applies a short per-caller request window, and prices every call server-side: the client never sends a cost, so a tampered client cannot buy compute for free. A daily failure guard fails closed after repeated errors, turning a runaway retry loop into a stopped one rather than an unbounded bill.
The storage presigner follows the same pattern with per-day upload and download caps and a byte ceiling. The principle is consistent across the platform: limits live on the server, in code, next to the operation they bound.