AI-powered movie & book recommendations tailored to who you actually are.
Live Demo · Setup Guide · Report Bug
Smart Advisor is a full-stack recommendation engine that builds a taste profile through a personality quiz — then uses Claude to generate one deeply-explained movie and one book pick that actually fit you. It is not a ranked list or a collaborative filter; every recommendation comes with a written explanation of why it matches your specific answers. The system uses different AI personas for users under 18 (warm, encouraging, PG-safe) and adults (direct, opinionated, willing to recommend dark and complex content).
- Sign up — email + password, Supabase Auth with PKCE flow
- Choose content — movies, books, or both
- Pick quiz length — 5, 10, or 15 questions
- Take the quiz — Claude generates personality-driven questions tailored to your age (scenario-based, preference comparisons, emotional responses)
- Get your pick — Claude reads your full answer profile and returns one movie and/or one book with a personalized explanation, enriched with real posters and metadata from TMDB and Google Books
- Save and revisit — every recommendation is persisted to your account with favorites and history
┌─────────────────────────────────────────────────────────────┐
│ Browser (Next.js App Router) │
│ Auth → Quiz → Questions → Answers → Results → History │
└──────────────────┬──────────────────────┬───────────────────┘
│ PKCE / JWT │ JWT
▼ ▼
┌─────────────────┐ ┌──────────────────────┐
│ Supabase Auth │ │ Supabase Edge Fns │
│ (PKCE flow) │ │ │
└────────┬────────┘ │ anthropic-questions │
│ │ anthropic-recs │
▼ │ tmdb-proxy │
┌─────────────────┐ │ google-books-proxy │
│Supabase Postgres│ └──────┬──────────┬────┘
│ │ │ │
│ profiles │ ▼ ▼
│ recommendations│ ┌────────────┐ ┌────────────┐
│ (RLS enforced) │ │ Anthropic │ │ TMDB / │
└─────────────────┘ │ Claude API │ │ Google │
└────────────┘ │ Books API │
└────────────┘
| Feature | Detail |
|---|---|
| Age-gated AI personas | Under-18 gets warm, encouraging picks. 18+ gets unfiltered recommendations including mature themes. |
| Single sharp recommendation | One movie. One book. Deeply explained. Not a ranked list. |
| Real cover art | TMDB and Google Books APIs fetch actual posters and covers. |
| Full auth with PKCE | Supabase Auth with email confirmation and PKCE flow. |
| Zero exposed secrets | All API keys live in Supabase Edge Function secrets, never the frontend. |
| Row Level Security | Every DB query is scoped to the authenticated user at the Postgres level. |
| Recommendation history | All picks saved to account with favorites and filters. |
| Layer | Technology | Why |
|---|---|---|
| Frontend | Next.js 15 + React 18 + TypeScript | App Router, SSR-ready auth, file-based routing |
| Styling | Tailwind CSS + Radix UI | Utility-first CSS, accessible primitives |
| Auth | Supabase Auth (PKCE) | Magic links, JWT, RLS integration built-in |
| Database | Supabase Postgres | RLS enforced at DB level, not app level |
| Edge Functions | Supabase Deno runtime | Server-side secrets, low latency, JWT verification |
| AI | Anthropic Claude Sonnet 4 | Better nuanced reasoning for taste-based recommendations |
| Movie data | TMDB API | Industry-standard movie metadata and poster images |
| Book data | Google Books API | Cover art and metadata for millions of titles |
| Hosting | Vercel | Zero-config Next.js deploys with automatic routing |
smart-advisor/
├── app/ # Next.js App Router pages
│ ├── layout.tsx # Root layout with metadata
│ ├── providers.tsx # Client providers (QueryClient, Auth, Toaster)
│ ├── globals.css # Global styles (Tailwind + custom)
│ ├── page.tsx # Landing page (/)
│ ├── not-found.tsx # 404 page
│ ├── auth/
│ │ ├── page.tsx # Sign up / sign in (/auth)
│ │ └── callback/route.ts # OAuth + email verification handler
│ ├── content-selection/page.tsx # Movie, book, or both
│ ├── question-count/page.tsx # 5 / 10 / 15 questions
│ ├── questionnaire/page.tsx # Dynamic AI-generated quiz
│ ├── results/page.tsx # AI recommendation display + favorites
│ └── history/page.tsx # Saved picks and favorites
│
├── public/
│ ├── smartadvisor.svg # App favicon and logo
│ ├── smart-advisor-preview.png # og:image for social sharing
│ ├── sitemap.xml # Search engine sitemap
│ ├── robots.txt # Crawler permissions
│ └── llms.txt # AI crawler discovery
│
├── src/
│ ├── components/
│ │ ├── account/ # History filters, user stats card
│ │ ├── enhanced/ # Shimmer loaders, animated spinners, progress bars
│ │ ├── ui/ # Base design system (shadcn — buttons, cards, inputs)
│ │ ├── ErrorBoundary.tsx # Global error boundary with recovery
│ │ └── ExpandableText.tsx # Truncated text with expand toggle
│ ├── hooks/
│ │ ├── useAuth.tsx # Session management, profile fetch, auth state
│ │ └── use-mobile.tsx # Responsive breakpoint detection
│ ├── lib/supabase/
│ │ ├── client.ts # Browser Supabase client (@supabase/ssr)
│ │ └── server.ts # Server Supabase client (cookie-based)
│ ├── store/
│ │ └── quizStore.ts # Zustand store for quiz flow state
│ ├── services/
│ │ ├── ai.ts # Calls anthropic-questions + anthropic-recommendations
│ │ ├── auth.ts # Supabase auth wrappers (sign up, sign in, profile)
│ │ ├── database.ts # Recommendation CRUD + favorites
│ │ ├── enhancedRecommendations.ts # Retry logic, TMDB/Books enrichment pipeline
│ │ ├── tmdb.ts # TMDB proxy client
│ │ └── googleBooks.ts # Google Books proxy client
│ ├── types/ # Shared TypeScript interfaces
│ │ ├── Answer.ts
│ │ ├── Question.ts
│ │ ├── Recommendation.ts
│ │ └── User.ts
│ ├── integrations/supabase/ # Supabase client + generated DB types
│ └── utils/
│ ├── envValidation.ts # Validates required env vars on startup
│ └── localStorage.ts # Safe localStorage wrapper with JSON helpers
│
├── middleware.ts # Next.js auth middleware (replaces ProtectedRoute)
│
├── supabase/
│ ├── functions/
│ │ ├── anthropic-questions/ # Claude generates personality quiz (JWT required)
│ │ ├── anthropic-recommendations/ # Claude generates recommendations (JWT required)
│ │ ├── tmdb-proxy/ # Movie metadata + poster URLs (public)
│ │ └── google-books-proxy/ # Book metadata + cover URLs (public)
│ ├── migrations/
│ │ └── 20250101000000_canonical_schema.sql # Tables, RLS, indexes, triggers
│ └── config.toml # Function config (JWT, entrypoints)
│
├── docs/
│ └── SETUP.md # Full local + Vercel + Supabase setup guide
└── .env.example # All required variables documented
git clone https://github.com/ponderrr/smart-advisor
cd smart-advisor
npm install
cp .env.example .env.local
# Fill in NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY
npm run dev
# http://localhost:3000For the full guide — including Supabase project setup, database migrations, edge function deployment, and production secrets — see docs/SETUP.md.
| Variable | Where to set | Required | Description |
|---|---|---|---|
NEXT_PUBLIC_SUPABASE_URL |
Vercel + .env.local |
Yes | Your Supabase project URL |
NEXT_PUBLIC_SUPABASE_ANON_KEY |
Vercel + .env.local |
Yes | Supabase anon/public key |
ANTHROPIC_API_KEY |
Supabase secrets | Yes | Powers all AI question and recommendation generation |
TMDB_API_KEY |
Supabase secrets | No | Movie posters and metadata. Falls back to placeholder if absent |
GOOGLE_BOOKS_API_KEY |
Supabase secrets | No | Book covers and metadata. Falls back to placeholder if absent |
Note:
ANTHROPIC_API_KEY,TMDB_API_KEY, andGOOGLE_BOOKS_API_KEYare Supabase Edge Function secrets. Set them in Supabase Dashboard → Edge Functions → Manage Secrets. They are never exposed to the browser.
All API keys (Anthropic, TMDB, Google Books) are server-side only — they live in Supabase Edge Function secrets and are never bundled into the frontend. Row Level Security is enforced at the Postgres level: every SELECT, INSERT, UPDATE, and DELETE on profiles and recommendations is scoped to auth.uid(), so even a compromised client cannot access another user's data. Authentication uses the PKCE flow with cookie-based sessions managed by @supabase/ssr and Next.js middleware. The NEXT_PUBLIC_SUPABASE_ANON_KEY exposed in the frontend is intentionally public; it can only access data that RLS policies explicitly allow for the authenticated user.
Vercel handles the frontend — it auto-detects Next.js and handles routing automatically via the App Router. Only two env vars go in Vercel: NEXT_PUBLIC_SUPABASE_URL and NEXT_PUBLIC_SUPABASE_ANON_KEY. Everything else (database, auth, edge functions, secrets) lives in Supabase. See docs/SETUP.md for step-by-step instructions.
- Social sharing — let users share a recommendation card with friends
- More content types — podcasts, TV shows, video games
- Recommendation comparison — side-by-side view of past picks
- Rate limiting on edge functions to prevent abuse at scale