Building a Modern Media Tracker Through Human-AI Collaboration
MediaLog is a personal media tracking application that combines Letterboxd (movies) and Goodreads (books) data into a single, beautiful dashboard. This case study documents the complete development process, from initial concept to production deployment, built entirely through human-AI collaboration over the course of a single day (February 9, 2026).
What makes this project interesting isn't just what was builtโit's how it was built. Every line of code, every design decision, and every feature was created through iterative dialogue between a human (Thomas Hunt) and an AI assistant (Claude by Anthropic). No traditional coding. No frameworks. Just conversation, iteration, and rapid prototyping.
February 9, 2026 - Morning Session โฑ๏ธ 2 hours
Create a centralized dashboard to track personal media consumption from multiple sources. The existing setup involved checking Letterboxd for movies and Goodreads for books separatelyโno unified view, no analytics, no insights.
Build a custom web application that aggregates data from both platforms into a MySQL database, providing a single source of truth for all media consumption.
Created MySQL schema with posts table supporting multiple content types:
Built scrapers for two platforms:
Initial dashboard with essential features:
Production-ready setup:
By the end of Session 1, we had a working application with a complete database of personal media history. The foundation was solid: clean separation of concerns, efficient queries, and a scalable architecture ready for enhancement.
February 9, 2026 - Midday Session โฑ๏ธ 1.5 hours
Having raw data wasn't enough. Users (me!) wanted deeper insights: reading patterns, viewing habits, projections for year-end goals, and meaningful statistics beyond simple counts.
Enhance the application with three dedicated analytics pages, each providing unique insights into consumption patterns, trends, and future projections.
Comprehensive stats across all media:
Reading-specific analytics:
Viewing-specific analytics:
Smart forecasting features:
// Example: Year-end projection calculation
$daysInYear = 365;
$daysPassed = date('z') + 1;
$daysRemaining = $daysInYear - $daysPassed;
$booksPerDay = $booksThisYear / $daysPassed;
$projectedBooks = $booksThisYear + ($booksPerDay * $daysRemaining);
// Smart rounding for realistic projections
$projected = round($projectedBooks);Analytics transformed the application from a simple tracker to a powerful insights tool. Users could now understand their consumption patterns, set realistic goals, and discover interesting trends in their viewing/reading habits.
February 9, 2026 - Afternoon Session โฑ๏ธ 2 hours
The existing homepage was functional but boring: just a simple list of recent items. We wanted something more engagingโa dashboard that felt personal, highlighted memories, and made rediscovering content easy.
Complete homepage redesign with a modern 3-column layout, hero stats section, and an innovative "On This Day" feature that surfaces memories from previous years.
Eye-catching stats display:
Smart memory feature with fallback:
Latest consumption timeline:
Rediscovery feature:
Image-first design:
Sticky top navigation:
Full mobile optimization:
Smooth interactions:
// Smart fallback: never show empty
if (empty($onThisDay)) {
for ($daysBack = 1; $daysBack <= 365; $daysBack++) {
$checkDate = date('m-d', strtotime("-{$daysBack} days"));
// Query for items on this historical date
$fallback = queryItemsByDate($checkDate);
if (!empty($fallback)) {
$onThisDay = $fallback;
$onThisDayDate = date('F j', strtotime("-{$daysBack} days"));
break; // Exit on first match
}
}
}The redesign transformed user engagement. The "On This Day" feature became the most-used feature, encouraging daily visits. The visual gallery made browsing enjoyable, and the 3-column layout maximized information density without feeling cluttered.
February 9, 2026 - Late Afternoon โฑ๏ธ 1 hour
The application had an Authors page for books but nothing equivalent for movies. We wanted symmetry: if we can track favorite authors, why not favorite directors? Plus, the movie data lacked critical metadata like runtime, genres, and director information.
Build a comprehensive Directors page mirroring the Authors functionality, and create a metadata scraper to enrich movie data from Letterboxd with directors, genres, and runtime information.
New analytics page for filmmakers:
Letterboxd data extraction:
Smart director parsing:
Summary metrics displayed:
// Convert user URL to canonical film URL
$canonicalUrl = preg_replace(
'/letterboxd\.com\/[^\/]+\/film/',
'letterboxd.com/film',
$movie['url']
);
// Extract director from meta tag
if (preg_match('/Each director card displays their name, film count, years watched, and a grid of poster images for every film they directed. The cards are sorted by watch count, putting your most-watched directors at the top.
The Directors page became immediately useful, revealing interesting patterns: "I've watched 5 films by Christopher Nolan" or "I only discovered Greta Gerwig in 2023." The metadata enrichment also enabled future features like filtering by genre and runtime-based analytics.
February 9, 2026 - Evening Session โฑ๏ธ 1 hour
The application was functionally complete but lacked a cohesive identity. The name "Hunt HQ" was generic and didn't convey the purpose. We also had edge cases with empty 2026 data showing zeros, and the overall polish needed refinement for public presentation.
Complete rebrand to "MediaLog" with professional polish across all pages. Implement smart year fallbacks, create shared design systems, add comprehensive documentation, and prepare for production deployment as a portfolio piece.
New identity across 10 pages:
Never show empty data:
Professional consistency:
Reusable attribution:
Portfolio integration:
Comprehensive guides created:
Graceful degradation:
Deployment preparation:
// Check if current year has any data
$currentYear = date('Y');
$stmt = $pdo->query("
SELECT COUNT(*) as total FROM posts
WHERE (site_id = 6 OR site_id = 7)
AND YEAR(publish_date) = {$currentYear}
");
$currentYearCount = $stmt->fetch()['total'];
// Fallback to previous year if current year is empty
if ($currentYearCount == 0) {
$currentYear = $currentYear - 1;
}Moved from generic to descriptive. "MediaLog" clearly communicates purpose: logging media consumption.
Specific attribution to data sources. Users immediately understand what it does and where data comes from.
Cleaner URLs and better SEO. Aligns with branding and makes purpose clear in the URL itself.
Version 5.0 transformed MediaLog from a personal tool to a showcase project. The rebrand gave it identity, the polish made it portfolio-worthy, and the documentation made it a valuable case study for human-AI collaboration. The application was now ready for public presentation and deployment.