albertonline.org docs

Local development

Prerequisites, install, environment, database, running apps, and testing the albertonline.org monorepo locally.

Prerequisites

  • Node.js 20+
  • pnpm 11+ (the repo pins pnpm@11.5.2 via packageManager)
  • PostgreSQL — for any database-backed feature

pnpm lint type-strips the TypeScript oxlint plugin at import time, which is on-by-default only in Node ≥ 22.18. On older Node the lint step fails with Unknown file extension ".ts". Use a recent Node 22 for the full gate.

Install

pnpm install

Create env files from the examples, then set at least DATABASE_URL:

cp apps/web/.env.example apps/web/.env
cp apps/native/.env.example apps/native/.env
# if you use them locally:
cp packages/cms/.env.example packages/cms/.env
cp packages/internationalization/.env.example packages/internationalization/.env

@repo/analytics validates its env with no skipValidation, so NEXT_PUBLIC_POSTHOG_KEY and NEXT_PUBLIC_POSTHOG_HOST must be set (dev placeholders are fine) or every page 500s. SUPABASE_JWT_SECRET is also required. SKIP_ENV_VALIDATION=1 bypasses the app-level schemas but not the analytics one.

Database

pnpm db:push       # push schema directly (dev)
pnpm db:studio     # open Drizzle Studio
pnpm db:generate   # generate a migration from schema changes
pnpm db:migrate    # apply migrations

Schema lives in packages/db/src/schema/; RLS policies in packages/db/src/rls.ts. All DB commands run from the repo root and target @repo/db.

Running apps

pnpm dev           # every app, via Turbo (kills known dev ports first)
pnpm dev:web       # web only
pnpm dev:native    # the Expo app
pnpm -F <pkg> dev  # any single app by its package name

pnpm dev runs scripts/kill-dev-ports.mjs first, so a stale process on a dev port won't block startup.

Dev against the prod Supabase pooler

pnpm dev:web:local-prod boots the web app on :3001 against the prod Supavisor pooler (DATABASE_URL from the git-ignored apps/web/.env.local) while overriding the auth origins so a localhost browser is accepted (BETTER_AUTH_URL / CORS_ORIGIN / NEXT_PUBLIC_URLhttp://localhost:3001, plus AUTH_DISABLE_POLAR_CUSTOMER_CREATE=true). The script scripts/dev-web-local-prod.mjs bundles these — don't assemble them by hand, and never point dev at the dead direct host db.<ref>.supabase.co.

Dev ports

PortApp
3000it-f-store / portal
3001web
3002juicy-shop
3003remotion
3004blog
3005market-web
3009docs (this site)
3010cvm
3030lila-server
3031lila-web
3032cvm-server
6006storybook
8081native (Expo)

Testing

Vitest is the test runner (node + browser modes). Naming:

  • Unit*.unit.test.ts / *.unit.spec.ts (node)
  • Component*.test.tsx / *.spec.tsx (browser, Playwright chromium)
  • E2Etests/e2e/*.e2e.test.ts
  • Visual*.visual.test.ts
pnpm test                       # affected suites, via Turbo
pnpm -F <pkg> exec vitest run   # one package
pnpm -F <pkg> exec vitest run --coverage

New or changed production code must keep SonarQube "Coverage on New Code" at ≥ 80% — write the tests in the same change (test-first), covering the error / guard branches, not just the happy path.

Before you push

Run the same gate CI runs — see CI/CD. In short:

pnpm ci:precheck   # lint + types + format + boundaries + doc-versions + fallow

The Husky pre-push hook runs ci:precheck plus tests and an affected build. Never bypass it with --no-verify.

On this page