~/ Build Log / Projects

The Nerd Herd Movie Club

Project Info

  • Category Projects
  • Published March 2026
The Nerd Herd Movie Club

I Built a Movie Club App for My Coworkers

We started with a spin wheel. Somebody would share a link, everyone pasted in their movie suggestions, and whatever the wheel landed on became the pick. It worked fine for a few weeks. Then the wheel picked the same director back to back. Then someone suggested something we had already watched. Then someone noticed that one person had submitted five movies and another had submitted one, and the person with five was essentially running the selection. Nobody said anything, but the cracks were there.

We needed something better. So I built it.

The club is called the Nerd Herd Movie Club. We're a work team that watches movies together. In four months we have watched 24 films as a group, and the whole process now runs through a custom web app I built from scratch using Django, Celery, and Tailwind CSS.


The Problem With Informal Movie Clubs

The spin wheel had no memory. It could not know we had already watched something. It had no concept of fairness beyond pure randomness. There was no record of what anyone thought of a given film, no way to see patterns in the group's taste, and no system for handling the fact that some people participate more than others.

Replacing it with a spreadsheet would have fixed the memory problem but not the rest. What I wanted was a system that was fair without feeling bureaucratic, that generated real data about the group's preferences, and that added a bit of structure without sucking the fun out of picking a movie with your coworkers.


How It Works

Every member gets a pool of "slots," which represent how many movies they can have queued at once. You search for a movie by title, the app pulls the metadata automatically from The Movie Database (a public film API), and the movie lands in your pool with poster, runtime, description, and release year already filled in.

When the club is ready to pick the next film, a weighted lottery runs. Not everyone has equal odds, and that is intentional. If your movie was just picked, your weight resets to baseline. If you have been waiting through several rounds with no luck, your weight increases. The more time passes without a win, the better your chances get. It self-corrects without anyone having to manage it.

Member submits movie → enters pool with their lottery weight
           ↓
      Weighted lottery runs at pick time
           ↓
      Movie becomes the current pick
           ↓
      Members vote after watching
           ↓
      Movie moves to history, AI summary generated
           ↓
      Suggester's weight resets, others' weights increase

There are also Side Quests: optional suggestions for theater showings or watch parties that sit outside the main lottery. They don't cost slots and they don't affect weights. They're just there for when someone wants to organize something on the side.

If a member really wants their movie picked and can not wait for the lottery, they can spend an override. Overrides are a limited resource. Using one drops your lottery weight significantly and boosts the previous pick's suggester as compensation. It's a pressure valve, not a cheat code.


Voting

After the group watches a film, members rate it across six categories:

  • Story and Entertainment - the baseline. Did it work as a movie?
  • Acting - performances specifically
  • Technical Craft - cinematography, editing, sound, score
  • Emotional Impact - did it make you feel something?
  • Rewatchability - would you sit through it again?
  • Would you Recommend - Would you tell someone else to watch it?

The overall score is a weighted average of those six, with story, acting, and technical craft contributing more than rewatchability and whether or not you would recommend it. Members can also leave a written review. Other members can react to reviews with a thumbs up or down.

Breaking the rating into categories was the right call. A single star rating flattens everything. With six categories you can see that a film scored high on acting and low on rewatchability, or that a fun popcorn movie rated poorly on technical craft but everyone enjoyed it anyway. The data is more honest and it makes for better post-watch conversations.


The AI Features

This is where it gets interesting.

Consensus summaries. When voting closes on a movie, the app automatically generates a short summary of what the group thought. It reads all the written reviews and scores, calculates the participation rate, and produces a two or three sentence paragraph that captures the group's actual reaction. Where opinions aligned, where they split, what the outlier takes were. This runs in the background via Celery, a task queue that handles deferred work without blocking the app. Every watched film now has a permanent group summary attached to it, written from the actual votes rather than anyone's memory of the conversation.

Personalized recommendations. Each member gets an AI-generated movie suggestion based on their own voting history. The system analyzes your scores across all six categories and looks for patterns. If you consistently rate emotional impact high, if you tend to dock points for weak technical craft, if you reliably deviate from the group on a particular type of film, the recommendation factors all of that in. It also knows what the club has already watched, so it will not suggest something you have already seen. The recommendations are validated against TMDB before being saved, so hallucinated film titles get discarded automatically.

Club identity. Separately from individual profiles, the app periodically generates a portrait of the club as a whole. It looks at the last six months of watches and reviews and produces a candid description of the group's collective taste: what it gravitates toward, what it consistently underrates, where its blind spots are. This is less about utility and more about making the data feel alive. It's interesting to read.

All three features run on Groq, using a large language model (llama-3.3-70b) under the hood. The prompts are tuned to avoid hype language and to make specific observations with references to actual films the club has watched.


Stats

Once you have 24 movies of structured voting data, the statistics become genuinely interesting.

The stats page tracks things like:

  • Highest and lowest rated films in club history
  • Most divisive film, calculated by standard deviation across voter scores
  • Most contrarian voter, meaning the member whose scores diverge furthest from the group average on a consistent basis
  • Genre breakdown with average ratings per genre
  • Decade distribution across all watches
  • Per-category averages (who are we as a group when it comes to technical craft?)
  • Longest review ever written, with word count and link to the original
  • "Luckiest" member: whoever has received the most bonus slots from wildcard picks

The stats recalculate automatically if they're more than six hours stale, and there's a manual refresh for managers who want fresh numbers on demand.


Other Features

Oscar predictions. Before awards season, managers open a bracket with nominated films per category and configurable point values. Members submit their picks. Once winners are announced, the app scores everyone and produces a leaderboard. The member with the most correct picks earns a movie override.

Challenges. Any member can create a curated list of films around a theme and invite others to work through it. Challenges use the same six-category rating system and rank all films in the list by average score once members have voted.

Forum. Every main pick and side quest automatically gets its own discussion thread when it goes live. There is also a general forum with categories. Threads support nested replies, reactions, pinning, and locking.

Membership tiers. Full members are expected to vote. Three missed votes generates a strike, and three strikes downgrades a member to casual. Casual members can still watch and vote but their lottery weight is reduced. Guests can join for a single film with no obligations. The tiers exist to keep the full-member pool honest without making participation feel punishing.


Architecture Notes

The app runs on Django 5. Movie metadata comes from The Movie Database API. Background work, including AI generation, stats calculation, voting reminders, and Discord announcements, runs through Celery with Celery Beat for scheduled tasks. The frontend uses Tailwind CSS. The whole thing is deployed via Docker Compose.

For non-technical readers: Django is the framework that handles the web server and database. Celery is the system that runs slow or scheduled tasks in the background so the app stays fast. Tailwind is a CSS tool for styling. Docker packages it all up so it runs the same way on any server.


What It Does Now

The club has watched 24 movies in four months. The lottery has run cleanly every round. The AI summaries have generated for every watched film. The stats page has enough data to tell you things about our collective taste that nobody consciously knew before, like the fact that we are more forgiving of genre films than their critical reputation and that our most consistent contrarian almost always rates emotional impact lower than the group.

I started building this because a spin wheel was not good enough. It turned into a full-featured application with a lottery system, a structured voting model, AI-powered analysis, a forum, Oscar brackets, and a stats engine with forty-plus calculated metrics.

The spin wheel was fine. This is better.