CLAUDE.md for fernhill-web
This is the file an AI coding agent reads before it touches Fernhill's code. Keep it accurate: a stale instruction costs an agent a wrong turn every single session.
Project overview
Fernhill is a booking platform for independent physiotherapy clinics. fernhill-web is the clinic dashboard: schedules, patient notes and invoices. It exists so a three-person clinic can run its week from one screen without a receptionist.
Commands
| Task | Command |
|---|---|
| Install dependencies | pnpm install |
| Run the dev server | pnpm dev (http://localhost:5173, uses the mock API) |
| Run the full test suite | pnpm test |
| Run one test file | pnpm test -- src/features/schedule/slots.test.ts |
| Type check | pnpm typecheck |
| Lint | pnpm lint |
| Build for production | pnpm build |
| End-to-end tests | pnpm e2e (needs pnpm dev running) |
Architecture map
src/
app/ router, auth guard, query client setup
features/ schedule, patients, invoices, settings: each with api.ts, use*.ts hooks, views
shared/ ui/ primitives, http/client.ts (the only fetch), date/ helpers
mocks/ MSW handlers used by dev and tests
Views never call fetch or import an api.ts directly: data flows view to hook to api.ts to shared/http/client.ts. A feature may use another feature's hooks, never its api.ts. All dates are stored in UTC and formatted only in shared/date/format.ts, because clinics span time zones.
Conventions
- Naming: components in PascalCase files, hooks start with
use, tests sit beside the file as*.test.ts. - State: server state lives in TanStack Query; UI state in component state or a feature's Zustand store. Never copy server data into Zustand.
- Errors: API errors surface through
useToastError(); neveralert()or a bareconsole.error. - Tests: every new hook gets a test against the MSW mocks; every new view gets at least one render test.
Do
- Read the surrounding code before writing new code, and match its existing patterns.
- Write or update a test alongside every behavior change.
- Keep commits small and each one buildable on its own.
- Add an MSW handler in
src/mocks/for any new endpoint you call. - Ask when a requirement is ambiguous rather than guessing at intent.
Don't
- Don't invent a new pattern when an existing one already solves the problem.
- Don't touch unrelated files in the same change, even to fix something adjacent.
- Don't skip the test suite before claiming a change works.
- Don't log or render patient notes in error messages; they are health data.
- Don't commit secrets,
.envfiles or generated build output.
Review checklist
Escalation
Stop and ask a human before: changing anything in src/features/patients/notes/ (health data rules apply), editing database migrations in the API repo, deleting files, or changing the auth guard. If a test fails for a reason you cannot explain in one sentence, report it rather than editing the test to pass.