97 lines
4.6 KiB
Markdown
97 lines
4.6 KiB
Markdown
# 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 <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
|