Files
pfadi-bussle/CLAUDE.md

65 lines
3.4 KiB
Markdown

# 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 `<Auth>` 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