Fresh Shots in Your Inbox

It is a turbulent world out there. Lots of things are happening all the time, so even though I have not posted anything since the last update, that definitely does not mean nothing happened.

A surprising amount of maintenance time now goes into keeping an eye on AI-related vulnerabilities, supply chain attacks, CVEs, dependency releases, runtime updates, and all the other boring but important things that keep Visualizer running safely. Not very glamorous, but absolutely necessary.

There was also one notable downtime incident. On April 22, Visualizer was down for about half an hour because of issues with the hosting provider. The database was unreachable during a Hetzner outage, and there was not much I could do except monitor and wait for things to recover. If you want more background, there was also a Reddit thread about Hetzner cloud leaf faults. Sincere apologies to everyone affected!

On the more user-facing side, Visualizer now has email notifications for new shot uploads in addition to the existing push notifications. Because I need to pay for email delivery, these are disabled by default and limited to Premium users. To put it in prespective: just 2 weeks ago there was a new record: 23,227 shots uploaded in a single week. 🤯

There were also some parser and chart improvements. Visualizer now parses Beanconqueror water dispensed data for Sanremo YOU exports, and I fixed a water flow timing issue in that same area. I also fixed temperature graphs using a full 0 to 100 scale instead of a useful range, which made the temperature line look almost flat. Dual axis charts also align zero thresholds more sensibly now.

Coffee Management got a few smaller improvements too. Active coffee bags are sorted ahead of frozen ones in the shot edit dropdown, and the coffee bag combobox now preserves the original ordering where that matters. The Loffee Labs importer was also updated to their new API.

I also finally fixed passkey login not prompting for Bitwarden. That one has been open for a while, and passkeys are one of those features where browser support and authenticator behavior can be surprisingly fiddly, but it should behave much better now.

Behind the scenes, Visualizer moved through Ruby 4.0.3, 4.0.4, and 4.0.5, got a Rails security bump, a refreshed Dockerfile, Bootsnap frozen strings, dependency updates, some Postgres tuning, and a bunch of other small changes.

As always, if you run into bugs or have ideas for improvements, please keep opening GitHub issues.

Thanks for reading, and enjoy your weekend! ☕


More Clear, Less Weird

This one is more of a smaller polish update, but there have still been quite a few changes since the last update.

The most visible one comes from a GitHub request about confusing comparison labels. In shot comparison, “left” and “right” are now called base and comparison, which should make more sense when you are actually trying to compare two shots and reason about what changed.

There was also a fix for temperatures showing in Celsius when they should have been Fahrenheit. Small bug, but definitely the kind that can make charts feel much more confusing than they should be.

I also spent some time improving passkey support. Unsupported browsers should now fail more gracefully, duplicate passkey registration is handled properly, and a few WebAuthn edge cases no longer dump you into vague error states.

Coffee bags got a bit of cleanup too. I moved some fields around, simplified some of the form behavior, and generally tried to make editing coffee bag details feel a bit more natural.

Behind the scenes, I switched Visualizer over to Action Policy, added active_job-performs, bumped Postgres to 18.3, and pulled in the usual dependency and security updates. If you want all the nitty gritty details, here is the full diff.

As always, if you run into bugs or have ideas for improvements, please keep opening GitHub issues.

Thanks for reading, and enjoy in what’s left of the weekend! ☕


The Scrape Escape

I hope you had a lovely weekend filled with some great coffee. Mine was a bit less lovely, because I spent a good chunk of it learning just how many websites now block scraping and crawling thanks to the flood of AI bots.

This matters for Coffee Management, because when you paste a coffee URL into Visualizer and ask it to import the details with AI, I want that to work as often as possible.

With the new changes the scraper still tries the old, simple approach first. But when that fails, Visualizer now falls back to Crawlbase, which can fetch the page through a real browser. That is much more reliable for blocked sites, but it can also take much longer. This longer runtime broke the existing approach I had, because the request would time out. So I was forced into switching the whole approach by using websockets via Action Cable.

The good news is that this actually made the whole feature much better. Instead of quietly doing mysterious things in the background while you watch the little animated logo, Visualizer now tells you exactly what it is working on. You can see it step through fetching the page, retrying in browser mode if needed, extracting the useful bits, and finally applying the results.

Another nice quality of life improvement: the PWA, when you save Visualizer to your phone home screen, now supports pull to refresh on the shot list. Small thing, but very handy if you use Visualizer on your phone and want that app-like feel.

I also spent some time rewriting the homepage and Premium messaging. No new features there, but I wanted the site to better reflect what Visualizer actually is: a place to keep useful coffee data in one place, learn from it, and brew better coffee because of it.

As always, if you run into bugs or have ideas for improvements, please keep opening GitHub issues. I really do read them all, and they very often end up shipped. And if you want all the nitty gritty details, here is the full diff.

Thanks for reading, and have a great week ahead! ☕