Deployment
The site — Cloudflare Pages
Section titled “The site — Cloudflare Pages”The live lab (https://met-al-lab.pages.dev/) is a direct-upload Pages project (there is no git remote, so no git integration):
npx wrangler@latest pages deploy . --project-name met-al-lab --branch main --commit-dirty=trueRules that were learned the hard way (details in Lessons):
- Deploy the repo root, not
dist/— the served apps import../../lib/met-stats.mjs, so the whole tree must share one origin. Exclude.gitexplicitly (in a worktree it is a pointer file, which wrangler does not auto-skip). - Pin
--branch maineven when deploying from another branch’s worktree, or the deploy becomes a preview URL instead of production. - A deploy reporting “0 files uploaded” reuses the previous manifest — removing a file from the upload set does not remove it from the live site; change file content to force a real manifest.
The data — R2 + gated Worker
Section titled “The data — R2 + gated Worker”Real data lives in a private R2 bucket (met-al-data) and is served only through the
met-al-data-proxy Worker: GET /stores/* with Range/206 support, CORS, and an
Origin/Referer allowlist — no SSO, no public bucket.
Operational division of labor: conversion scripts and upload staging are automated, but bucket creation, R2 uploads, and Worker deploys are maintainer-run commands (the assistant’s safety tooling correctly refuses bulk uploads of internal data to internet-served destinations). Upload scripts are resumable (HEAD-skip existing objects) after a transient R2 500 mid-upload proved why that matters.
The docs site (this site)
Section titled “The docs site (this site)”docs-site/ is an Astro Starlight project:
cd docs-sitenpm installnpm run dev # local docs at localhost:4321npm run build # static site in docs-site/dist/It can be deployed as its own Pages project or mounted under the lab site; it is intentionally decoupled from the dependency-free apps.
