7.8 KiB
7.8 KiB
MemeStudio - Quick Reference Guide
🏗️ ARCHITECTURE AT A GLANCE
┌─────────────────────────────────────────────────────────┐
│ Next.js 14 (App Router) │
│ With basePath=/studio │
└──────────────┬──────────────────────────────────────────┘
│
┌─────────┴─────────┐
│ │
┌────▼────┐ ┌──────▼─────┐
│ Frontend │ │ API Routes │
│ Pages │ │ (Protected)│
│ & UX │ └──────┬─────┘
└────┬────┘ │
│ ┌──────┴─────────────────┐
│ │ Better Auth (7-day) │
│ └──────┬─────────────────┘
│ │
└───────────┬───────┘
│
┌────────▼────────┐
│ MySQL via │
│ Prisma ORM │
│ (7 models) │
└─────────────────┘
📊 DATABASE MODELS (7)
| Model | Purpose | Key Fields |
|---|---|---|
| Level | Game levels | id, imageUrl, answer, hint1-3, sortOrder |
| User | Admin users | id, email, name, password (in Account) |
| Session | Auth sessions | id, token (unique), expiresAt, userId |
| Account | Auth accounts | id, password, providerId, userId |
| Verification | Email verification | id, identifier, expiresAt |
| WxUser | Mini-program users | id, openid, nickname, points |
| WxUserLevelProgress | User progress | id, userId, levelId, completedAt |
🔐 AUTH FLOW
1. User Login
└─> POST /api/auth/sign-in (Better Auth)
└─> Session created in DB
└─> Cookie set (7-day expiry)
2. Page Navigation
└─> Middleware checks cookie
├─> If missing → Redirect to login
└─> If present → Allow access
3. API Calls
└─> auth.api.getSession({ headers: request.headers })
├─> If null → Return 401 Unauthorized
└─> If valid → Proceed with operation
🛣️ API ENDPOINTS (14 total)
Auth (1 catch-all)
POST /api/auth/[...all]- Better Auth routes
Levels (4 routes)
GET /api/levels- List all (sorted by sortOrder)POST /api/levels- Create new (auto-increment sortOrder)PUT /api/levels- Update existingDELETE /api/levels?id=...- Delete levelPUT /api/levels/reorder- Batch reorder (transaction)
Users (4 routes)
GET /api/users- List all admin usersPOST /api/users- Create new adminPUT /api/users- Update user/passwordDELETE /api/users?id=...- Delete user (prevent self-delete)
WeChat Users (3 routes)
GET /api/wx-users?search=...&page=...- List with paginationGET /api/wx-users/[id]- Get user with progress historyDELETE /api/wx-users/level-progress- Batch delete progress
COS (1 route)
GET /api/cos/temp-key- Get 30-min temp credentials
📁 PROJECT STRUCTURE
MemeStudio/
├── app/
│ ├── (auth)/login/page.tsx # Public login
│ ├── (dashboard)/ # Protected pages
│ │ ├── levels/page.tsx # Levels UI + CRUD
│ │ ├── users/page.tsx # User management
│ │ └── wx-users/page.tsx # WeChat users
│ └── api/ # All API routes
├── lib/
│ ├── auth.ts # Better Auth config
│ ├── auth-client.ts # Client hooks
│ ├── prisma.ts # Singleton
│ ├── cos.ts # COS utilities
│ ├── api.ts # apiFetch (adds basePath)
│ └── utils.ts # Tailwind cn()
├── components/ # React UI components
├── prisma/schema.prisma # Database schema
├── middleware.ts # Session validation
├── types/index.ts # TypeScript interfaces
└── next.config.js # basePath=/studio config
🔑 ENVIRONMENT VARIABLES
# Required
DATABASE_URL=mysql://user:pass@host:port/db
BETTER_AUTH_SECRET=32+ chars
BETTER_AUTH_URL=https://domain.com # ⚠️ NO path!
NEXT_PUBLIC_APP_URL=https://domain.com
NEXT_PUBLIC_BASE_PATH=/studio
# Admin seed
ADMIN_EMAIL=user@example.com
ADMIN_PASSWORD=password
# Tencent COS
COS_SECRET_ID=AKID...
COS_SECRET_KEY=...
COS_BUCKET=lookai-1308511832
COS_REGION=ap-guangzhou
COS_APPID=1308511832
⚙️ KEY UTILITIES
apiFetch(path, options) - API Wrapper
- Automatically prepends basePath
- Usage:
apiFetch('/api/levels')→ requests/studio/api/levels - Used in all client components
getTempKey() - COS Credentials
- Returns temp credentials valid 30 minutes
- Restricts uploads to
mini_game/images/* - Called before image upload
useSession() - Auth Hook
- Returns:
{ data: session, isPending: boolean } - Shows current user email in header
- Used in all protected pages
🚀 DEPLOYMENT
Server: root@119.91.211.52:/root/apps/meme-studio
Process: PM2
Staging: /studio path (reverse proxy)
Deploy Steps:
npm run build(locally)./deploy.sh(rsync + npm install + PM2 restart)
⚠️ CRITICAL GOTCHAS
1. basePath Issues
❌ request.nextUrl.pathname INCLUDES basePath in Next.js 12
✅ request.nextUrl.pathname EXCLUDES basePath in Next.js 13+/14
✅ Middleware: DO check for `/levels`, NOT `/studio/levels`
❌ Don't manually prepend /studio to routes
✅ Use apiFetch() which handles basePath automatically
2. Better Auth Configuration
✅ BETTER_AUTH_URL = "https://domain.com"
❌ BETTER_AUTH_URL = "https://domain.com/studio" (WRONG!)
✅ basePath = "/api/auth"
❌ basePath = "/studio/api/auth" (WRONG!)
3. Cookie Naming
HTTP: better-auth.session_token
HTTPS: __Secure-better-auth.session_token
Middleware checks both!
4. Image Upload
Frontend → GET /api/cos/temp-key
→ Upload directly to COS (no backend)
→ Backend stores URL only
→ (Frontend handles COS SDK)
🔍 NO SHARING/INVITE LOGIC
✅ What Exists:
- Basic auth (email/password)
- User management (admins only)
- Level CRUD
- WeChat user tracking
❌ What's Missing:
- Share links/tokens
- Permission system (all authenticated = full admin)
- Invite workflows
- Role-based access
💡 COMMON TASKS
Add a new API endpoint
- Create file:
app/api/resource/route.ts - Follow session check pattern
- Use
apiFetch()from client - Add types in
types/index.ts
Modify database schema
- Edit
prisma/schema.prisma - Run
pnpm run db:push(dev) ordb:migrate - Generate types:
pnpm run db:generate
Deploy to production
- Push changes to git
- Run
pnpm run deploy(builds locally + deploys via ssh)
📋 QUICK STATS
- Framework: Next.js 14.2.28 (App Router)
- Auth: Better Auth v1.2.7
- Database: MySQL + Prisma v6.5.0
- UI: shadcn/ui + Tailwind CSS
- State: TanStack React Query
- Storage: Tencent COS
- Deployment: PM2 on Linux server
- Code Language: TypeScript
- Session Duration: 7 days
- COS Temp Credentials: 30 minutes
- Protected Routes: All except /login and /api/* (handled separately)