Buckets:
HD-Basin Public Demo Setup
Target URL: https://hdbasin.pages.dev
Deployment status as of 2026-07-01:
- Cloudflare Pages project
hdbasinexists. - Production URL
https://hdbasin.pages.devreturns HTTP 200. - API health route
https://hdbasin.pages.dev/api/healthreturns OK. - Supabase env vars are configured in Cloudflare Pages.
- Free demo route
POST /api/demo/sessionis available for no-payment queue tests. - Stripe env vars are still pending until the Stripe account/test keys exist.
This repo now has the local foundation for the public demo:
- Vite React frontend in
web/ - Cloudflare Pages Functions under
web/functions/api/ - Supabase migration under
supabase/migrations/ - Stripe Checkout + webhook API routes
- A100 worker queue harness at
scripts/a100_worker.py
Accounts
Create or have access to:
- GitHub
- Cloudflare
- Supabase
- Stripe
- Gmail or other support email
- The current private A100 box
Optional later:
- Runpod or Modal for pay-on-demand GPU workers
- Sentry for error tracking
- UptimeRobot or Better Stack for uptime checks
- PostHog for funnel analytics
Cloudflare Pages
Sign up: https://dash.cloudflare.com/sign-up
Create a Pages project connected to the GitHub repo.
Use:
Project name: hdbasin
Production URL: https://hdbasin.pages.dev
Root directory: web
Build command: npm run build
Build output directory: dist
Set these environment variables in Cloudflare Pages:
SUPABASE_URL
SUPABASE_SERVICE_ROLE_KEY
STRIPE_SECRET_KEY
STRIPE_WEBHOOK_SECRET
PUBLIC_APP_URL=https://hdbasin.pages.dev
Supabase
Create a Supabase project and run:
-- Paste and run:
-- supabase/migrations/202607010001_hdbasin_public_demo.sql
The migration creates:
public.hdbasin_jobspublic.hdbasin_job_events- queue RPC functions for the worker
- private storage buckets
hdbasin-uploadsandhdbasin-results
Use the service-role key only in Cloudflare Pages Functions and the private A100 worker. Do not expose it in frontend code.
Stripe
Start in test mode.
Use Stripe Checkout Sessions for one-time payments.
Webhook endpoint:
https://hdbasin.pages.dev/api/stripe/webhook
Minimum events:
checkout.session.completed
checkout.session.expired
payment_intent.payment_failed
The webhook is the only thing that moves a job into queued.
Local Cloudflare Preview
cd web
cp .dev.vars.example .dev.vars
# Fill .dev.vars.
npm run pages:dev
Health check:
curl http://127.0.0.1:8788/api/health
A100 Worker
On the private GPU box:
cp .env.a100-worker.example .env.a100-worker
# Fill SUPABASE_URL and SUPABASE_SERVICE_ROLE_KEY.
set -a
. ./.env.a100-worker
set +a
python3 scripts/a100_worker.py --once
Without HDBASIN_RUN_COMMAND, the worker writes a pipeline-only demo report.
For the public demo, the A100 worker is now wired to a real small AG News
DistilBERT run through scripts/run_public_demo_job.py.
Once the paid runner is ready, set:
HDBASIN_RUN_COMMAND="python3 scripts/run_public_demo_job.py --job-id {job_id} --outdir {outdir} --trial-budget {trial_budget} --workload {workload} --file-name {file_name}"
This still uses a built-in public benchmark workload. Replace it with the real customer-dataset runner after private dataset upload/download is wired.
Demo Gate
Before public traffic:
- Cloudflare Pages deploy loads at
https://hdbasin.pages.dev. /api/healthreturns OK.- Supabase migration is applied.
- Stripe test webhook succeeds.
- Test checkout creates a job.
- Webhook changes the job to
queued. - A100 worker claims the job.
- Worker uploads report artifacts.
- Job ends as
succeeded. - Failure path marks jobs as
failedand does not leave them running forever.
Xet Storage Details
- Size:
- 3.81 kB
- Xet hash:
- 09255a50ad453e7ef843f977ae5245cfe55ecc661fbca90f0758616061e78320
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.