5.4 KiB
Contributing
By participating in this project, you agree to abide by our Code of Conduct.
Setup
Prerequisites: Node.js 24+ (managed by Volta)
git clone git@github.com:saltbo/zpan.git
cd zpan
pnpm install
Development
pnpm dev # CF Workers mode with HMR (default, uses staging D1)
pnpm dev:node # Node.js mode with HMR (SQLite, reads .dev.vars)
Quality Gates
Every commit and PR must pass these checks. Husky enforces them on pre-commit.
pnpm lint # Biome — lint + format check
pnpm typecheck # TypeScript strict mode
pnpm test # Unit + integration tests (Node runtime, 90% coverage gate)
pnpm test:cf # Integration tests (Cloudflare Workers runtime)
pnpm e2e # Playwright E2E tests
Adding a Feature
- Write code in the relevant directory (
server/,src/,shared/) - Write tests — co-locate with source as
*.test.ts(Node) or*.cf-test.ts(CF Workers) - Run checks —
pnpm lint && pnpm typecheck && pnpm test && pnpm test:cf - Coverage — new code must maintain 90%+ line coverage on
server/ - Commit — use Conventional Commits (
feat:,fix:,docs:, etc.) - PR — target the
masterbranch - Preview verification — every PR must be verified in the preview environment (see below)
Preview Verification
Every PR that touches UI or API behavior must be verified in the Cloudflare Workers preview environment before merging. The verification report must be posted as a PR comment — a PR without a verification comment cannot be merged.
Cloudflare Workers automatically deploys each PR to a preview URL (posted as a PR comment).
Before merging, the reviewer must verify in the preview environment and post a PR comment with:
- Screenshots proving the feature works (golden path + edge cases)
- What was tested (e.g. "Switched theme to dark, changed language to Chinese, verified password mismatch error")
- Verdict — approve or request changes
A code-review-only approval (reading the diff without visiting the preview) is not sufficient to merge.
Preview environment details
- All PRs share one staging D1 database (
zpan-db-staging) — data persists across deployments - A dev storage backend is pre-configured, so file upload works out of the box
- If you need a clean state, coordinate with maintainers
Staging test account
A shared test account is available on the staging database for preview verification:
| Field | Value |
|---|---|
reviewer@zpan.dev |
|
| Password | zpan-staging-reviewer-2026 |
Use this account for UI regression testing in preview deployments. Do not change the password — other contributors depend on it.
For admin feature testing, read admin credentials from the local .dev.vars file (DEV_ADMIN_PASSWORD). The admin email is admin@zpan.space.
Database Migrations
Schema is defined in server/db/schema.ts and server/db/auth-schema.ts.
pnpm db:generate # Generate migration SQL after schema changes
pnpm db:migrate # Apply migrations (Node/SQLite)
pnpm db:migrate:d1 # Apply migrations (D1 local)
wrangler d1 migrations apply zpan-db --remote # Apply migrations (D1 production)
To reset local databases with seed data (admin user + dev storage):
pnpm db:reset # Reset Node database (zpan.db)
pnpm db:reset:d1 # Reset D1 local database (.wrangler)
Migration files live in migrations/ at project root. Always commit them.
Turso (libSQL) migrate path
When deploying the Node/Docker image against a Turso (libSQL) database, set TURSO_DATABASE_URL (and TURSO_AUTH_TOKEN for remote URLs) before running db:migrate. drizzle.config.ts detects the env var and switches to the turso dialect automatically:
TURSO_DATABASE_URL=libsql://your-db.turso.io \
TURSO_AUTH_TOKEN=your-token \
pnpm db:migrate
For local libSQL files the token can be omitted:
TURSO_DATABASE_URL=file:./zpan.db pnpm db:migrate
Migrations run automatically at Docker container startup when TURSO_DATABASE_URL is set. See docs/deploy/docker.md for the full Docker + Turso setup.
Deployment
Primary target is Cloudflare Workers. Node.js (Docker) is the backup runtime.
pnpm build # Build frontend to dist/
pnpm deploy # Build + deploy to Cloudflare Workers
Project Structure
zpan/
├── server/ # Hono API (routes, middleware, auth, platform abstraction)
├── src/ # React frontend (TanStack Router, shadcn/ui)
├── shared/ # Shared types, Zod schemas, constants
├── workers/ # Cloudflare Workers entry
├── migrations/ # D1/SQLite migrations (drizzle-kit generated, wrangler managed)
├── wrangler.toml # Cloudflare Workers config
└── biome.json # Lint + format config
Financial Contributions
We welcome financial contributions on our Open Collective.
Contributors
Thank you to all the people who have already contributed to ZPan!