Guides

Development Setup

Dev environment options, commands, environment variables, CI, git hooks, and the API key vault.

Collection of info about the codebase environment, setup and design choices. For the first-run walkthrough (dev container vs. local setup, seeding), see Getting Started - this page assumes you're already up and running and covers the commands, CI, and env vars you'll come back to as you keep working.

Commands

CommandDescription
pnpm devStart the dev server with hot reload
pnpm buildProduction build
pnpm startStart the production server (requires a prior build)
pnpm lintRun ESLint
pnpm formatAuto-format all files with Prettier
pnpm format:checkCheck formatting without writing (used in CI)
pnpm db:generateGenerate migrations from schema changes
pnpm db:migrateApply all pending migrations
pnpm db:seedSeed the 6 teams + a seed account (idempotent)
pnpm db:resetDrop and recreate the local database (blocked in production)
pnpm db:studioOpen Drizzle Studio - visual database browser (dev only)
pnpm testRun the unit test suite once
pnpm test:watchRe-run tests on save (use while developing)
pnpm test:uiOpen the Vitest browser UI
pnpm test:coverageGenerate a coverage report

CI & Git Hooks

Every push and PR runs ESLint, Prettier, a TypeScript check, and the Vitest suite in GitHub Actions, and every commit runs lint-staged + commitlint locally via Husky - see Code Quality Tooling for the full breakdown of what each workflow and hook does. Run pnpm check before pushing to catch what CI would catch without waiting on it.

Environment Variables

VariableRequiredDescription
BETTER_AUTH_SECRETYesSession signing secret - openssl rand -hex 32
VAULT_ENCRYPTION_KEYProd onlyAES-256 key for vault secrets - openssl rand -hex 32
NEXT_PUBLIC_APP_URLNoPublic origin, e.g. http://localhost:3000
BETTER_AUTH_URLNoSame as NEXT_PUBLIC_APP_URL
BETTER_AUTH_TRUSTED_ORIGINSNoExtra origins allowed to make auth requests (needed when accessing the dev server from a second machine on the LAN)
DATABASE_PATHNoPath to the SQLite file (default: ./db/dashboard.db)
RESEND_API_KEYNoResend API key for transactional email
EMAIL_FROMNoSender address, e.g. TrickFire Robotics <[email protected]>
MINECRAFT_SERVER_HOSTNoMinecraft server hostname/IP (default: localhost)
MINECRAFT_SERVER_PORTNoMinecraft query port (default: 25565)
MINECRAFT_SERVER_PATHNoAbsolute path to the Minecraft server directory
MINECRAFT_WORLD_PATHNoAbsolute path to the world directory (for the playtime leaderboard)
MINECRAFT_RCON_PORTNoRCON port (default: 25575)
MINECRAFT_RCON_PASSWORDNoRCON password
MINECRAFT_BOT_SKIN_URLNoSkin URL applied to players detected as Carpet bots (real bot names come from the bots scoreboard team via RCON - see External Integrations)
PL3XMAP_URLNoInternal URL of the Pl3xMap web server, e.g. http://localhost:8080
TAILSCALE_API_KEYNoTailscale API key (admin console → Settings → Keys)
TAILSCALE_TAILNETNoTailnet name, or - to auto-detect from the API key
ONSHAPE_BASE_URLNoOnShape API base URL
ONSHAPE_ACCESS_KEYNoOnShape access key
ONSHAPE_SECRET_KEYNoOnShape secret key
ONSHAPE_COMPANY_IDNoOnShape company ID (auto-detected from the access key if omitted)
SIM_CACHE_DIRNoDirectory the simulation export proxy caches generated archives in (default: /var/cache/trickfire-sim)
SIM_CACHE_MAX_ENTRIESNoMax cached export archives before the oldest are evicted (default: 50)
SIM_CACHE_TTL_DAYSNoDays before a cached export archive expires (default: 7)
SEED_ADMIN_EMAILNoEmail for the seeded account
SEED_ADMIN_PASSWORDNoPassword for the seeded account
SEED_ADMIN_NAMENoDisplay name for the seeded account
GITHUB_ORGNoGitHub organization name (e.g. trickfirerobotics) - enables the GitHub tab on the Members page
GITHUB_TOKENNoFine-grained PAT with Organization → Members: Read and write permission

Danger

Never commit .env.local or .env.production. BETTER_AUTH_SECRET lets anyone forge session tokens - if it leaks, rotate it immediately by changing the value and restarting the server (all existing sessions are invalidated). Rotating or losing VAULT_ENCRYPTION_KEY makes every existing vault entry permanently unrecoverable - back it up.

API Key Vault

The API Keys page is a shared credential vault to store third-party API keys and service logins. Any logged-in member can open the page and see what entries exist - reading a specific secret is the gated part, via a per-person grant set from that entry's Manage access action. There's no global "vault access" toggle and no bypass for any particular user.

Each entry is either a login (username + password, revealed in the browser on demand) or an api_key (never shown in the UI - retrieved only via the API endpoint below).

Fetching an API key - GET /api/vault/{id}/key

Authenticated by the caller's dashboard session cookie. Returns the key only if the user has been granted access to that entry.

StatusMeaning
200{ "name": "Resend", "key": "re_live_..." }
401Not logged in
403Logged in but no access grant for this entry
404Entry doesn't exist, or it is a login (use GET /api/vault/{id}/reveal instead)
Terminal
$ curl -s https://dashboard.trickfirerobotics.com/api/vault/12/key \
  -H "Cookie: better-auth.session_token=<your-session-cookie>"

Secrets are encrypted at rest with AES-256-GCM using VAULT_ENCRYPTION_KEY. In local dev, if that variable is unset, a key is auto-generated and saved to db/vault.key (gitignored).

On this page