- Use Node >=24.14 (see
.nvmrc), pnpm 10, and Turborepo for workspace orchestration. - The
apps/mapdirectory contains the Next.js 15 map UI (port 3000). - Shared code is organized in
packages/:api(tRPC routers),auth(auth helpers),db(Drizzle schema/migrations),ui(shared components),validators(Zod schemas), andshared(utilities). - Configuration files are in
tooling/; pnpm patches go inpatches/; Turbo generators live inturbo/.
- Install dependencies with
pnpm install. You can scope installations with--filter <workspace>. - Start development:
pnpm dev --filter f3-nation-mapfor the map app, orpnpm devto run all watch tasks. - Ensure a populated root
.envfile is present for any scripts relying onwith-env. - Build with
pnpm build(orpnpm build --filter apps/map), and start production withpnpm -C apps/map start. - Code quality: always run
pnpm lint(orpnpm lint --filter apps/map) andpnpm format:fixto ensure your code passes all lint and formatting checks. Also runpnpm typecheckto validate types. - Testing:
- Run all tests with
pnpm test(via the Turbo pipeline). - Run targeted tests:
pnpm -C apps/map test,pnpm -C apps/map test:e2e. - Database helpers:
pnpm db:pull,pnpm db:push, andpnpm reset-test-db.
- Run all tests with
- Use Prettier (
@acme/prettier-config) and ESLint (@acme/eslint-configbase/next/react) as the source of truth. - Always autofix issues with
pnpm lint:fixand confirm changes withpnpm lintandpnpm formatbefore committing. - Code should use two-space indentation by default.
- Prioritize TypeScript; use
.ts/.tsxwith explicit typings. - Name React components in PascalCase, prefix hooks with
use, and use kebab-case for files/directories (e.g.,apps/map/src). - Co-locate feature-specific assets and tests near their sources (e.g.,
apps/map/src/app/(feature)/).
- Use Vitest for unit and integration tests; name test files
*.test.ts[x]and place under or near source code or in__tests__. - Use Playwright for e2e in
apps/map; generate reports viapnpm -C apps/map test:e2e:report. - Reset databases before any suite that mutates data (
pnpm reset-test-dborpnpm -C packages/db reset-test-db). - Prefer fixtures in
apps/map/testsorpackages/*/__mocks__instead of live service calls.
This repo enforces Conventional Commits via commitlint + Lefthook. Every commit message must follow:
<type>(<scope>): <subject>
Scope is required. The Lefthook commit-msg hook will reject commits that omit it or use an unrecognized scope.
Use standard Conventional Commit types: feat, fix, chore, docs, style, refactor, perf, test, build, ci, revert.
Scopes are defined in commitlint.config.mjs and map to monorepo packages:
| Category | Scopes |
|---|---|
| Apps | map |
| Apps & Packages | api, auth (exist in both apps/ and packages/) |
| Packages | db, env, mail, shared, sso, ui, validators |
| Tooling | eslint, prettier, tsconfig, scripts, github, tailwind |
| Cross-cutting | deps, ci, repo, release |
Choosing a scope:
- Use the app or package the change primarily affects (e.g.,
fix(db): correct migration) - For dependency updates:
chore(deps): bump next to 15.1 - For CI/GitHub Actions:
ci(ci): add deploy workflow - For root config, monorepo tooling, or multi-package changes:
chore(repo): update turbo pipeline - For release-related changes:
chore(release): v3.10.0
When adding a new workspace, add its scope to the array in commitlint.config.mjs.
feat(map): add workout detail modal
fix(auth): handle expired refresh tokens
chore(deps): bump drizzle-orm to 0.35
refactor(api): extract pagination into shared helper
test(validators): add edge cases for date parsing
docs(repo): update AGENTS.md with commit conventions
ci(ci): add preview deploy for map app
chore(repo): configure turborepo remote caching
- Every pull request should:
- Include a clear summary, any related issue(s), commands run, and impact to DB/env.
- Add screenshots or screen recordings for UI changes in
apps/map. - Highlight any new migrations or environment variables.
- Never include secrets; share them using Slack or Doppler scripts, not via git.
- Before opening a pull request, ensure both
pnpm lintandpnpm formatpass with no errors or changes required.
- Store all secrets in a root
.envfile. Always usewith-envhelpers to load environment variables and never commit.envfiles to the repo. - Scope Sentry/analytics keys per environment and rotate if leaked. Run production DB changes only through scripts in
packages/db.