Media Club In Progress

Self-hosted SvelteKit catalog for movies, TV shows, vinyl, and books with collections, genre filters, show tracker, random picker, and 14 MCP tools for LLM clients.

Role
Project Lead / Full Stack Developer
Year
2026
Category
Software Dev

About This Project

Built Media Club as a free, open-source catalog for collectors who want to share what they own without running a media server or storing files. The app tracks titles, cover art, and metadata across four categories with separate owned lists, wishlists, and per-category collection folders. A show tracker keeps actively watching and upcoming TV series outside the permanent catalog. TMDB genre sync, include/exclude filters, and a random movie picker make large catalogs easy to browse. External API keys stay server-side behind authenticated search proxies, and the public-read/admin-write model lets visitors browse while only the admin can mutate data. Shipped dual deployment paths (Cloudflare Workers + D1 or Docker + SQLite), 151 unit tests, and an MCP endpoint so LLM clients can search and organize the catalog conversationally.

Project Gallery

Technologies Used

SvelteKitSvelte 5TypeScriptTailwind CSSDrizzle ORMSQLiteCloudflare WorkersCloudflare D1DockerZodModel Context ProtocolVitestGitHub Actions

Engineering Challenges

Dual Database Adapters: Designed a single Drizzle schema that runs on local SQLite (better-sqlite3) for dev and Docker while switching to Cloudflare D1 in production Workers, without branching business logic across environments.

Public Read, Admin Write: Enforced a security model where catalog pages are fully public but every mutation and metadata search requires session auth, with rate limiting on search endpoints and API keys never exposed to the browser.

Unified Catalog Schema: Modeled movies, TV shows, vinyl, and books in one items table with category and list_type discrimination, collection grouping, and duplicate prevention via a composite unique constraint on external provider IDs.

Show Tracker vs Collection: Added a separate show_tracker_items table so actively watched and upcoming series can be tracked without forcing every title into the owned catalog.

Genre Pipeline at Scale: Synced TMDB genres into JSON metadata, built include/exclude filters and a multi-select picker dialog, and added bulk genre sync in Settings so admins can refresh hundreds of titles in one action.

LLM Integration: Exposed 14 MCP tools for catalog search, add, move-to-owned, collection management, and stats while keeping Bearer token auth and reusing the same server-side item services as the web UI.

Technical Highlights

Adapter Switching: Vite config toggles between Cloudflare and Node adapters at build time; getDb() selects D1 or file-backed SQLite based on the runtime platform binding.

Server-Side Metadata Proxies: Authenticated /api/search routes proxy TMDB, Discogs, and Open Library with Zod validation, 30 req/min IP rate limits, and normalized response shapes for the admin add flow.

Discovery UX: Supercharged random movie picker with genre and collection filters, DVD-style show cards, studio atmosphere gradients, GIF covers on hover, and a rotary nav dial for category navigation.

Streaming Admin Lists: Admin-only watchlists with TMDB provider badges, overflow modals, and CRUD routes separate from the public catalog.

Session Security: PBKDF2 password hashing, SHA-256 hashed session tokens in HTTP-only cookies, CSRF protection via SvelteKit form actions, and CSP nonces set in hooks.server.ts.

Test and CI Pipeline: 151 Vitest unit tests across auth, items, collections, import, show tracker, TMDB genres, random picker, and MCP handlers; GitHub Actions runs lint, check, test, and dependency audit on every pull request.

Business Logic

Collector-First UX: Separate owned and wishlist views per category, one-click wishlist-to-owned promotion, per-item notes and format tags, and collection folders for curated groupings like genre marathons or reading lists.

Catalog, Not Streaming: Deliberately tracks titles and cover art only so collectors can share inventories without piracy risk, file hosting costs, or media-server complexity.

Zero Hosting Cost Path: Documented Cloudflare Workers + D1 deployment on the free tier so personal collectors can fork, deploy, and share a public catalog without monthly fees.

Open Source Onboarding: MIT license, seed and mock catalog scripts, theme customization via palette.ts, and step-by-step Cloudflare and Docker guides to lower the barrier for self-hosters.