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! ☕


Feeling Bitter, Looking Better

There is a new chart option inspired by this GitHub issue about showing temperature together with the other curves: if you want to see temperature overlaid on the main chart instead of split out on its own, you can now enable that in your profile settings. The separate temperature chart remains the default, but I know some of you prefer having everything in one place.

I also added bitterness to tasting assessments, following some very sensible observations on the scoring metrics. Leaving it out felt more and more silly the longer I looked at it. That gives you 8 dimensions total and makes the whole thing feel more complete and balanced.

Then there was a request to also copy taste rating and coffee grams when copying from previous shots. After the initial straightforward implementation, I got a few reports about drink weight changing when copying values from another shot and drink weight being overwritten during copy, so I refined the whole thing a bit more. Rollbacks are clearer now, and imported shot weights should no longer get accidentally overwritten when copying details from another shot.

There were several API and security improvements too. Private notes are now available via the API, the API authentication is properly stateless now, and the docs mention rate limits and response formats much more clearly. 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 have a great week! ☕