# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## About A Next.js booking system for a local scouts van. Users submit booking requests; an admin approves/rejects them. Authentication is restricted to a small allowlist. ## Commands ```bash npm run dev # Start dev server with Turbopack npm run build # Production build npm run lint # ESLint npm test # Run Jest tests npm run test:watch # Jest in watch mode ``` ## Architecture ### Tech Stack - **Next.js** (Pages Router) with TypeScript - **MongoDB/Mongoose** for persistence - **better-auth** for authentication (replaced next-auth) - **Google Calendar API** for syncing bookings - **Tailwind CSS v4** for styling - **MDX** for static content pages (impressum, privacy, terms) ### Authentication Auth is handled by `better-auth` via `lib/auth.ts` (server) and `lib/auth-client.ts` (client). The API route is `pages/api/auth/[...all].ts`. Access is restricted: only a specific `ADMIN_EMAIL` and a hardcoded allowlist of GitHub user IDs (`GITHUB_USERS_GRANTED`) can log in. Protected pages use the `withAuth` HOC (`helpers/withAuth.tsx`), which wraps pages in the `` component that redirects unauthenticated users to GitHub OAuth. ### Data Flow: Bookings 1. `db/booking.ts` — Mongoose model (`IBooking`). Dates stored as `YYYY-MM-DD` strings. The `days` array is auto-computed from `startDate`/`endDate` in a pre-validate hook. On save, a Google Calendar event is created (or deleted on cancel/reject) via the pre-save hook. 2. `db/index.ts` — Database connection and query helpers (`getBookedDays`, `createBooking`, `patchBooking`, etc.). `getBookedDays` merges days from MongoDB and Google Calendar. 3. `lib/googlecalendar.ts` — Google Calendar integration using a service account. Reads env var `GOOGLE_SERVICE_ACCOUNT_KEY_JSON` (JSON string). ### Booking Status Lifecycle `BOOKING_STATUS` enum (in `db/enums.ts`): `requested` → `confirmed` | `rejected` | `canceled` ### Key Environment Variables - `MONGO_URI` — MongoDB connection string - `ADMIN_EMAIL` — Only email allowed to log in - `BETTER_AUTH_SECRET` — Auth secret key - `GITHUB_CLIENT_ID` / `GITHUB_CLIENT_SECRET` — GitHub OAuth app (optional) - `SMTP_USER` / `SMTP_PASS` / `FROM_EMAIL` — Email via wirtanen.uberspace.de:465 - `GOOGLE_CALENDAR_ID` — Calendar to sync bookings into - `GOOGLE_SERVICE_ACCOUNT_KEY_JSON` — Service account credentials (JSON string) ### Date Handling Frontend dates use `dd.MM.yyyy`; backend/DB uses `yyyy-MM-dd`. Helpers in `helpers/date.ts` (`dateFormatFrontend`, `dateFormatBackend`, `dateParseFrontend`, `dateParseBackend`). Timezone-aware "now" uses `nowInTz()` defaulting to `Europe/Berlin`. ### Page Structure - `/` — Public landing page with calendar showing booked days - `/book` — Multi-step booking form (context in `context/book.tsx`) - `/bookings/[uuid]` — Public booking confirmation/details page - `/admin` — Admin dashboard (auth-protected via `withAuth`) - `/admin/bookings/[uuid]` — Admin booking management - `/prices`, `/impressum`, `/privacy`, `/terms` — Static/MDX pages ### API Routes - `POST /api/bookings` — Create booking - `GET/PATCH /api/bookings/[uuid]` — Get or update booking - `GET /api/daysbooked` — Returns booked days array (JSON) - `GET /api/daysbooked.ics` — Returns booked days as iCal feed - `/api/auth/[...all]` — better-auth handler