Acctz Node
Acctz Node is a Node.js / Fastify / TypeScript server with two independently deployable modes: a REST API that serves the Acctz UI, and a Firestore sync listener that keeps PostgreSQL and Firestore in sync. Both modes can run in the same process or as separate Cloud Run services.
Tech Stack
| Layer | Technology |
|---|---|
| Runtime | Node.js |
| Framework | Fastify 5 |
| Language | TypeScript |
| Database | PostgreSQL 18 (via pg) |
| Auth | Firebase Admin SDK (ID token verification) |
| OpenAPI | @fastify/swagger + @fastify/swagger-ui |
| Build | tsc |
| Dev | tsx watch |
Startup Modes
The server requires at least one mode flag at startup — either as a CLI argument or environment variable.
| Flag | Env var | What it starts |
|---|---|---|
--enable-rest | ENABLE_REST=true | Fastify REST API on PORT (default 3000) |
--enable-sync | ENABLE_SYNC=true | Firestore sync listener; health check on PORT (default 8080) |
Both flags can be combined to run both in a single process.
# REST only
npx tsx src/index.ts --enable-rest
# Sync only
npx tsx src/index.ts --enable-sync
# Both
npx tsx src/index.ts --enable-rest --enable-sync
If neither flag is set the process exits immediately with an error.
REST API
When started with --enable-rest, Fastify registers seven route groups, all protected by Firebase ID token verification:
| Tag | Routes |
|---|---|
entities | GET/POST /entities, GET/PUT/PATCH/DELETE /entities/:id |
accounts | GET/POST /entities/:entityId/accounts, GET/PUT/PATCH/DELETE …/:id |
journal-entries | GET/POST /entities/:entityId/journal-entries, GET/PUT/PATCH/DELETE …/:id |
parties | GET/POST /entities/:entityId/parties, GET/PUT/PATCH/DELETE …/:id |
iam-users | GET/PATCH /iam/users/me |
iam-orgs | GET/POST /iam/organizations, GET/PATCH/DELETE …/:orgId |
iam-memberships | GET/POST /iam/organizations/:orgId/memberships, GET/PATCH/DELETE …/:id |
The OpenAPI spec is served at /documentation/json; the Swagger UI is at /documentation.
Firestore Sync
When started with --enable-sync, the server runs startFirestoreSyncListener — a pg_notify-driven listener that streams PostgreSQL changes into Firestore in real time. This is the write path for the Firestore read layer used by the UI.
Running Locally
cd node
npm install
| Script | What it runs |
|---|---|
npm run dev | REST API only (--enable-rest) |
npm run dev:sync | REST API + sync listener |
npm run dev:sync-only | Sync listener only |
The REST server listens on http://localhost:3000; OpenAPI UI at http://localhost:3000/documentation.
Deployment
The same Docker image is deployed as two separate Cloud Run services via node/scripts/deploy.sh:
| Service | Mode | Visibility |
|---|---|---|
acctz-node-api | ENABLE_REST=true | Public, scales to zero |
acctz-node-sync | ENABLE_SYNC=true | Private, min 1 instance, 1 Gi RAM |
./node/scripts/deploy.sh
The script rebuilds the core package, regenerates the lockfile, builds and pushes the Docker image to Artifact Registry (us-east4, project acctz-ai-fs), then deploys both services to Cloud Run.
Integration with Acctz UI
The Acctz UI Vite dev server proxies /api requests to http://localhost:3000. In production, requests go to https://api.acctz.dev.