diff --git a/CLAUDE.md b/CLAUDE.md index 373c9af..9de1835 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -9,16 +9,17 @@ Meme Studio is a homophone pun game operation platform built with Next.js 14 (Ap ## Commands ```bash -npm run dev # Start development server -npm run build # Production build -npm run lint # Run ESLint +pnpm run dev # Start development server (port 3001) +pnpm run build # Production build +pnpm run deploy # Build and deploy to production server (./deploy.sh) +pnpm run lint # Run ESLint # Database (Prisma + MySQL) -npm run db:generate # Generate Prisma client -npm run db:push # Push schema changes (dev) -npm run db:migrate # Create migration -npm run db:studio # Open Prisma Studio -npm run db:seed # Create/update admin user +pnpm run db:generate # Generate Prisma client +pnpm run db:push # Push schema changes (dev) +pnpm run db:migrate # Create migration +pnpm run db:studio # Open Prisma Studio +pnpm run db:seed # Create/update admin user ``` ## Architecture @@ -52,13 +53,37 @@ npm run db:seed # Create/update admin user - `Level` - Game levels with image, answer, hints, sortOrder - `User`, `Session`, `Account`, `Verification` - Better Auth models +### basePath & Reverse Proxy + +The app is deployed behind a reverse proxy at `/studio` path: +- `next.config.js` sets `basePath: '/studio'` +- All pages and API routes are served under `/studio/...` + +**Critical gotchas**: +- **Next.js strips basePath from `request.url` in route handlers** — Better Auth's `basePath` must be `/api/auth` (without `/studio`), not `/studio/api/auth` +- **`BETTER_AUTH_URL` must NOT contain a path** (just the origin like `http://localhost:3001`) — Better Auth's `withPath()` silently ignores the `basePath` config if the URL already has a path component +- **HTTPS production adds `__Secure-` cookie prefix** — middleware must check both `better-auth.session_token` and `__Secure-better-auth.session_token` +- **`router.push()` auto-prepends basePath** — never manually add `/studio` to paths used in client-side navigation or callbackUrl params +- **`request.nextUrl.pathname` in middleware excludes basePath** — e.g., `/levels` not `/studio/levels` +- Prisma requires `binaryTargets = ["native", "rhel-openssl-3.0.x"]` for cross-platform deployment (macOS dev → Linux server) + +### Deployment + +- **Server**: `root@119.91.211.52` at `/root/apps/meme-studio` +- **Process Manager**: PM2 (`ecosystem.config.js`) +- **Script**: `./deploy.sh` — builds locally, rsyncs files (excluding node_modules), installs deps on server, restarts PM2 +- **Standalone output**: `next.config.js` sets `output: 'standalone'` +- Server uses `npm install --production` + `npx prisma generate` (prisma is a devDependency) + ### Environment Variables Required in `.env`: ``` DATABASE_URL=mysql://... BETTER_AUTH_SECRET= # 32+ chars, generate with: openssl rand -base64 32 -BETTER_AUTH_URL=http://localhost:3000 +BETTER_AUTH_URL= # Origin only, NO path (e.g., http://localhost:3001) +NEXT_PUBLIC_APP_URL= # Same as BETTER_AUTH_URL +NEXT_PUBLIC_BASE_PATH= # /studio ADMIN_EMAIL= ADMIN_PASSWORD= COS_SECRET_ID= # Tencent Cloud COS