mirror of
https://github.com/tomru/pfadi-bussle.git
synced 2026-03-04 06:57:12 +01:00
66 lines
3.5 KiB
Markdown
66 lines
3.5 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)
|
|
- `NEXT_PUBLIC_GITHUB_ENABLED` — Set to enable GitHub OAuth login on the client
|
|
- `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 |