# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Commands ```bash # Development pnpm dev # Start dev server (http://localhost:3000) pnpm build # Production build (standalone output) pnpm lint # Run ESLint # Database (use pnpm instead of npx) pnpm prisma migrate dev --name # Create and apply migration pnpm prisma generate # Regenerate Prisma client pnpm prisma studio # Open DB GUI ``` ## Stack - **Next.js 16** (App Router, standalone output) - **SQLite + Prisma 7** via `@prisma/adapter-better-sqlite3` (not the default SQLite adapter) - **NextAuth.js v5** (beta.30) — JWT sessions, Credentials provider only - **Tailwind CSS v4** — CSS Variables theming in `src/app/globals.css` - **Drag & Drop** — `@dnd-kit` and `@hello-pangea/dnd` (both present) - **pnpm** — package manager (use pnpm, not npm/yarn) ## Architecture Overview ### Workshop Types There are 5 workshop types: `swot` (sessions), `motivators`, `year-review`, `weekly-checkin`, `weather`. **Single source of truth**: `src/lib/workshops.ts` exports `WORKSHOPS`, `WORKSHOP_BY_ID`, and helpers. Every place that lists or routes workshop types must use this file. **All types and UI config constants** are in `src/lib/types.ts` (e.g. `MOTIVATORS_CONFIG`, `YEAR_REVIEW_SECTIONS`, `SWOT_QUADRANTS`, `EMOTIONS_CONFIG`). ### Layer Structure ``` src/ ├── actions/ # Next.js Server Actions ('use server') — call services, revalidate paths ├── services/ # Prisma queries + business logic (server-only) │ ├── database.ts # Prisma singleton (global for dev HMR) │ ├── session-permissions.ts # Shared permission factories │ └── session-share-events.ts # Shared share + SSE event handlers ├── app/ │ ├── api/ # Route handlers (SSE subscribe + auth) │ ├── (auth)/ # Login/register pages │ └── [workshop]/ # One folder per workshop type ├── components/ │ └── collaboration/ # BaseSessionLiveWrapper + share/live UI ├── hooks/ │ └── useLive.ts # SSE client hook (EventSource + reconnect) └── lib/ ├── workshops.ts # Workshop metadata registry ├── types.ts # All TypeScript types + UI config └── share-utils.ts # Shared share types ``` ### Real-Time Collaboration (SSE) Each workshop has `/api/[path]/[id]/subscribe` — a GET route that opens a `ReadableStream` (SSE). The server polls the DB every 1 second for new events and pushes them to connected clients. Server Actions write events to the DB after mutations. Client side: `useLive` hook (`src/hooks/useLive.ts`) connects to the subscribe endpoint with `EventSource`, filters out events from the current user (to avoid duplicates), and calls `router.refresh()` on incoming events. `BaseSessionLiveWrapper` (`src/components/collaboration/`) is the shared wrapper component that wires `useLive`, `CollaborationToolbar`, and `ShareModal` for all workshop session pages. ### Shared Permission System `createSessionPermissionChecks(model)` in `src/services/session-permissions.ts` returns `canAccess`, `canEdit`, `canDelete` for any Prisma model that follows the session shape (has `userId` + `shares` relation). Team admins have implicit access to their members' sessions. `createShareAndEventHandlers(...)` in `src/services/session-share-events.ts` returns `share`, `removeShare`, `getShares`, `createEvent`, `getEvents` — used by all workshop services. ### Auth - `src/lib/auth.ts` — NextAuth config (signIn, signOut, auth exports) - `src/lib/auth.config.ts` — config object (used separately for Edge middleware) - `src/middleware.ts` — protects all routes except `/api/auth`, `_next/static`, `_next/image`, `favicon.ico` - Session user ID is available via `auth()` call server-side; token includes `id` field ### Database Prisma client is a singleton in `src/services/database.ts`. `DATABASE_URL` env var controls the SQLite file path (default: `file:./prisma/dev.db`). Schema is at `prisma/schema.prisma`. ### Adding a New Workshop Pattern followed by all existing workshops: 1. Add entry to `WORKSHOPS` in `src/lib/workshops.ts` 2. Add Prisma models (Session, Item, Share, Event) following the existing pattern 3. Create service in `src/services/` using `createSessionPermissionChecks` and `createShareAndEventHandlers` 4. Create server actions in `src/actions/` 5. Create API route `src/app/api/[path]/[id]/subscribe/route.ts` (copy from existing) 6. Create pages under `src/app/[path]/` 7. Use `BaseSessionLiveWrapper` for the session live page