Recommendation Generation
Recommendation generation happens inside GET /api/recommend, which handles auth, cache reuse, regeneration, My List context, validation, and fallback behavior in one place.
How It Works
- Authenticates the user via a Supabase JWT token
- Fetches the user's watched movies from
user_watched_movies - Fetches the user's My List IDs from
user_my_list - Builds a compact taste profile from watched movies plus My List context
- Calls the platform AI client with JSON-schema-constrained output
- Resolves recommendation names back to TMDB IDs through Supabase search first, then TMDB fallback when needed
- Filters out watched movies, duplicates, unresolved titles, and excess My List matches
- Requests replacement picks when backend validation blocks too many candidates
- Returns valid TMDB IDs and caches them in Supabase
Provider Strategy
The AI client uses OpenAI-compatible chat completions.
Provider order comes from server/utils/recommendations/ai-client.ts:
- Google AI Studio models from
NUXT_GOOGLE_MODELS - OpenRouter models from
NUXT_OPENROUTER_MODELS
If both providers are configured, Google is tried first. The server walks every configured model in order until one succeeds.
Default models in nuxt.config.ts are:
gemini-flash-lite-latestgemini-2.5-flash-litegemini-2.0-flash-litegoogle/gemini-2.5-flash-litethrough OpenRouter
Rate Limiting
Recommendation generation is limited to 20 requests per day per authenticated user.
The following headers are included on generation requests:
| Header | Description |
|---|---|
X-RateLimit-Limit | Maximum requests allowed per day |
X-RateLimit-Remaining | Requests remaining in the current window |
X-RateLimit-Reset | Unix timestamp (ms) when the window resets |
Failure Behavior
When regeneration fails and an older cached set exists, /api/recommend can return:
regenerationErrorstaleRecommendations
If no provider is configured, or every configured provider/model attempt fails, the route returns an AI-provider error message and a regenerationError flag. If cached recommendations are available, it also returns a staleRecommendations flag to indicate that the returned recommendations may be outdated.