6.5 KiB
CLAUDE.md
Guidance for Claude Code working in this repo. Keep this file lean — per-package details live in each
package's own CLAUDE.md. Detailed prose lives under docs/.
Project
Compass (compassmeet.com) — transparent platform for forming deep, authentic 1-on-1 connections. Yarn-workspaces monorepo: Next.js web, Express API, Capacitor Android shell, shared TS packages. Backed by Supabase (Postgres), Firebase (auth + media), Vercel (web), Google Cloud (API).
Workspaces
| Path | What it is | Read first |
|---|---|---|
web/ |
Next.js + React + Tailwind frontend | web/CLAUDE.md |
backend/api/ |
Express REST + WebSocket server | backend/api/CLAUDE.md |
backend/shared/ |
Backend-only utils (DB, websockets, monitoring) | backend/shared/CLAUDE.md |
backend/email/ |
React-email templates + send helpers | backend/email/CLAUDE.md |
backend/scripts/ |
One-off scripts (migrations, maintenance) | backend/scripts/CLAUDE.md |
backend/supabase/ |
Per-table SQL reference + type-regen makefile | backend/supabase/CLAUDE.md |
common/ |
Types + pure utils shared by web and backend | common/CLAUDE.md |
supabase/ |
Active migrations + local-stack config | supabase/CLAUDE.md |
android/ |
Capacitor WebView wrapper around the web build | android/CLAUDE.md |
Import boundaries (load-bearing)
webandbackend/*import fromcommon/*.commonnever imports fromweborbackend/*.- Anything in
backend/*may import frombackend/shared.backend/sharednever imports from sibling backend packages. - Keep
common's dependency footprint small.
Cross-cutting commands
Run from the repo root. Package manager is yarn (yarn install --frozen-lockfile).
yarn dev # web + API against the shared remote dev DB (visit http://localhost:3000)
yarn dev:isolated # web + API + local Supabase + Firebase emulators (needs Docker, Supabase CLI, Java 21+, Firebase CLI)
yarn lint # ESLint across all packages
yarn lint-fix
yarn typecheck # tsc --noEmit across all packages
yarn prettier
yarn test:coverage
yarn test:e2e # Playwright E2E (spins up services)
yarn test:e2e:dev # Playwright against an already-running dev server
Don't run yarn test (the whole monorepo). It is slow and mostly unrelated to any given change.
Run only the workspaces the change touches, naming specific files where you can — the full suite is
CI's job. The workspace test script already passes --config, so Jest args just append:
yarn --cwd=common test
yarn --cwd=backend/api test path/to/file.unit.test.ts
yarn --cwd=web test -t "renders profile card"
Database:
./scripts/migrate.sh supabase/migrations/<file>.sql # apply a migration to dev
yarn --cwd=backend/api regen-types-dev # rebuild common/src/supabase/schema.ts
Adding an API endpoint (3 files across 2 packages)
- Schema — add entry (method,
authed, Zodprops,returns) incommon/src/api/schema.ts. - Handler —
export const x: APIHandler<'endpoint-name'>inbackend/api/src/<verb>-<resource>.ts. - Register — add to the
handlersmap inbackend/api/src/app.ts(~line 583).
Frontend then calls it via useAPIGetter('endpoint-name', props) (client) or api('endpoint-name', props)
(server-side). Full details in backend/api/CLAUDE.md and
web/CLAUDE.md.
Database access
- Backend:
createSupabaseDirectClient()fromshared/supabase/init— raw SQL via pg-promise. - Frontend:
dbfromweb/lib/supabase/db— Supabase JS client (PostgREST). Web cannot run raw SQL. - Never string-concatenate SQL. Use helpers in
shared/supabase/utils(insert,update,updateData,bulkUpsert, ...) or compose withrenderSql/select/from/wherefromshared/supabase/sql-builder. SQL is lowercase by convention.
Cross-cutting conventions
- Timestamps:
Dateeverywhere in TS,TIMESTAMPTZin Postgres (pg-promise converts). Zod handles Date↔string serialization across the wire. When persistingDateto localStorage, convert string back toDateon load. - Logging:
debug()fromcommon/logger(orlogfromshared/monitoring/logon the backend). Neverconsole.log. - No
sleep()for "eventual consistency" — rely on transactional integrity (seebackend/api/src/create-user-and-profile.ts). - Don't split into multiple API calls when data can be batched in one transaction (e.g. fetch profile options together).
- Lodash (
keyBy,uniq,uniqBy, ...) over hand-rolled loops/Sets. - i18n:
useT()fromweb/lib/locale, thent('key', 'English fallback'). Translation JSON incommon/messages/. Details indocs/internationalization.md. - Scripts that mutate backend state or schema are run by the human, not Claude.
- When editing files, do NOT remove comments or commented-out code.
Docs
Architecture and patterns: docs/knowledge.md,
docs/architecture.md, docs/development.md.
Frontend: docs/next-js.md, docs/react.md,
docs/filters.md.
Database: docs/database-schema.md,
docs/database-connection-pooling.md,
docs/performance-optimization.md.
Cross-cutting: docs/internationalization.md,
docs/profile-fields.md, docs/testing.md,
docs/logging-monitoring.md,
docs/troubleshooting.md.
Mobile: android/README.md, docs/ios.md (iOS plan, not built yet).