Skip to content

Getting started ​

This page takes you from a fresh checkout to the portal running locally on http://localhost:8787. All commands run from cloud/reform-assistant/.

Prerequisites ​

  • Node.js 22 or newer. The locked Wrangler release (4.x) declares "node": ">=22.0.0" in package-lock.json.
  • npm, which ships with Node.js.
  • No Cloudflare or Stripe account is needed for local development. Wrangler emulates D1 and R2 on disk under .wrangler/. Billing endpoints answer 503 billing_not_configured until you add Stripe values (see Stripe billing and Stripe setup).

1. Install dependencies ​

sh
cd cloud/reform-assistant
npm ci

npm ci installs exactly what package-lock.json pins. The Worker has no runtime dependencies; the devDependencies are Wrangler, TypeScript, Vitest with the Workers pool, the Workers type definitions, and VitePress for these docs.

2. Create the local database ​

sh
npm run db:migrate:local

This runs wrangler d1 migrations apply reform-assistant --local, applying migrations/0001_init.sql and migrations/0002_checkout_sessions.sql to the local D1 database. See Architecture for the tables it creates. Re-run it whenever a new migration file is added.

3. Configure local secrets ​

sh
cp .dev.vars.example .dev.vars

.dev.vars is read by wrangler dev and is git-ignored. The example file contains:

VariablePurposeNeeded for
APP_URLPublic origin of the portal. Defaults to http://localhost:8787. Used to build Stripe success, cancel, and portal return URLs. (The session cookie's Secure flag follows the request scheme, not this value.)Always
STRIPE_SECRET_KEYStripe test-mode secret key (sk_test_...).Checkout and billing portal
STRIPE_PRICE_MONTHLY, STRIPE_PRICE_QUARTERLY, STRIPE_PRICE_ANNUALStripe Price IDs (price_...) for the three plans.Checkout, plan detection in webhooks
HERMES_LINK_TOKENShared secret for the /api/hermes/* endpoints. Any long random string.Hermes bridge

STRIPE_WEBHOOK_SECRET (the whsec_... signing secret) verifies webhooks; without it POST /api/stripe/webhook answers 503 billing_not_configured.

Leave the Stripe values empty to explore signup, the inmate form, and the console without payments. Generate a Hermes token with, for example, openssl rand -hex 32.

4. Start the Worker ​

sh
npm run dev

npm run dev runs wrangler dev. Wrangler serves the Worker and the static assets from public/ on http://localhost:8787.

5. Open the pages ​

URLWhat you get
/Marketing landing page (public/index.html)
/signup/Create an account (name, email, password of at least 10 characters)
/login/Log in
/console/The family console (redirects to /login/ when there is no session)

A quick end-to-end check without Stripe:

  1. Open /signup/ and create an account. You land on /console/.
  2. Go to Inmate (/console/#inmate) and save an inmate.
  3. Go to Plan & billing (/console/#billing) and click Choose. Without Stripe secrets the console shows "Payments are not switched on yet (sandbox setup pending)." That message is the UI's handling of billing_not_configured.

Useful commands ​

CommandWhat it does
npm run devwrangler dev
npm run db:migrate:localApply D1 migrations to the local database
npm run typechecktsc --noEmit (strict)
npm testvitest run (see Testing)
npm run deploywrangler deploy (see Cloudflare deployment)
npm run docs:devServe these docs with VitePress
npm run docs:buildBuild the docs into docs/.vitepress/dist
npm run docs:previewPreview the built docs

Resetting local state ​

Local D1 and R2 data live under .wrangler/ (git-ignored). Deleting that directory and re-running npm run db:migrate:local gives you an empty database.