This repo follows the shared JustEvery starter conventions. See README.md
for the full workflow and environment guidance.
apps/web/hosts the Expo placeholder shell; share config viapackages/config.apps/web/src/profile/exposesuseJustEveryProfilePopupwhich wraps the hostedprofile-popup.jshelper from the login worker. UseopenProfilePopupin the app shell to show account/settings/orgs/billing; the helper handles the iframe and events.workers/api/runs the Cloudflare Worker with Wrangler config, D1 access, and Vitest suites; keep bindings inEnv.docs/archive/keeps operational playbooks (bootstrap, deployments, SSO) cited inPLAN.md; refresh when flows or providers change.tests/e2e/holds Playwright journeys against the deployed worker; keep fixtures aligned with seeded data.- Root helpers:
pnpm bootstrap:*commands provision Cloudflare + Stripe resources via the typed CLI.
npm run dev– Starts both dev processes: the Worker (dev:worker) and the Expo web shell (dev:local) with loopback overrides.npm run dev:worker– Wrangler dev server (wrangler dev --config workers/api/wrangler.toml) backed by Miniflare; honours.dev.varsfor env/bindings. Add D1/R2 bindings there so tests mirror production. Usenpm run dev:worker:localwhen you need localhost overrides without mutating.env.npm run dev:local– Rewrites.env.local+workers/api/.dev.varsfor localhost origins and launches the Expo web shell with those overrides (mirrors the login repo’sdev:local). Assumes the Better Auth worker runs athttp://127.0.0.1:9787; exportJE_LOCAL_LOGIN_ORIGINto change it.npm run build– Runs workspace builds (expo export, Worker bundle).npm test --workspace workers/api– Vitest unit suites.npm run test:e2e– Playwright againstE2E_BASE_URLorPROJECT_DOMAIN.scripts/deploy.sh --mode deploy|dry-run– Single source of truth for every deploy path. This script runs the Expo build, client smoke tests, env audit, bootstrap plan, migrations, worker deploy, and HTTP smoke probes. Update this file (and nowhere else) when changing deploy behaviour.pnpm bootstrap:deploy/pnpm bootstrap:deploy:dry-run– Still available under the hood, but the unified script orchestrates their usage. Call these directly only for debugging.- Pushing to
mainautomatically triggers the GitHub deploy workflow tostarter.justevery.com; monitor that run withgh run watch --branch mainwhen shipping user-visible changes.
- Always run
scripts/deploy.sh --mode deployfor production pushes andscripts/deploy.sh --mode dry-runfor validation. CI uses the exact same script, so any change to the deploy sequence must land in this file to avoid drift. - The deploy script executes
pnpm audit:deploy-env, which reads.env.ci/.env.generatedto ensure Cloudflare, Stripe, Better Auth, and billing credentials are present and non-placeholder before proceeding. Fix failing audits before re-running. - Post-deploy verification curls
/api/statusand/api/stripe/productsusingPROJECT_DOMAIN. Keep this updated if domains change. - Repo-specific deploy overrides are passed via the
ENV_BLOB_OVERRIDEsecret (base64 env lines) in CI; local overrides live in.env.repo(ignored by git). - This repo is isolated:
PROJECT_ID=starter,PROJECT_DOMAIN=https://starter.justevery.com,D1_DATABASE_NAME=starter-d1,CLOUDFLARE_R2_BUCKET=starter-assets(set viaENV_BLOB_OVERRIDE).
- TypeScript is strict via
tsconfig.base.json; add explicit return types on exported helpers and updateEnvwhen bindings change. - Use 2-space indentation, trailing commas, PascalCase for components, camelCase for hooks/utilities, and keep secrets in config packages rather than source files.
- Place unit tests under
workers/api/testwith*.test.tsnames; focus on behaviour (auth, asset serving, migrations). - Keep Playwright specs idempotent and rely on data seeded by the bootstrap CLI; add fixtures under
tests/e2e/__fixtures__when needed. - New endpoints need Vitest coverage plus an end-to-end check proving auth and the happy path.
- Follow the imperative, scope-prefixed style in history (
chore: upgrade toolchain,Add Worker unit tests) and avoid noisy WIP commits. - PRs should outline scope, list verification commands (
npm test --workspace workers/api,npm run test:e2e), and document any env/config updates or manual steps. - Link relevant roadmap items (
PLAN.md), update docs, and supply screenshots or curl transcripts for user-visible changes.
- Run the CLI (
pnpm bootstrap:preflight,pnpm bootstrap:env,pnpm bootstrap:deploy) after cloning and when infra config changes; it is idempotent and reuses the.envmetadata to skip recreating Cloudflare or Stripe resources. - Record updates to secrets, Better Auth, or Stripe setup in
docs/better-auth.md(Better Auth integration) ordocs/archive/DEPLOYMENTS.md, and mirror changes in.dev.varsfiles. FONT_AWESOME_PACKAGE_TOKENlives in~/.env; thescripts/sync-fontawesome-token.mjspreinstall hook now reads that file automatically so pnpm installs pull the private Font Awesome packages without extra steps.- Shared credentials live in
~/.env; source it (set -a; source ~/.env; set +a) before running remote validation or CI-like scripts so required env vars exist. - For local auth testing, create
workers/api/.dev.varswith the same bindings used in production (D1, R2, BETTER_AUTH_URL, etc.). Wrangler loads these automatically duringnpm run dev:workerand keeps state under.wrangler/state/. - Use
wrangler dev --remotewhen you need Cloudflare's edge runtime (JWT verification with real Better Auth tenant) while retaining hot reload. - Session verification uses the
LOGIN_SERVICEservice binding (points to theloginworker). Always include this binding when cloning/creating new environments; otherwise worker-to-worker requests will time out. - Better Auth now scopes
better-auth.session_tokento/api/*. All browsers must call the Worker’s/apiroutes (or a server-side proxy) to send the cookie—calling out to other origins/paths will never include it. - For local auth, cookies are set on
127.0.0.1; the app now normalizes anylocalhostreturn/login URLs to127.0.0.1so callbacks keep the session. - Placeholder/mock data must never be served on production domains. Keep
ALLOW_PLACEHOLDER_DATAunset in prod and treat any Cloudflare D1 issues as blockers that require migrations or DB fixes rather than falling back to seeded data.
- Requires
APPETIZE_API_KEY(orAPPETTIZE_API_KEY) in~/.env. - Build with EAS profile
simulatorand upload via the helper script if installed:~/.code/skills/ios-appetize-automation/scripts/appetize_build_upload.sh --repo . --name "Starter". - For authenticated sessions, use the login approval-link flow described in
../login/docs/cli-tokens.md.
- Local iOS dev-client auth + screenshot parity notes:
docs/archive/LOCAL_IOS_DEVCLIENT_AUTH_AND_SCREENSHOTS.md.