简体中文 · English
MoodShaker is an AI-powered, bilingual cocktail recommendation web app.
It turns a short mood questionnaire into a personalized cocktail recipe with ingredients, tools, steps, and a shareable visual card.
- AI recommendation pipeline with two bartender modes (
classic_bartender/creative_bartender). - Localized UX in Chinese and English (
/cn,/en) with path-based routing and auto language redirect. - Full cocktail journey: home → questions → recommendation → gallery → detail page.
- Image generation + optimization via external image API, optional
sharpprocessing, and DB thumbnail backfill support. - Performance-focused client state using split contexts, async storage batching, request dedup/cache, and dev performance overlay.
| Home | Questionnaire |
|---|---|
![]() |
![]() |
| Gallery | Detail |
|---|---|
![]() |
![]() |
- Framework: Next.js 16 (App Router), React 19
- Language: TypeScript
- Styling/UI: Tailwind CSS, Framer Motion, Radix UI, Lucide
- Data layer: Prisma + PostgreSQL
- AI integration: OpenAI-compatible chat endpoint + image generation endpoint
- Tooling: pnpm, ESLint (
next/core-web-vitals+ TypeScript rules)
flowchart LR
A["User (Web)"] --> B["App Router Pages (/cn, /en)"]
B --> C["Client Contexts (Language / Form / Result)"]
C --> D["API Routes (/api/cocktail, /api/image)"]
D --> E["LLM + Image Providers"]
D --> F["Prisma"]
F --> G["PostgreSQL"]
B --> H["Gallery / Detail (DB + fallback catalog)"]
app/
[lang]/
page.tsx
questions/page.tsx
gallery/page.tsx
cocktail/[id]/page.tsx
cocktail/recommendation/page.tsx
api/
cocktail/route.ts
cocktail/[id]/route.ts
image/route.ts
components/
context/
locales/
lib/
prisma/
proxy.ts
- Node.js 20+
- pnpm 9+
- PostgreSQL 15+ (or Docker)
pnpm installcp .env.example .envFill in required API/database values in .env (see Environment Variables).
Make sure PostgreSQL is running and DATABASE_URL is reachable, then:
pnpm db:initThis runs Prisma client generation, migration deploy, and seed data.
pnpm devOpen http://localhost:3000.
Root path redirects to language routes (default /cn).
| Variable | Required | Description |
|---|---|---|
OPENAI_API_KEY |
Yes | API key for chat completion endpoint |
OPENAI_BASE_URL |
Yes | OpenAI-compatible base URL (keep trailing /, e.g. .../v1/) |
OPENAI_MODEL |
Yes | Chat model name |
IMAGE_API_URL |
Yes (for image generation) | Image generation endpoint |
IMAGE_API_KEY |
Yes (for image generation) | Image API key |
IMAGE_MODEL |
No | Image model name |
DATABASE_URL |
Yes for persistent DB mode | PostgreSQL connection string |
HOST_PORT |
Optional (Docker Compose) | Exposed web port |
POSTGRES_USER |
Optional (Docker Compose) | Database username |
POSTGRES_PASSWORD |
Optional (Docker Compose) | Database password |
POSTGRES_DB |
Optional (Docker Compose) | Database name |
| Command | Description |
|---|---|
pnpm dev |
Start local development server |
pnpm build |
Build production bundle |
pnpm start |
Run built app |
pnpm lint |
Run ESLint |
pnpm db:init |
Prisma generate + migrate deploy + seed |
pnpm prisma:generate |
Generate Prisma client |
pnpm prisma:migrate |
Apply Prisma migrations |
pnpm prisma:seed |
Seed popular cocktails |
pnpm prisma:backfill-thumbnails |
Backfill thumbnail column from existing images |
| Method | Endpoint | Purpose |
|---|---|---|
POST |
/api/cocktail |
Generate cocktail recommendation from questionnaire payload |
GET |
/api/cocktail/:id |
Fetch cocktail detail by id |
POST |
/api/image |
Generate cocktail image and optionally persist optimized image/thumbnail |
- Supported languages:
cn,en proxy.tshandles language detection from URL, cookie, andAccept-Language- Missing language prefix paths are redirected to localized routes
- Translation dictionaries live in
locales/cn.tsandlocales/en.ts
This repo includes:
Dockerfilefor multi-stage app image builddocker-compose.ymlwithmoodshaker-web+postgresservicesscripts/docker-entrypoint.shto init DB schema and seed on container startup
Run:
docker compose up -dIf you see:
The column `cocktails.thumbnail` does not exist in the current database
Run:
pnpm db:init
# or
pnpm prisma:migrate- Verify
.envkeys and endpoint URLs - Ensure
OPENAI_BASE_URLis OpenAI-compatible and includes/v1/ - Check server logs from
api/openai.tsandapp/api/*handlers
There is no automated test runner configured yet. Recommended checks:
pnpm lint
pnpm buildManual smoke checks:
- Questionnaire flow and recommendation generation
- Gallery search + filters
- Detail page rendering and language switch
- Share card generation/download
PRs are welcome. Suggested PR content:
- short summary
- related issue (if any)
- verification steps
- screenshots for UI changes
- env/database notes when applicable
- AI outputs can be inaccurate; always review recipes and safety constraints.
- Do not commit
.envor any secret values.



