6.2 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 # Jest unit + integration across all workspaces
yarn test:coverage
yarn test:e2e # Playwright E2E (spins up services)
yarn test:e2e:dev # Playwright against an already-running dev server
Single workspace / single test (the workspace test script already passes --config, so append Jest args):
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.