# Local Development ## Prerequisites - Node.js 20+ - [pnpm](https://pnpm.io/) - A DataForSEO account/API credentials ## Local Development Workflow ```sh pnpm install # Run once per fresh local DB pnpm run db:migrate:local ``` Configure `.env.local`: 1. `cp .env.example .env.local` 2. Add `DATAFORSEO_API_KEY` as a base64-encoded `login:password` value: `printf '%s' 'YOUR_LOGIN:YOUR_PASSWORD' | base64` Run locally: ```sh # Option 1 pnpm run dev # Option 2 (Recommended) # This log file makes it easier for your coding agent to debug. mkdir .logs touch .logs/dev-server.log # This command uses portless, which is great for worktrees. It also pipes logs to that fixed file, which is helpful for agent debugging output. pnpm dev:agents ``` `pnpm dev:agents` runs through [portless](https://github.com/vercel-labs/portless) at `http://open-seo.localhost:1355` by default. When using a git worktree, [portless](https://github.com/vercel-labs/portless) prefixes the branch name, for example `http://feature-name.open-seo.localhost:1355`. ## Database Commands Generate migration: ```sh pnpm run db:generate ``` Migrate local DB: ```sh pnpm run db:migrate:local ``` ## Auth Modes - `AUTH_MODE=cloudflare_access` (default): validates Cloudflare Access JWTs (`cf-access-jwt-assertion`) using `TEAM_DOMAIN` + `POLICY_AUD`. - `AUTH_MODE=local_noauth`: local trusted mode, no auth check, injects `admin@localhost`. - `AUTH_MODE=hosted`: Better Auth-backed email/password mode. Requires Better Auth schema generation plus `BETTER_AUTH_SECRET` and `BETTER_AUTH_URL`. Local scripts (`pnpm dev` and `pnpm dev:agents`) set `AUTH_MODE=local_noauth` automatically. Use `AUTH_MODE=cloudflare_access pnpm dev` when you specifically want to test Access validation locally. For Cloudflare deployments, ensure Cloudflare Access is enabled on your Worker route/domain and provide `TEAM_DOMAIN` + `POLICY_AUD` in environment variables.