Skip to content

Environments & Infrastructure

Three environments — Dev, Test, Prod (plus local). Each maps to a branch in both repos. Verified against commit history on 2026-06-24.

Environment Frontend — branch → host Backend — branch → API LangGraph
Dev dev → dev.consumr.ai dev → dev-api.consumr.ai pw-dev-maven
Test test → test.consumr.ai test → test-api.consumr.ai pw-dev-maven
Prod main → app.consumr.ai app → app-api.consumr.ai (api.consumr.ai = legacy) pw-prod-maven
Local feature branch → localhost dev-api / 127.0.0.1:5001 pw-dev-maven
📎 Evidence
  • Dev FE branch is devpw-enterprise-frontend git — git branch -a shows remotes/origin/dev; a Dev workflow exists in .github/workflows/dev.yml. ✅
  • Dev FE host dev.consumr.aipw-enterprise-frontend/src/api/config.js:144-152 — hostname branch sets url = dev, environment = 'dev'. ✅
  • Dev BE branch is devpw-enterprise git — remotes/origin/dev exists; backend .github/workflows/dev.yml named dev. ✅
  • Dev BE API dev-api.consumr.aipw-enterprise-frontend/src/api/config.js:18const dev = 'https://dev-api.consumr.ai' assigned when hostname is dev.consumr.ai. ✅
  • Dev LangGraph pw-dev-mavenpw-enterprise-frontend/src/api/config.js:31 and pw-enterprise/api/product_health.py:55-58 — both map dev to the pw-dev-maven deployment URL. ✅
  • Test FE branch is testpw-enterprise-frontend git — git branch -a shows remotes/origin/test exists. (Finder wrongly marked this unverifiable; the branch IS present.) ✅
  • Test FE host test.consumr.aipw-enterprise-frontend/src/api/config.js:135-143 — hostname branch sets url = test, environment = 'test'. ✅
  • Test BE branch is testpw-enterprise git — remotes/origin/test exists. Note .github/workflows/test.yml is an API-test workflow targeting alpha, NOT a test-env deploy. ✅
  • Test BE API test-api.consumr.aipw-enterprise-frontend/src/api/config.js:19,136const test = 'https://test-api.consumr.ai' assigned when hostname is test.consumr.ai. ✅
  • Test LangGraph pw-dev-mavenpw-enterprise-frontend/src/api/config.js:142-143 — under test.consumr.ai, langgraphDeployment = 'dev' and langraphUrl = langgraphDevUrl. ✅
  • Prod FE branch is mainpw-enterprise-frontend git — git symbolic-ref refs/remotes/origin/HEAD = refs/remotes/origin/main; Main workflow runs main-action.sh. ✅
  • Prod FE host app.consumr.aipw-enterprise-frontend/src/api/config.js:127-134 — hostname branch sets url = app, environment = 'app'. ✅
  • Prod BE branch is apppw-enterprise git — git symbolic-ref refs/remotes/origin/HEAD = refs/remotes/origin/app; local * app. ✅
  • Prod BE API app-api.consumr.aipw-enterprise-frontend/src/api/config.js:17,129const app = 'https://app-api.consumr.ai' assigned under app.consumr.ai. ✅
  • api.consumr.ai is legacy (not active)pw-enterprise-frontend/src/api/config.js:15 declares const api = 'https://api.consumr.ai' but no hostname branch assigns it to url; active prod is app-api.consumr.ai. Table now marks it legacy. ✅
  • Prod LangGraph pw-prod-mavenpw-enterprise-frontend/src/api/config.js:32 and pw-enterprise/api/product_health.py:55-57 — both map app to the pw-prod-maven URL. ✅
  • Local FE = feature branch → localhostpw-enterprise-frontend/src/api/config.js:103-125 — code routes localhost/local.consumr.ai hostnames; the ‘feature branch’ part is convention, not code-enforced. ⚠️
  • Local BE = dev-api / 127.0.0.1:5001pw-enterprise-frontend/src/api/config.js:104,118local.consumr.ai defaults to 127.0.0.1:5001 (via VITE_API_URL); plain localhost sets url = dev. ✅
  • Local LangGraph pw-dev-mavenpw-enterprise-frontend/src/api/config.js:124-125localhost sets langgraphDeployment = 'dev', langraphUrl = langgraphDevUrl. ✅
  • Promotion flow: dev → test → prod (visible in git history — test is fed by merges from dev).
  • Environment selection: the frontend resolves its environment at runtime by hostname (src/api/config.js), not a build flag.
  • Deploys: manual — GitHub Actions workflow_dispatch on a self-hosted runner running shell scripts (dev-action.sh / main-action.sh for FE; pw-enterprise-dev-server.sh / pw-enterprise-main-server.sh for BE). The frontend dev deploy also purges the Cloudflare cache (the prod main.yml has no purge job).
📎 Evidence
  • Promotion dev → test → prodpw-enterprise git merge log on test — shows merges of app INTO test and PRs #9841 (I5216) etc.; a literal merge dev into test was not seen. Flow is convention-supported, not a hard pipeline. ⚠️
  • Env resolved at runtime by hostnamepw-enterprise-frontend/src/api/config.js:4,103-160 — reads window.location.hostname then if/else-if chain sets url/env/langgraph; only VITE_API_URL overrides local URL. ✅
  • Manual deploys via workflow_dispatchpw-enterprise/.github/workflows/dev.yml:2, Main.yml:3-4, pw-enterprise-frontend/.github/workflows/dev.yml:2, main.yml:2 — all use on: workflow_dispatch. ✅
  • Self-hosted runnerpw-enterprise/.github/workflows/dev.yml:9 & Main.yml:8, pw-enterprise-frontend/.github/workflows/dev.yml:9 & main.yml:9 — all jobs declare runs-on: self-hosted. ✅
  • FE dev deploy runs dev-action.shpw-enterprise-frontend/.github/workflows/dev.yml:11-15cd /home/coder/rushab/; time ./dev-action.sh. Script lives on the runner, not in repo. ✅
  • FE prod deploy runs main-action.shpw-enterprise-frontend/.github/workflows/main.yml:11-15cd /home/coder/rushab/; time ./main-action.sh. ✅
  • BE dev deploy runs pw-enterprise-dev-server.shpw-enterprise/.github/workflows/dev.yml:11-15cd /home/coder/rushab/; time ./pw-enterprise-dev-server.sh. ✅
  • BE prod deploy runs pw-enterprise-main-server.shpw-enterprise/.github/workflows/Main.yml:10-14cd /home/coder/rushab/; time ./pw-enterprise-main-server.sh. ✅
  • FE cache purge is dev-onlypw-enterprise-frontend/.github/workflows/dev.yml:18-26 runs purge_profitwheel_cache.sh after deploy; main.yml (prod) has no purge job. Doc now scopes this to dev. ✅
📎 Evidence
  • Stale production branch exists (BE)pw-enterprise git — git branch -a lists remotes/origin/production. ✅
  • production last commit April 2024pw-enterprise git — git log -1 remotes/origin/production = 2024-04-11 17:51:49 ‘Added tracing for answer engine’. ✅
  • Real prod branch is app (default)pw-enterprise git — git symbolic-ref refs/remotes/origin/HEAD = refs/remotes/origin/app; local checkout shows * app. ✅

Known providers: GCP (Secret Manager, BigQuery), Azure (Key Vault — legacy), Cloudflare (Pages, Workers; Worker edge bindings: AI, Vectorize ×3, Hyperdrive). Cloudflare R2 is used for object storage server-side (boto3), not as a Worker binding.

📎 Evidence
  • GCP Secret Manager (primary)pw-enterprise/library/gcp_secrets.py:1-18 & pyproject.toml:101 — imports google.cloud.secretmanager; SDK google-cloud-secret-manager>=2.26.0 declared (line 101, not 100). ✅
  • GCP BigQuerypw-enterprise/api/common.py:4,11 & pyproject.toml:100from google.cloud import bigquery; client = bigquery.Client(); SDK google-cloud-bigquery>=3.39.0 declared. ✅
  • Azure Key Vault is legacypw-enterprise/library/gcp_secrets.py:3-5 (docstring ‘replacing Azure Key Vault’), library/secrets.py:109-116 (*_key_vault fns delegate to GCP), pyproject.toml:27-28, .env:91-93 (AZURE_* keys empty). ✅
  • Cloudflare Pages (FE hosting)pw-enterprise-frontend/wrangler.toml:3pages_build_output_dir = "dist" is the Cloudflare Pages config key. ✅
  • Cloudflare Workerspw-enterprise-frontend/src/api/config.js:13 (a *.profitwheel.workers.dev worker URL) & pw-enterprise/pyproject.toml:31 (cloudflare>=4.3.1 SDK). ✅
  • Workers AI bindingpw-enterprise-frontend/wrangler.toml:13-14,22-23[ai] binding = "AI" for both default and [env.production]. ✅
  • Vectorize binding (×3 indices)pw-enterprise-frontend/functions/_middleware.ts:11-13 and worker-configuration.d.ts:9-11 declare VECTORIZE_INDEX_SMALL/BASE/LARGE: VectorizeIndex in the Worker Env; configured via the Pages dashboard (only AI is declared in wrangler.toml), which is why wrangler.toml alone doesn’t list it. ✅
  • Hyperdrive bindingpw-enterprise-frontend/functions/_middleware.ts:14 (PRODDB: Hyperdrive) and worker-configuration.d.ts:12 (DEVDB: Hyperdrive) declare it in the Worker Env; configured via the Pages dashboard, not wrangler.toml. ✅
  • Cloudflare R2 (object storage, server-side)pw-enterprise/library/storage.py:1-7,32-37 builds a boto3 S3 client against *.r2.cloudflarestorage.com; .env:144-148 define the R2 keys. Used server-side, not as a Worker edge binding. ✅
📎 Evidence
  • Cloud inventory pending notepw-docs/src/content/docs/environments-infrastructure.mdx:28-31 — self-describing status note in the doc; not a factual system claim. 🔍 needs: cloud-account access to enumerate full per-provider inventory. ✅