A Richer Note Taking Experience

It has not been long since the last update, but I have already shipped another substantial change: notes in Visualizer now use a proper rich text editor.

Until now, bean notes, espresso notes, private notes, and coffee bag notes were plain text fields with GitHub Flavored Markdown support. Markdown is great if you already know it, but it is not exactly welcoming when you just want to make something bold, add a link, or create a list.

Those fields now use Lexxy, a modern rich text editor built on Rails Action Text. You can format text directly, add headings, links, tables, lists, quotes, and code blocks, and see the result while you write it.

Existing notes were migrated automatically, including their Markdown formatting, so nothing should be lost or suddenly appear as raw syntax. The same editor now powers these update posts too, which made this post a convenient real world test. 😅

One important change for Airtable users: notes are still sent from Visualizer to Airtable as plain text, but edits made to notes in Airtable no longer sync back. Airtable does not support the same rich text format, so syncing them in both directions would lose formatting and create incompatible results.

There were also several smaller fixes around dark mode, copied shot values, coffee bag forms, code highlighting, and displaying rich content consistently across the app, plus a bunch of other changes.

As always, bug reports and feature requests are very welcome on GitHub. This change touched quite a few places, so please let me know if any existing notes look strange.

Thanks for reading, and enjoy the rest of your weekend! ☕


Tag, You're It

Long time, no update! I spent almost a month in Japan, so things were a little quieter around here after the last update.

The good news is that Visualizer kept running smoothly while I was away. There were no reported incidents, which is exactly what I hoped to see while checking in from the other side of the world. 🥳

I did not stop working completely, though. The biggest visible addition is filtering shots by tags. If you use tags as a Premium user, they now appear alongside the other Instant Filters, so finding every shot made with a particular basket, grinder speed, recipe variation, or anything else you track should be much easier.

Tag filtering is also available through the API, which should make it easier for integrations to retrieve a precise group of shots without downloading everything and filtering it themselves.

The API got quite a few other improvements too. There are now endpoints for searching canonical roasters and coffee bags, shot results can be filtered by when they were updated, and list responses include a little more useful context. The Coffee Management API was cleaned up as well.

There was also an interesting discussion in the Decent community about temperature goals from the newer Decent app. The original DE1 app reports the basket temperature goal, while newer integrations can also report the mix temperature the machine is targeting to achieve it. These are two different values, which made some charts look confusing when only one goal was shown.

Visualizer can now display both the basket and mix temperature goals. I also added support for sending that extra data to Reaprime. Other integrations might start providing it in the future, so the chart support is now ready for them.

There were plenty of other changes too. Transient web push failures are now retried instead of immediately giving up. I also fixed TCL profile exports with spaces around special characters, which could previously produce files that Tcl could not read back correctly.

I removed the Decent API integration that synced machine serial numbers to Visualizer. The API has not changed or gained any useful features in a long time, and at this point it looks abandoned. There was little value in maintaining an entire integration just to sync serial numbers, so I removed it. This does not affect Decent shot uploads, which still work as before.

I also updated Visualizer to Ruby 4.0.6, refreshed dependencies, and made a bunch of other smaller changes.

I am working on a few other things now, but as always, bug reports and feature requests are very welcome on GitHub. They help me understand what actually gets in your way, and they very often end up shipped.

Thanks for reading, and enjoy the rest of your week! ☕


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