Skip to main content

Quantago Dev Environment

Isolated dev stack for active coding & testing. Provisioned 2026-04-28.

URLs​

SurfaceProdDev
Frontendhttps://app.quantago.cohttps://dev.quantago.co
APIhttps://api.quantago.cohttps://dev-api.quantago.co
Pagesquantago-app.pages.devquantago-dev-app.pages.dev
Workerquantago-apiquantago-dev-api
DatabaseNeon ep-patient-glade-akbt9n8kNeon ep-calm-truth-ak38uzzc (project quantago-dev, id flat-bonus-34310933)

Login (dev)​

  • email: [email protected]
  • password: QuantagoDev!1b5c2b5c (from the provisioning secret blob)
  • role: admin

What is isolated​

  • Database — separate Neon project, separate neondb schema, ran all 12 migrations cleanly.
  • Worker — quantago-dev-api is a distinct Worker script. Separate Durable Objects, separate Workflows (named *-dev).
  • Auth — fresh BETTER_AUTH_SECRET, fresh INGESTION_ADMIN_SECRET. Sessions don't cross between envs.
  • Cron — disabled on dev (triggers.crons = []) so dev never auto-mutates ClickHouse / Finnhub.
  • Pages project — quantago-dev-app, separate deploys from prod.

What is shared (intentional)​

  • 3rd-party API keys: Google OAuth, cTrader, Alpaca, Finnhub, Twelve Data — these are vendor-side credentials, no risk in sharing read-only or sandbox keys.
  • Cloudflare account, R2 buckets (none configured yet), AI binding.

How dev was provisioned​

  1. Neon project created via REST: POST https://console.neon.tech/api/v2/projects with org org-frosty-salad-83675640. Returned project flat-bonus-34310933.
  2. Migrations applied: DATABASE_URL=<dev pooler> bash scripts/migrate-neon.sh.
  3. Wrangler [env.dev] block added to services/backend/wrangler.jsonc — duplicates the workflows / DOs / migrations / AI bindings under the new name quantago-dev-api, overrides vars with dev URLs and ENABLE_DEFAULT_ADMIN_SEED=true, disables cron.
  4. First deploy: wrangler deploy --env dev (creates the Worker).
  5. Secrets: bash scripts/provision-dev-env.sh secrets generates fresh BETTER_AUTH_SECRET + INGESTION_ADMIN_SECRET, sets DATABASE_URL=<dev>, PROD_DATABASE_URL=<prod>, copies vendor API keys, uploads via wrangler secret bulk.
  6. Custom domain for dev API: bash scripts/provision-dev-env.sh dns calls the Workers Custom Domains API. Uses the legacy CF global key for the DNS CNAME because the scoped API token doesn't have Zone:DNS:Edit.
  7. Dev Pages project: wrangler pages project create quantago-dev-app, then build with VITE_API_URL=https://dev-api.quantago.co and wrangler pages deploy dist.
  8. Pages custom domain: dev.quantago.co CNAME → quantago-dev-app.pages.dev, plus POST /pages/projects/quantago-dev-app/domains to bind it.

Re-provisioning / refreshing dev​

cd projects/quantago

# Push secrets only (idempotent)
bash scripts/provision-dev-env.sh secrets

# Push DNS / domain bindings only (idempotent)
bash scripts/provision-dev-env.sh dns

# Both
bash scripts/provision-dev-env.sh all

Deploying​

# Backend dev
cd services/backend
pnpm exec wrangler deploy --env dev

# Frontend dev
cd ../..
VITE_API_URL=https://dev-api.quantago.co \
pnpm --filter @quantago/frontend build
cd services/frontend
pnpm exec wrangler pages deploy dist \
--project-name=quantago-dev-app \
--branch=main --commit-dirty=true

Frontend API target switcher​

The dev frontend renders a small env selector in the header (only on dev.quantago.co and localhost). Choices:

  • auto — uses dev API on dev.* host, local API on localhost
  • dev — force https://dev-api.quantago.co
  • prod — force https://api.quantago.co (⚠ red banner — talks to prod data)
  • local — force http://localhost:8787

Selection is persisted in localStorage['quantago.apiTarget'] and triggers a reload.

Known follow-up​

  • Per-request prod-DB override (an admin-only header X-Db-Override: prod on the dev backend that swaps DATABASE_URL for one request) is not yet implemented. The PROD_DATABASE_URL secret and ALLOW_PROD_DB_DEBUG var are already provisioned on the dev worker so it can be added in a follow-up without re-provisioning. For now use the frontend "prod API" target switcher to talk to the prod backend instead.
  • Pulumi: Pulumi.dev.yaml is not yet authored. Today the dev env is encoded in wrangler.jsonc [env.dev] and the provisioning script. Promoting that to Pulumi is a follow-up.
  • Admin pages project for dev (dev-admin.quantago.co) — referenced in vars.ADMIN_ORIGIN but not deployed.
  • Admin password rotation — current value QuantagoDev!1b5c2b5c was generated by the script. To rotate, edit scripts/.dev-env.local to set DEV_ADMIN_PASSWORD=... and re-run provision-dev-env.sh secrets, then update the user row directly via psql or use the Better Auth password change flow.

Files added/changed​

  • services/backend/wrangler.jsonc — env.dev block.
  • services/backend/src/auth/auth-env.ts — added dev.quantago.co and quantago-dev-app.pages.dev to allowed origins.
  • services/frontend/src/lib/runtime-config/index.ts — runtime API target switcher + dev.<domain> → dev-api.<domain> host inference.
  • services/frontend/src/components/layout/header/DevApiTargetSwitcher.tsx — new component.
  • services/frontend/src/components/layout/header/Header.tsx — mounts the switcher.
  • scripts/provision-dev-env.sh — secrets bulk-upload + DNS/domain binding.
  • scripts/.dev-env.local — gitignored local override (DEV_DATABASE_URL).
  • .gitignore — ignores scripts/.dev-env.local.