diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..fab0cfa --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,89 @@ +# 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