Skip to content

Operations

Environments

Environment Notes
dev Local pnpm workflow (pnpm dev).
production Vercel project mypaidtrafficbrandvelia.com, app.brandvelia.com.
shared DB Supabase project panoptes (São Paulo). Only the brandvelia schema is Brandvelia's.

Build & quality gates

Run from the monorepo root:

pnpm install      # install all workspace deps
pnpm build        # production build (Turborepo → Next.js app)
pnpm lint         # ESLint
pnpm typecheck    # tsc --noEmit across all packages
pnpm test         # Vitest (money path: INS decrypt, link builder, score, rate limit)

Gate: pnpm lint && pnpm typecheck && pnpm build && pnpm test must all pass before a change is complete.


Database migrations

Migrations are versioned SQL files under supabase/migrations/ and are additive-only on the shared brandvelia schema.

supabase db push --linked --dry-run   # preview what will be applied
supabase db push --linked             # apply (from repo root)
supabase migration list --linked      # local vs remote state
supabase db dump --linked -f backup.sql   # before structural migrations

Placeholders *_shared_panoptes.sql in the migrations directory are other systems' history applied to the shared database — do not edit or remove them.


Backup / disaster recovery (shared database)

panoptes is shared with other production systems, so any structural change requires a verified safety net before the migration is applied:

  1. Confirm the Supabase project has daily backups / PITR enabled (Dashboard → Database → Backups). This is an operator action and a hard gate for structural migrations.
  2. Take a logical dump before structural changes: supabase db dump --linked -f backup-$(date +%Y%m%d).sql.
  3. Rollback policy: migrations are additive-only, so the rollback of a bad migration is a new migration that disables/works around it — never DROP against shared objects.
  4. Restore drill: verify once per quarter that a backup actually restores (document the result here).
Date Drill Result
pending first drill

Deployment

Push to main (via PR) → Vercel deploys to production on brandvelia.com and app.brandvelia.com. The Next.js app is the Vercel project root directory.

DNS / Vercel protection: *.vercel.app URLs require SSO; custom domains are public (all_except_custom_domains).


Secrets (where each lives)

Secret Local Vercel Env var
Supabase anon key .env.local encrypted, 3 stages NEXT_PUBLIC_SUPABASE_ANON_KEY
Supabase service role .env.local encrypted, 3 stages SUPABASE_SERVICE_ROLE_KEY
OpenRouter key .env.local sensitive, 3 stages OPENROUTER_API_KEY
ClickBank INS secret ~/.brandvelia/clickbank-ins-secret (600) 3 stages CLICKBANK_NOTIFICATION_SECRET
ClickBank API keys (Key 1 + 2) ~/.brandvelia/clickbank-api.json (600) 3 stages CLICKBANK_API_KEY_1 / _2
Cron guard token .env.local 3 stages CRON_SECRET
Rate-limit store (Upstash) .env.local 3 stages UPSTASH_REDIS_REST_URL / UPSTASH_REDIS_REST_TOKEN
Marketplace feed URL (optional) 3 stages MARKETPLACE_FEED_URL

Server-side secrets never reach client bundles. The ClickBank/INS secrets are also vendored (with a lifetime cap) but never committed to the repo.


Browser automation

Some ClickBank flows use a local Playwright browser:

npx playwright test   # launches once, collects browsers, then exits

AI validation (E2E)

The Copilot pipeline is validated end-to-end: session → workspace → transactions → OpenRouter call → response citing SQL-computed values → logged to bv_ai_runs (tokens, cost, latency). Per-call cost is derived from the bv_ai_models registry.