Kynoa
Project Overview
We designed and built Kynoa to set a new standard for what a modern movie tracking platform can be. The brief was clear: go beyond the tired watchlist-and-stars formula and deliver something genuinely useful — fast discovery, an expressive rating system, and a social layer that actually earns its place in the product.
Project Details
Type
In-House Product
Designed and developed by Topography Digital
Status
Beta Launch
Live and actively developed
Timeline
Ongoing
Iterative development
The Challenge
The TMDB API key must never be exposed to the client. Every request for movies, TV shows, people, and genres had to be routed through secure server-side API routes — requiring a full proxy layer that maps cleanly to the TMDB SDK.
Ratings, favorites, and lists must be strictly scoped to the authenticated user. With Supabase as the backend, this meant implementing Row Level Security (RLS) policies across every table — preventing any possibility of cross-user data leakage.
Supabase Auth relies on cookies, and Safari's Intelligent Tracking Prevention (ITP) has stricter cookie policies than other browsers. Session persistence was breaking silently on page reload in Safari, requiring careful tuning of sameSite, secure, and maxAge cookie options.
Implementing a follow/follower system — with a live activity feed showing what followed users are rating — introduced query complexity that basic REST endpoints couldn't handle efficiently. Purpose-built server routes and database views were needed.
Users coming from Letterboxd expect to bring their history with them. Parsing Letterboxd's CSV export format, matching each title against TMDB, converting 0.5–5 star ratings to a 1–100% scale, and handling edge cases like ambiguous titles and year mismatches required a robust migration pipeline.
Objectives
Deliver a Best-in-Class Discovery Experience
Give users powerful tools to find movies and TV — by popularity, genre, rating, release date, and trending windows — backed by TMDB's full catalog.
Build an Expressive Rating System
Replace the reductive 5-star model with a 1–100% scale, giving users the granularity to genuinely express how they feel about a film.
Create a Social Layer That Adds Real Value
Let users follow friends, see a live activity feed of what they're watching, and share curated lists — making the platform more than just a personal tracker.
Make Migration From Other Platforms Seamless
Support Letterboxd CSV import so existing film lovers can carry their ratings and watchlists over without starting from scratch.
Ship With Production-Grade Security
Row Level Security, Content Security Policy headers, Cloudflare Turnstile bot protection, and server-side API key handling — engineered in from the start, not bolted on at the end.
The Solution
Key Features
Media Discovery
Browse popular, top-rated, trending, and new-release content. Advanced filtering by genre, rating, year, and media type across both movies and TV shows.
Ratings & Favorites
A 1–100% rating scale with per-user history, average tracking, and a favorites system — all persisted in Supabase with full RLS.
Custom Lists
Users can create, manage, and share curated lists of movies and TV shows. Lists support public visibility and are browsable across the platform.
Social & Activity Feed
A follow/follower graph with a live activity feed showing what followed users are rating and favoriting — sorted by recency with pagination.
User Profiles
Public profile pages with username-based routing, avatar uploads via Supabase Storage, bio, and a full view of that user's ratings and lists.
Letterboxd Import
CSV import pipeline that parses Letterboxd exports, matches titles against TMDB, converts ratings, and adds unrated entries to a Watch Later list.
Technical Implementation
| Technology | Role |
|---|---|
| Nuxt 4 | Full-stack framework — SSR, routing, server API routes |
| Nuxt UI | Component library and design system |
| Tailwind CSS | Utility-first styling |
| TypeScript | Type safety across client and server |
| Supabase (PostgreSQL) | Database, auth, storage, and Row Level Security |
| @nuxtjs/supabase | Supabase module with SSR-compatible session handling |
| TMDB API (tmdb-ts) | Movie and TV data — proxied via server routes |
| Zod | Runtime validation on all API request/response shapes |
| Bun | Fast runtime and package manager |
| Vercel | Serverless deployment with global edge distribution |
All TMDB requests are routed through server-side API handlers, keeping the API key off the client entirely. Supabase is accessed both server-side (via a service-role client for trusted operations) and client-side (via the anon key, with RLS enforcing data ownership).
Authentication uses @nuxtjs/supabase with carefully tuned cookie options (sameSite: lax, secure: true in production) to ensure reliable session persistence across all browsers, including Safari with ITP.
Security headers — including a strict Content Security Policy, X-Frame-Options, X-Content-Type-Options, and Permissions-Policy — are applied globally in production via Nitro route rules.
Cloudflare Turnstile is integrated on auth forms to prevent bot signups without degrading the user experience.
The Supabase schema is purpose-built for the social platform use case:
| Table | Purpose |
|---|---|
profiles | Public user data — username, avatar, bio |
ratings | Per-user media ratings with TMDB metadata cached |
lists | User-created curated lists with public/private visibility |
list_items | Junction table for list contents |
follows | Directed follow graph (follower → following) |
Every table uses Row Level Security policies to ensure users can only read/write their own data, with appropriate public read exceptions for profiles and public lists. Analytic views pre-aggregate stats like average ratings and per-user counts for efficient querying.
Highlights
What We Delivered
100%
Server-Side API Security
Zero TMDB API key exposure — all external API calls proxied through server routes.
6 Core
Feature Areas
Discovery, ratings, lists, social graph, profiles, and import — all fully shipped.
Full RLS
Data Isolation
Row Level Security policies on every user-data table — cross-user data leakage is impossible at the database level.
Cross-Browser
Safari Compatible Auth
Session persistence works reliably across Chrome, Firefox, and Safari — including Safari's stricter ITP cookie handling.
Conclusion
Kynoa is the result of treating a product with the full rigour it deserves — from architecture to UX to security. Every decision, from the TMDB proxy layer to the RLS policies to the Safari auth handling, was made deliberately and with real users in mind.
The result is a platform that's genuinely enjoyable to use: fast, secure, and social in a way that adds real value.
Let's create your success story
Ready to achieve similar results? Get in touch and let's discuss how we can help transform your business.