Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

Development Workflow

Environments

EnvironmentURLDatabasePurpose
Localhttp://localhost:8787Local D1Development
QAhttps://qa.aero2.devaero2-qaStaging & E2E tests
Productionhttps://aero2.devaero2Live

Local Development

# Install dependencies
npm install
 
# Start local dev server
npm run dev
 
# Run unit tests
npm test
 
# Run linting
npm run lint

Local development uses a local D1 database. Changes are isolated to your machine.

Pull Request Workflow

When you push a branch and open a PR against main, CI runs automatically:

  • Lint — Biome linting
  • Build — Compile and bundle
  • Unit Tests — Vitest against local D1
  • Migration Separation — Fails if PR mixes code and migration files

No deployment happens on PRs. Code is reviewed and merged to main.

Deployment Pipeline

When a PR is merged to main:

  1. Build & Test — Lint, build, unit tests
  2. Deploy to QA — Deploys to https://qa.aero2.dev
  3. E2E & API Tests — Playwright tests against live QA
  4. Deploy to Production — Deploys to https://aero2.dev
  5. Health Check — Verifies production, auto-rollback on failure

Database Migrations

Migrations are manual and follow the expand-contract pattern.

Creating a Migration

touch migrations/0002_your_migration_name.sql

Safe Migration Process

  1. PR 1: Code that works with OLD and NEW schema — merge & deploy
  2. PR 2: Migration files ONLY — merge (triggers CI but no auto-apply)
  3. Apply migrations manually:
# Apply to QA first
npm run migrate:qa
 
# Verify on QA, then apply to production
npm run migrate:prod

Migration Rules

Safe migrations (can apply anytime):

  • ALTER TABLE ... ADD COLUMN
  • CREATE TABLE
  • CREATE INDEX

Dangerous migrations (use expand-contract):

  • ALTER TABLE ... DROP COLUMN
  • ALTER TABLE ... RENAME COLUMN
  • Changing column types

NPM Scripts Reference

ScriptDescription
npm run devStart local development server
npm run buildBuild for production
npm run lintRun Biome linter
npm testRun unit tests
npm run test:e2eRun Playwright E2E tests
npm run test:apiRun API tests
npm run deploy:qaDeploy to QA (use CI instead)
npm run deploy:prodDeploy to Production (use CI instead)
npm run migrate:qaApply migrations to QA database
npm run migrate:prodApply migrations to Production database

Secrets Management

Cloudflare Secrets (per environment)

# QA
wrangler secret put SECRET_NAME --env qa
 
# Production
wrangler secret put SECRET_NAME --env production

Required secrets:

  • MASTER_KEY — Encryption key
  • GITHUB_CLIENT_ID — GitHub OAuth app ID
  • GITHUB_CLIENT_SECRET — GitHub OAuth app secret
  • BOOTSTRAP_ADMIN_EMAIL — Initial admin user email

GitHub Secrets (for CI/CD)

Set in GitHub repo → Settings → Secrets:

  • CF_API_TOKEN — Cloudflare API token
  • CF_ACCOUNT_ID — Cloudflare account ID
  • D1_QA_DATABASE_ID — QA database UUID
  • D1_PROD_DATABASE_ID — Production database UUID

Troubleshooting

CI/CD Failures

# View recent workflow runs
gh run list
 
# View logs for a specific run
gh run view <run-id> --log-failed

Check Environment Health

curl https://qa.aero2.dev/health
curl https://aero2.dev/health

View Live Logs

npx wrangler tail --env qa
npx wrangler tail --env production

Quick Reference

ActionCommand/Process
Start codingnpm run dev
Run tests locallynpm test
Open PRPush branch, CI runs automatically
DeployMerge to main (automatic)
Apply migrationnpm run migrate:qa then npm run migrate:prod
Rollback productionnpx wrangler rollback --env production
Add secretwrangler secret put NAME --env ENV