Skip to content

Tendo33/MoodShakerFront

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

252 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MoodShaker Frontend

An AI-powered bilingual cocktail experience that turns a quick mood check into a complete drink recommendation.

Chinese Next.js React TypeScript Prisma Tailwind CSS

Overview Status Quick Start Deployment

Overview

MoodShaker is a bilingual web app for cocktail discovery and recommendation. Instead of browsing a static recipe database first, users answer a short mood-based questionnaire and receive a personalized cocktail with ingredients, tools, steps, and a shareable visual card.

The project is built with Next.js App Router, React 19, TypeScript, Prisma, PostgreSQL, and a pair of AI-backed endpoints for recommendation and image generation. It also ships with a localized experience for Chinese and English users, a gallery for browsing drinks, and a detail page for revisiting recipes.

Current Status

Implementation status

  • Batch 1 hardening is complete: local verification is restored, private recommendation access no longer puts editToken in the URL, unsafe wildcard CORS headers were removed, API 500s were standardized, and shared rate-limit storage was added.
  • Lightweight automated verification is now part of the repo through pnpm test.
  • Recommendation recovery is intentionally same-browser-session access. When local edit access is unavailable, the product now shows an explicit unavailable state instead of a silent failure.

Release status

  • Suitable for local development, staging, and controlled beta testing.
  • Not yet recommended for a full production launch.

Formal release blockers are tracked in docs/release-readiness.md.

Highlights

  • Two recommendation styles are supported through different bartender personas: classic_bartender and creative_bartender.
  • Language-aware routing is built in, with /cn and /en paths plus automatic redirect logic in proxy.ts.
  • The main product flow is connected: landing page, questionnaire, recommendation page, gallery, cocktail details, and share card output.
  • Recommendation access is private by default and requires both the recommendation id and a local edit token.
  • Server responses use stable error codes and generic client-safe 500 messages.
  • Recommendation and image endpoints emit rate-limit headers and can use shared Postgres-backed buckets.

Screenshots

Home Questionnaire
Home Questionnaire
Gallery Cocktail Detail
Gallery Cocktail Detail

Demo Flow

Landing page
  -> mood questionnaire
  -> AI cocktail recommendation
  -> generated image + recipe details
  -> shareable card
  -> gallery browsing
  -> cocktail detail revisit

Tech Stack

  • Framework: Next.js 16 with App Router
  • UI: React 19, Tailwind CSS 4, Framer Motion, Radix UI, Lucide
  • Language: TypeScript
  • Data layer: Prisma with PostgreSQL
  • Data fetching: SWR
  • AI integration: OpenAI-compatible chat endpoint and image generation endpoint
  • Tooling: pnpm, ESLint, tsx, Docker Compose

Architecture

flowchart LR
  A["User"] --> B["Localized app routes (/cn, /en)"]
  B --> C["Questionnaire / Gallery / Detail pages"]
  C --> D["App API routes"]
  D --> E["Cocktail recommendation provider"]
  D --> F["Image generation provider"]
  D --> G["Prisma Client"]
  G --> H["PostgreSQL"]
  C --> I["Client persistence / share card / motion UI"]
Loading

Main runtime pieces

  • App routes live under app/[lang] and provide the user-facing pages.
  • API handlers live under app/api and coordinate recommendation generation, detail lookup, image generation, and private recommendation retrieval.
  • Shared UI lives in components, while app-wide state is managed in context.
  • Database schema, migrations, seed data, and maintenance scripts are in prisma.
  • Current remediation notes and performance tracking live under docs.

Project Structure

app/
  api/
    cocktail/
    image/
    recommendation/
  [lang]/
    page.tsx
    questions/page.tsx
    gallery/page.tsx
    cocktail/[id]/page.tsx
    cocktail/recommendation/page.tsx
components/
  animations/
  layout/
  pages/
  share/
  ui/
context/
docs/
  plans/
  screenshots/
lib/
locales/
prisma/
public/
tests/
proxy.ts

Quick Start

1. Prerequisites

  • Node.js >= 22
  • pnpm >= 10
  • PostgreSQL 15+ or Docker

2. Install dependencies

pnpm install

postinstall runs prisma generate, so a clean install should produce a usable Prisma client automatically.

3. Configure environment variables

cp .env.example .env

Then fill in the required values in .env.

4. Prepare the database

Make sure PostgreSQL is running and DATABASE_URL is reachable:

pnpm db:init

This command will:

  • generate the Prisma client
  • apply migrations
  • seed initial cocktail data

5. Start the development server

pnpm dev

Open http://localhost:3000. Requests to / are redirected to the proper language path, defaulting to /cn.

Environment Variables

Variable Required Description
OPENAI_API_KEY Yes API key for the chat recommendation endpoint
OPENAI_BASE_URL Yes OpenAI-compatible base URL
OPENAI_MODEL Yes Chat model name
IMAGE_API_URL Yes for image generation Image generation endpoint
IMAGE_API_KEY Yes for image generation Image generation API key
IMAGE_MODEL No Image model name
IMAGE_FETCH_HOST_ALLOWLIST Recommended Comma-separated host allowlist for server-side image fetch and optimization
DATABASE_URL Yes PostgreSQL connection string
HOST_PORT Optional Exposed web port for Docker Compose
POSTGRES_USER Optional Database username for Docker Compose
POSTGRES_PASSWORD Optional Database password for Docker Compose
POSTGRES_DB Optional Database name for Docker Compose

Available Scripts

Command Description
pnpm dev Start the local development server
pnpm build Build the production bundle
pnpm start Run the production build
pnpm lint Run ESLint
pnpm test Run the lightweight Node-based regression suite
pnpm test:e2e Run the Playwright smoke test for the localized home -> questions flow
pnpm db:init Generate Prisma client, apply migrations, and seed data
pnpm prisma:generate Generate Prisma client only
pnpm prisma:migrate Apply Prisma migrations
pnpm prisma:seed Seed cocktail data
pnpm prisma:backfill-thumbnails Backfill the thumbnail field from stored images

API Endpoints

Method Endpoint Purpose
POST /api/cocktail Generate a cocktail recommendation from questionnaire input
GET /api/cocktail/:id Fetch a public cocktail detail record by id
POST /api/image Generate or refresh a recommendation image when the caller has edit access
POST /api/recommendation/:id Retrieve a private recommendation by id using an editToken in the JSON body

Security and behavior notes

  • editToken is no longer accepted in the URL for private recommendation access.
  • POST /api/recommendation/:id returns recommendation metadata without echoing the editToken.
  • POST /api/cocktail is currently rate-limited by client IP.
  • POST /api/image is rate-limited per recommendation id.
  • In production, missing shared rate-limit storage is treated as a deployment error instead of silently falling back forever.

Localization

  • Supported languages are cn and en.
  • proxy.ts detects language from the URL, cookie, and Accept-Language header.
  • Requests without a language prefix are redirected to a localized route.
  • Translation dictionaries live in locales/cn.ts and locales/en.ts.

Deployment And Release

This repository already includes the essentials for containerized deployment:

Minimum deployment checklist

  1. Set all required environment variables.
  2. Run Prisma migrations against the target database.
  3. Verify the rate_limit_buckets table exists after deploy.
  4. Verify the recommendation endpoint returns 503 instead of a generic 500 when shared limiter storage or the primary database is unavailable.
  5. Run the verification commands:
pnpm test
pnpm test:e2e
pnpm lint
pnpm build
  1. Run a manual smoke pass:
    • home -> questions -> recommendation
    • image generation / refresh
    • recommendation restore from the same browser session
    • gallery search and filter
    • cocktail detail page in both languages

Current release warning

The project is not yet ready for a full GA release. See docs/release-readiness.md before promoting beyond staging or a controlled beta.

Troubleshooting

Prisma P2022: missing thumbnail column

If you see:

The column `cocktails.thumbnail` does not exist in the current database

Run:

pnpm db:init

If the database already exists and only migrations are missing, you can also try:

pnpm prisma:migrate

Rate limiting fails immediately after deploy

If recommendation or image requests start failing in production after the hardening batch, verify that the latest Prisma migration was applied and that the rate_limit_buckets table exists.

Recommendation or image API errors

  • Check that the keys and URLs in .env are correct.
  • Make sure OPENAI_BASE_URL points to an OpenAI-compatible endpoint.
  • Confirm IMAGE_FETCH_HOST_ALLOWLIST includes any remote host you expect the server to fetch for image optimization.
  • Inspect the server logs for the handlers under app/api.

Private recommendation cannot be reopened

Private recommendation recovery is currently same-browser-session access. If local edit access was cleared, the app will show an explicit unavailable state and ask the user to generate a new recommendation.

Validation

The baseline checks for this repository are:

pnpm test
pnpm lint
pnpm build

If you install dependencies in an environment where Prisma client generation was skipped, run this once before pnpm build:

pnpm prisma:generate

Recommended manual smoke checks:

  1. Complete the questionnaire and verify recommendation generation.
  2. Refresh the recommendation image and confirm rate-limit feedback behaves correctly.
  3. Reopen a private recommendation from the same browser session.
  4. Confirm a private recommendation without local access shows the unavailable state.
  5. Browse the gallery and confirm search or filters still behave correctly.
  6. Open a cocktail detail page and switch languages.
  7. Verify share card generation and download flow if you touch that area.

Project Docs

Contributing

If you open a PR, include:

  • a short summary of the change
  • linked issue or context, if any
  • verification steps
  • screenshots for UI changes
  • notes for environment or database updates

Notes

  • AI-generated content should be reviewed before real-world use.
  • Do not commit .env or any production secret values.
  • Current automated coverage is still lightweight. Treat pnpm test as regression support, not a substitute for end-to-end verification.

About

A cocktail recommendation website

Topics

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages