Skip to content

Deploy Environments (Dev / Production)

Neemias uses two deployment environments controlled by the DEPLOY_ENV build-time variable.

Git hooks (Husky)

O projeto usa Husky para hooks versionados (instalado automaticamente via pnpm install):

HookArquivoO que faz
pre-commit.husky/pre-commit6 gates: lint-staged, as any regression, Biome check, typecheck, doc lint, unit tests, E2E smoke
pre-push.husky/pre-pushDoc drift detection + pre-deploy check

Se qualquer gate falhar, o commit ou push e bloqueado com a mensagem do erro.

Environment matrix

EnvironmentDEPLOY_ENVSeed runs?URLBackend API
Dev (local)dev✅ Full seedlocalhost:5173(none — offline-only)
Productionproduction❌ Skippedapp.neemias.appapi.neemias.app

Important: app.neemias.app and api.neemias.app are production. They must have AUTH_MODE=jwt, ENVIRONMENT=production, and DEPLOY_ENV=production configured in Cloudflare Dashboard. See production-checklist.md.

Deploy script

scripts/deploy.sh automates the build:

bash
./scripts/deploy.sh        # production (default: NODE_ENV=production)

The script executes:

  1. pnpm -r test — all monorepo tests
  2. NODE_ENV=production DEPLOY_ENV=production pnpm build:app — production build with hash-based CSP
  3. npx wrangler deploy — Worker deploy
  4. npx wrangler pages deploy app/dist --project-name neemias — frontend deploy

How it works

Frontend (app/vite.config.ts)

ts
define: {
  __DEPLOY_ENV__: JSON.stringify(process.env.DEPLOY_ENV ?? "dev"),
}

When DEPLOY_ENV is not set (local dev, or Pages secret not configured), the default is "dev" — the seed runs normally.

Seed guard (app/src/db/seed.ts)

ts
const deployEnv = typeof __DEPLOY_ENV__ !== "undefined" ? __DEPLOY_ENV__ : "dev";
if (deployEnv === "production") {
  return; // no demo data in production
}

Backend seed (workers/src/routes/seed.ts)

The worker seed (POST /api/v1/_seed) is blocked when ENVIRONMENT=production is set in the Worker environment variables.

Configuring Cloudflare

Production

Set these in Cloudflare Dashboard:

ServiceVariableValueType
Worker (api.neemias.app)AUTH_MODEjwtPlain text
Worker (api.neemias.app)AUTH_JWT_SECRETopenssl rand -hex 32Secret
Worker (api.neemias.app)ENVIRONMENTproductionPlain text
Pages (app.neemias.app)DEPLOY_ENVproductionPlain text

Data flow per environment

text
┌──────────┐     ┌─────────────────────┐     ┌──────────────────────┐
│ Dev      │────▶│ Frontend SQLite WASM│◀────│ Worker D1 (seed)     │
│ (local)  │     │ demo data           │     │ demo data            │
└──────────┘     └─────────────────────┘     └──────────────────────┘

┌──────────┐     ┌─────────────────────┐     ┌──────────────────────┐
│  Prod    │────▶│ Frontend SQLite WASM│◀────│ Worker D1 (vazio)    │
│(no seed) │     │ Só dados reais      │     │ Só dados reais       │
└──────────┘     └─────────────────────┘     └──────────────────────┘

In dev (local), both the frontend and worker can be seeded with demo data. In production, neither seed runs. All data comes from real usage.

Pre-deploy checklist

Before any production deployment, run:

bash
bash scripts/pre-deploy-check.sh

This validates:

  • AUTH_MODE is not dev
  • app/public/_headers exists and uses hash-based CSP (no nonces)
  • scripts/validate-csp.sh passes (all required origins in connect-src)
  • workers/wrangler.toml exists
  • migrations/ directory exists
  • AUTH_JWT_SECRET is set (warning if missing)

See also:

Distribuído sob licença MIT.