Projects
Each of these has a demo you can click around in. They use made-up or anonymized data, so nothing private is exposed. If the code is private, I’m happy to walk you through it.
Song Rank
Jul 2026 · Solo projectAn analytics site for a yearly song-ranking party: leaderboards, awards, taste comparisons, and a slideshow for the reveal.
- Reads each year’s score sheet (about 380 songs over four years, and thousands of scores) and works out every stat in the browser.
- Uses correlation to show whose taste lines up with whose, then breaks that down to the artists behind it.
- Recounts the votes a few different ways (Borda count, median, trimmed mean) to see how much the method changes the winner.
- Before every release, it compares its numbers with the group’s own spreadsheet analysis, and all 1,205 comparisons match.
- The public version swaps out everyone’s names but keeps the real scores.
Product Monitor
Jun 2025 – now · Solo projectA 24/7 bot that posts new products, restocks and sell-outs from two online stores to several Discord servers, backed by a SQLite database I designed.
- Each server chooses where alerts go and which product lines it follows, and members can opt in to a ping for the lines they care about.
- I moved its data out of JSON files and into a SQLite database with about 20 related tables. Before switching over, the migration compared record counts for every table.
- It backs up to AWS S3 during the day. Once a month it restores the newest backup and makes sure it opens cleanly.
- It records when each product first appears on each page of the store. I used SQL on that history to decide which pages the bot should check first.
- Around 970 automated tests.
Language Study Bot
Dec 2025 – now · Built with a second developerA bot that keeps our Japanese study group on track with stats, streaks, daily recaps, and LLM-written reminders.
- Pulls each member’s progress from WaniKani, the kanji-learning site we use, and only asks for what’s changed since last time.
- Recreates WaniKani’s streak rules, including the “offerings” that save a missed day, so our streaks match the ones on the site.
- Stores everyone’s API keys encrypted and uses each person’s own time zone. Changes to its 35-table database go through small migrations.
- An LLM writes the reminders in Japanese using only kanji the person has already learned. If the API is down, it sends a plain message instead.
- Built alongside a second developer through pull requests, with 26+ merged so far.
Listening Stats
Sep 2026 · Solo projectA self-updating YouTube Music history and a dashboard that tracks skips and listening time more accurately than most play-tracking tools.
- Imports my full history from Google Takeout once, then checks for new plays every 20 minutes.
- Counts a song as skipped if the next one starts too soon, and only counts the time I spent listening.
- When a newer Takeout export comes in, it replaces the estimated plays with the exact ones, so nothing gets counted twice.
- The dashboard covers streaks, listening sessions, what time of day I listen, when I found each artist, and old favorites I’ve stopped playing.
Flight Price Monitor
Apr – Sep 2026 · Solo projectTracks award points and cash fares for saved trips, alerts on new lows and target prices, and limits smaller drops to one alert a day.
- It follows four alert rules that I wrote down and tested. A new all-time low always alerts, a target price alerts once when it’s crossed, small drops wait 24 hours, and a brand-new watch stays quiet.
- Plans its requests around each data source. Award prices come back for a whole date range in one call, while cash fares have to be fetched one date at a time, three seconds apart.
- It started out as a Discord bot. After using it for a while, I rebuilt it as a small web app around the parts I needed.
- It has 225 automated tests, and they all run without an internet connection.
Holodle
May – Aug 2026 · Solo projectA Wordle-style daily game played as a Discord Activity, with live progress from everyone playing.
- All the grading happens on the server, so there’s no way to find the answer in the browser. Other players see your colored squares but not your guesses.
- The admin page measures how much each clue helps players narrow down the answer in real games, and a solver suggests the best next guess.
- Each day’s answer is picked so recent ones rarely repeat, and the day rolls over at midnight wherever you are.
- About 176 automated tests. It runs for free on a small cloud server.