Blog
2026-07-27
Sprint 14 Closes: A Second Opinion Pauses the Badge Work to Harden the Session Layer First
The next thing on the board was milestone badges. Before picking it up I had the whole codebase looked at with fresh eyes, and the review found real holes in how sessions and confirmations were protected. So the badges went back on the shelf, a hardening sprint got slotted in ahead of them, and four fixes plus one refactor shipped before any more feature work. Then badges resumed, on a cleaner foundation than they'd have had otherwise.
2026-07-27
Sprint 13 Closes: Milestone Badges, and the Difference Between Earning Something and Just Having It
The badge sprint had been sitting half-finished since before a hardening detour bumped it aside. Picking it back up meant deciding what actually counts as a moment worth celebrating, catching a wrong number in my own writeup before it shipped, and chasing down a ghost bug that turned out to be nothing more than a stale file.
2026-07-26
Sprint 12 Closes: The Pipe Carries Its First Real Message, and the Owner Gets a Second Dashboard
Last sprint built a delivery pipe and proved it with a test message nobody actually needed. This sprint sends the first real thing through it — a beer you saved is on tap tonight — and separately gives the tavern owner a screen for the question the day-to-day dashboard was never built to answer: who's about to lapse, and what does everyone actually want.
2026-07-26
Sprint 11 Closes: Building the Whole Notification Pipeline Before There's a Single Notification to Send
Web push needs a service worker, a place to store subscriptions, an opt-in, and a background job to do the sending — a lot of plumbing for a sprint that, in the end, sends exactly one thing: an admin test message to prove the pipe holds. Also: the stacked pull request that auto-closed its own next step the moment I merged the first one, and why a phone on the café Wi-Fi still won't get a notification.
2026-07-25
Sprint 9 Closes: Rebuilding the Confirmation Flow, and Finally Fixing the Bug Left Broken on Purpose
The sprint that came out of last session's UX pause is built and shipped: format-based credit, a queue instead of one PIN entry per beer, self-serve catalog entries, a two-tab nav, and a new anomaly signal — plus an automated review pass that caught six real bugs before any of it merged.
2026-07-25
Sprint 10 Closes: My Beers Ships, and a Merge-Day Lesson in What 'Independent Branches' Actually Means
The screen the last few sprints kept promising is real: a completed list, a want list that survives a whole confirmed round, and a personal stats page. Also: three branches that never touched a single line of each other's code still managed to collide the moment they all tried to merge.
2026-07-24
Sprint 8 Closes: Eight Small Fixes, One Bug the Test Suite Was Structurally Unable to Catch
Eight independent admin and engagement UX fixes, shipped as eight separate pull requests instead of one bundled sprint — and the moment writing microcopy for one of them surfaced a real 500 error that every unit test in the project had been quietly incapable of catching.
2026-07-24
Pausing Sprint 9 for a UX Brainstorm — and Why That's the Agile Move, Not a Detour
A one-line login bug and a bigger question about the core flow surfaced from live use on the same day. Instead of patching the bug and moving on, development stopped entirely for a structured discovery session — and the sprint that came out the other side replaced the one that was already scoped.
2026-07-24
Grooming an Epic Too Big for One Sprint: My Beers, Push Notifications, and What Stayed Off the Board
The next epic on the roadmap — badges, push notifications, a full My Beers screen, a social layer — is bigger than anything scoped so far. Rather than ticket the whole thing in one pass, only two of its five natural phases got turned into real GitHub issues.
2026-07-23
Stress-Testing Five 'Done' Sprints Before Writing Sprint 6
Five sprints all shipped green. Then I actually used the product like an owner and a customer would, and found twelve real gaps a passing test suite had no way to see — plus two architecture questions I'd been quietly avoiding.
2026-07-23
Sprint 7 Closes: Letting Customers Search Outside the List, and Learning From What They Ask For
Beer Discovery & Recommendations reuses two admin-only integrations from Sprint 3 as a rate-limited customer feature, adds a lightweight request-and-triage loop, and turns every logged search into a signal about what the tavern's catalog is missing.
2026-07-23
Sprint 6 Closes: A Bottom Tab Bar, an Account Hub, and Setting Up a Browser to Check My Own Work
Six small UX fixes, all frontend-only, closed in one pull request — plus the moment a green test suite wasn't enough to actually trust the nav bar, and I installed a real browser on the spot to prove it, after being pushed to do it before merging rather than just flagging the gap.
2026-07-23
Sprint 5 Closes: One Audit Trail, Three Screens, and the Bugs You Only Find by Using the Thing
Seven issues, seven pull requests, one shared audit pattern reused three times instead of rebuilt three times — plus a crash that only showed up because I actually logged in as the admin I'd just built the screen for.
2026-07-23
Sprint 4 Closes: Social Sign-In, Password Reset, and the Cost of Doing Auth Right
Seven issues, six pull requests, three OAuth providers sharing one decision engine — and the two design problems that don't show up in anyone's OAuth tutorial: what happens to a customer's mug club history when they ask to be forgotten, and how you attach a second sign-in method to an account without ever putting a bearer token in a URL.
2026-07-23
Grooming Sprint 5: Turning the Backstop Into a Real Admin Experience
Seven more issues, zero lines of code — but this time the scoping problem wasn't sequencing new work, it was figuring out how much of the sprint already secretly exists.
2026-07-23
Five Sprints In: A Post-Mortem on the Bugs the Tests Didn't Catch
236 backend tests, 149 frontend, all green, all written before the code they test. None of that is why the real bugs got caught. This is a look back at what actually went wrong across five sprints, and the pattern underneath all of it.
2026-07-21
Sprint 3 Closes: Search, Real Beer Data, and a Phone That Actually Works
Seven stories: a search-first beer list, two external data integrations built the same resilient way, a hit-rate spike that earned its name, and a mobile UX sweep that closed gaps the nav alone couldn't hide.
2026-07-21
Grooming Before Coding: Scoping the Beer App's Auth II Sprint
No code shipped today. Just seven GitHub issues — and the discipline of deciding what those issues are before writing a line of the sprint they describe.
2026-07-15
Turning Comments On: The Last Mile Is Configuration
The comment system was fully built a week ago, but nobody could use it. Enabling it took zero code changes. Here's what the last mile actually looked like.
2026-07-15
Sprint 2 Closes and the Mug Club Epic Is Done
Seven items, two of them unplanned interrupts, and the beer app's core promise is now fully built: lockout, PIN lifecycle, a permanent mug award, and an audited fix path for bar mistakes.
2026-07-15
Designing PIN Lockout for Someone Else's Phone
Sprint 2 of the beer app is underway: the registration fix shipped after a mid-story pause that cost nothing, and the first groomed story asked a genuinely interesting security question.
2026-07-15
Comment Moderation and Rate Limiting: Closing the Loop
Comments went live with two known gaps: no way to delete spam without raw SQL, and nothing stopping rapid-fire submissions. Here's how I closed both.
2026-07-14
Shipping the Mug Club Core Loop
One session, two hats: a feature storm got turned into a plan of record, a design assumption got overturned mid-flight, and then Sprint 1 shipped — the bartender now signs the customer's phone with a six-digit PIN.
2026-07-14
Live Testing and Triage: Feeding Real Feedback Into the Sprint
I used the beer app the way a customer would and found three problems the docs never mentioned. Here is how each one got triaged, and what a green CI pipeline failed to tell me.
2026-07-13
Running the Beer App Like a Real Agile Project
After merging the foundation work, I set up epics, sprints, and a session log for a solo project instead of just diving into the next feature.
2026-07-13
Re-Planning the Beer App Around the Customer's Phone
A code audit confirmed what I suspected: the app I built is an admin catalog, not something a customer would use at the bar. So I stopped and re-planned it.
2026-07-13
Refactor Milestone: Making TDD Real
This was supposed to be a TDD project from the start. It wasn't — there wasn't a single test anywhere in the repo. This session backfilled a real suite, wired CI to enforce it, and cleaned up two years of accidentally-committed build output along the way.
2026-07-13
Refactor Milestone: Hardening the Foundation
Before building the mug club feature, I found three real gaps in the beer app's foundation: no database migrations, no seed data, and roles that existed on paper but weren't enforced anywhere.
2026-07-08
Refactor Milestone: A Mobile-First Starter
The first milestone of the refactor is now in place: a mobile-first shell, auth flow, and API foundation.
2026-07-08
Why Technical PMs Should Get Hands-On With AI Tools
A short case for why project managers shouldn't just consume AI-generated reports. They should understand how the tools work.
2026-07-08
A Follow-Up: The Resume PDF Links Needed the Same Fix
I fixed external links to open in a new tab and missed the two 'Download PDF' buttons. Here's the fix, and why the distinction matters.
2026-07-08
Making Every Off-Site Link Open in a New Tab
A small usability fix with two different implementations, depending on whether the link came from markdown or from a React component.
2026-07-08
How I Added Comments with Neon Postgres and Cloudflare Turnstile
A build log and step-by-step guide for adding a database-backed comment system to a Next.js blog, with bot protection that doesn't get in the way.
2026-07-08
Building a Beer Catalog Refactor
How I started turning an old ASP.NET MVC app into a modern, mobile-first product with a new frontend and backend stack.
2026-07-01
Welcome to My Corner of the Internet
Why I built this site, and what I plan to write about here.