3.4 KiB
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
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 <Auth> component that redirects unauthenticated users to GitHub OAuth.
Data Flow: Bookings
db/booking.ts— Mongoose model (IBooking). Dates stored asYYYY-MM-DDstrings. Thedaysarray is auto-computed fromstartDate/endDatein a pre-validate hook. On save, a Google Calendar event is created (or deleted on cancel/reject) via the pre-save hook.db/index.ts— Database connection and query helpers (getBookedDays,createBooking,patchBooking, etc.).getBookedDaysmerges days from MongoDB and Google Calendar.lib/googlecalendar.ts— Google Calendar integration using a service account. Reads env varGOOGLE_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 stringADMIN_EMAIL— Only email allowed to log inBETTER_AUTH_SECRET— Auth secret keyGITHUB_CLIENT_ID/GITHUB_CLIENT_SECRET— GitHub OAuth app (optional)SMTP_USER/SMTP_PASS/FROM_EMAIL— Email via wirtanen.uberspace.de:465GOOGLE_CALENDAR_ID— Calendar to sync bookings intoGOOGLE_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 incontext/book.tsx)/bookings/[uuid]— Public booking confirmation/details page/admin— Admin dashboard (auth-protected viawithAuth)/admin/bookings/[uuid]— Admin booking management/prices,/impressum,/privacy,/terms— Static/MDX pages
API Routes
POST /api/bookings— Create bookingGET/PATCH /api/bookings/[uuid]— Get or update bookingGET /api/daysbooked— Returns booked days array (JSON)GET /api/daysbooked.ics— Returns booked days as iCal feed/api/auth/[...all]— better-auth handler