Cloudflare + Supabase deployment

Production notes for running TariffsChart on Cloudflare Workers with Supabase Postgres.

TariffsChart is configured for Cloudflare Workers + OpenNext with Supabase Postgres as the production database.

This page is an operational checklist. It does not change the product boundary: TariffsChart remains a planning, evidence, and review workflow, not a customs broker or guaranteed landed-cost engine.

What changed

The codebase now includes:

  • wrangler.jsonc for Cloudflare Workers deployment;
  • open-next.config.ts for the OpenNext Cloudflare adapter;
  • cloudflare-worker.ts, a custom Worker entrypoint that delegates normal requests to the OpenNext handler and adds a scheduled() handler for tariff source-monitor checks;
  • cf:build, cf:preview, cf:deploy, and cf:typegen scripts in package.json;
  • Supabase-oriented PostgreSQL settings in .env.example and .dev.vars.example;
  • Postgres client options that disable prepared statements and avoid cross-request singleton reuse in Cloudflare/serverless runtimes;
  • optional Cloudflare Hyperdrive support through a HYPERDRIVE binding.

For production Cloudflare Workers, the safest path is:

  1. Keep DATABASE_PROVIDER=postgresql.
  2. Use Supabase Postgres.
  3. Prefer a Cloudflare Hyperdrive binding named HYPERDRIVE once traffic is meaningful.
  4. If Hyperdrive is not configured yet, use the Supabase Transaction Pooler connection string for DATABASE_URL and keep prepare: false.

Example Supabase pooler URL:

DATABASE_URL=postgresql://postgres.PROJECT_REF:PASSWORD@aws-0-REGION.pooler.supabase.com:6543/postgres?sslmode=require

The app automatically prefers env.HYPERDRIVE.connectionString when that binding exists, and falls back to DATABASE_URL otherwise.

Cloudflare secrets

Do not put real secrets in wrangler.jsonc. Set them with Wrangler:

pnpm wrangler secret put DATABASE_URL
pnpm wrangler secret put AUTH_SECRET
pnpm wrangler secret put TARIFF_MONITOR_CRON_SECRET
pnpm wrangler secret put RESEND_API_KEY

Optional payment secrets should stay unset until self-serve checkout is intentionally opened:

pnpm wrangler secret put STRIPE_SECRET_KEY
pnpm wrangler secret put STRIPE_WEBHOOK_SECRET
pnpm wrangler secret put CREEM_API_KEY
pnpm wrangler secret put CREEM_WEBHOOK_SECRET

Local preview

Use .dev.vars.example as a template:

cp .dev.vars.example .dev.vars

Then run:

corepack enable
pnpm install
pnpm cf:preview

Migrations

Generate and run migrations against Supabase before production deploy:

pnpm db:generate
pnpm supabase:migrate

If you prefer pushing schema during a private beta:

pnpm supabase:push

Use migrations for production once real users exist.

Deploy

pnpm cf:build
pnpm cf:deploy

pnpm cf:deploy uses --keep-vars, so Cloudflare dashboard or Wrangler secrets are not overwritten during deploy.

Scheduled source-monitor checks

wrangler.jsonc defines a daily cron trigger:

"triggers": {
  "crons": ["0 10 * * *"]
}

The custom Worker scheduled() handler calls:

POST /api/tariff/source-monitors/run

Set one of these secrets before relying on scheduled checks:

TARIFF_MONITOR_CRON_SECRET=replace-with-random-secret
# optional fallback
CRON_SECRET=replace-with-random-secret

Manual checks from /workspace/alerts still work for Pro beta and Team pilot users even if scheduled checks are not enabled.

Create a Hyperdrive configuration pointing at Supabase’s direct Postgres connection string, then add this binding to wrangler.jsonc:

"hyperdrive": [
  {
    "binding": "HYPERDRIVE",
    "id": "<cloudflare-hyperdrive-id>"
  }
]

When HYPERDRIVE is bound, TariffsChart uses that connection string automatically.

Launch checklist

Before production launch:

  • run pnpm install so pnpm-lock.yaml includes @opennextjs/cloudflare;
  • run pnpm lint and pnpm build locally or in CI;
  • run pnpm cf:preview against a staging Cloudflare Worker;
  • run migrations against Supabase;
  • confirm auth callback URLs use https://tariffschart.com;
  • set Cloudflare secrets;
  • verify scheduled monitor checks in Cloudflare logs;
  • keep public checkout disabled until billing, webhook, downgrade, refund, and legal review flows are ready.