Skip to content

Contributing to ClinicFlow

  • Node.js 22+
  • npm
  • A Supabase project (or access to the shared dev project)
  • Redis (local via Docker, Railway plugin, or hosted provider)

See Local Development for setup instructions.


Branch Purpose Base
main Production. Auto-deploys to Railway. Never commit directly.
dev Optional staging for pre-prod validation before merge. main
feat/<name> New features. PR into main. main
fix/<name> Bug fixes. PR into main. main
chore/<name> Maintenance, no behaviour change. PR into main. main
docs/<name> Documentation-only changes. PR into main. main

Rules:

  • Branch from main, not dev.
  • Delete branch after PR merges.
  • Annotated tags mark releases: git tag -a vX.Y.Z -m "..." then git push origin vX.Y.Z.

Conventional Commits format:

feat(chatbot): add FAQ keyword matching fallback
fix(auth): handle expired JWT on /me endpoint
chore(deps): bump @anthropic-ai/sdk to 0.101.0
docs(api): document PATCH /users/me endpoint
test(whatsapp): add concurrency lock test cases

Subject line: max 72 chars, imperative mood, no period.
Body (optional): explain why, not what.


  • Tests pass: cd backend && npm test (458 tests, ~22s)
  • TypeScript valid: cd backend && npm run typecheck + cd frontend && npm run typecheck
  • Lint clean: cd frontend && npm run lint → 0 errors
  • No console.log left in production code (use logger.* from src/utils/logger.js)
  • No secrets or credentials in committed files
## What
One-sentence summary of the change.
## Why
Why this change is needed.
## Test plan
- [ ] Manual step 1
- [ ] Manual step 2

Review SLA: 2 business days. Tag @ErnestNuma for urgent reviews.


  • Runtime: Node.js 22+, ES modules (import/export). Runs .ts files via Node native type-stripping (Node ≥22.18).
  • TypeScript: Incremental migration in progress (allowJs during transition). New files should use .ts when touching migrated areas; .js is still accepted.
  • Type-check: Always run tsc --noEmit (both backend and frontend).
  • Error handling: try/catch in route handlers, always return JSON { error: "..." }.
  • Logging: Use logger.info/error/warn from src/utils/logger.js — never console.log.
  • Multi-tenancy: Every DB query must filter by req.user.clinicId — no exceptions.
  • Secrets: Never log, never return in responses. Mask tokens with ...****.
  • Styling: Tailwind CSS is preferred for new components. Brand green #059669 is the brand token in tailwind.config.js. Inline styles being migrated; match existing patterns when touching legacy code.
  • Fonts: DM Sans for body, Bricolage Grotesque for headings/display.
  • Icons: lucide-react — don’t add other icon libraries.
  • State: TanStack Query for server state, useState/useContext for UI state.
  • No new dependencies without discussion — keep the bundle lean.
  • Match surrounding code style even if you’d do it differently.
  • Don’t “improve” adjacent code that isn’t broken — surgical changes only.
  • Remove imports/variables made unused by your changes.

Terminal window
cd backend
npm test # run once (458 tests)
npm run test:watch # watch mode
npm run test:cover # with coverage

Test files live in src/__tests__/. New backend features should have tests. Match the existing pattern in __tests__/helpers/testDb.js for DB setup.

Terminal window
cd frontend
npm test

Schema changes go through Supabase migrations:

  1. Edit backend/src/db/schema.sql
  2. Apply locally: npm run migrate
  3. Document the change in Database Schema

Never hardcode values that belong in environment variables. Add new vars to:

  1. backend/.env.example (with placeholder value)
  2. frontend/.env.example (VITE_-prefixed)
  3. Environment Variables doc

Open a GitHub issue or reach out at ernest@clinicflow.lat.