Zach Allaun

Hi, I'm Zach. I'm a programmer, industrial designer, and machinist. Those last two started as a hobby, designing and building mechanical keyboards, but turned into a profession when I co-founded Keycult.

This site is a collection of things I've worked on professionally and in my free time. It's not exhaustive — just some highlights.

Mneme — Snapshot Testing in Elixir

The basic idea of snapshot testing is that you run some piece of code and then capture its result, saving it somewhere so that it can be compared to later. Many snapshot testing libraries hide those results away, e.g. in a /snapshots folder. Mneme takes a different approach that is more idiomatic to Elixir: instead of hiding the result, Mneme patches test files directly.

I like to think of Mneme as a sort of "persistent REPL" that allows you to tinker with code and quickly see and verify the output, while still winding up with useful tests at the end.

For instance, here's what a new test might look like:


test "creates a new user with valid params" do
  auto_assert Accounts.create(@valid_user_params)
end
      

The first time this is run with mix test, you get a prompt in your terminal to update the assertion. If you accept, your test is automatically patched to look something like this:


test "creates a new user with valid params" do
  auto_assert {:ok, %Accounts.User{}} <-
                Accounts.create(@valid_user_params)
end
      

This pattern asserts that a user is created and returned (inside an :ok tuple), but doesn't assert anything about that user's attributes, so the test doesn't start failing if you add or remove attributes.

Here's a 1-minute demo of the workflow:

All the examples above use auto_assert, but the library also auto_assert_raise to capture exceptions, auto_assert_receive(d) to capture messages in the process inbox, and an experimental test-runner, mix mneme.watch, which re-runs tests when files are saved.

Structural Diffing

You can see this in the demo above, but Mneme also includes custom, structural diffing that only highlights semantically meaningful changes in your code (in contrast to the usual line- or word-based diffs you see using tools like git). This approach is heavily inspired by Difftastic.

I'd like to eventually ship this as a standalone library.

Lexical — Various contributions

Lexical is a language server for Elixir that I've been contributing to since mid-2023. (Language servers power almost all of the "intellisense" features in modern editors.)

Drawing system on keycult.com

Keycult has always been limited by production capacity, meaning we have fewer keyboards to sell than customers who want to buy them. That's a decent problem for a business to have, but it leads to unfortunate consequences like people buying things just to resell them.

To tackle this, keycult.com, which is hosted on Shopify, proxies certain URLs to an Elixir/Phoenix backend that implements a custom drawing system. Customers can register and fill out some personal details to be automatically registered for drawings. When we have stock available, we randomly issue "tickets" (that last 24 hours) to customers, who can then buy a keyboard kit or choose to pass if what we have isn't what they're looking for.

Janus — Authz for Elixir

Janus is an authorization library for Elixir that I'm using on Keycult's backend.

There are two really common authorization actions:

  1. checking whether an actor can perform some action on some resource
  2. loading all the resources an actor can perform some action on

When I wrote Janus, there wasn't an Elixir library that let you perform both of those with a single set of rules, and I didn't want duplicate authorization logic.

Janus integrates with Ecto, a toolkit for data-mapping and database interaction that nearly everyone using Elixir uses, and allows you to perform both of the actions above using a single set of rules defined using basic functions.


# build the policy for a user with the `:moderator` role
def build_policy(policy, %User{role: :moderator} = mod) do
  policy
  |> allow(Post, :read)
  |> allow(Post, [:edit, :archive, :unarchive], where: [user: [role: :member]])
  |> allow(Post, [:edit, :archive, :unarchive], where: [user_id: mod.id])
  |> deny(Post, :unarchive, where: [archived_by: [role: :admin]])
end

# elsewhere, use the policy to load and authorize resources
Policy.authorize(some_post, :archive, moderator)
#=> {:ok, some_post}

Policy.authorize(post_archived_by_admin, :unarchive, moderator)
#=> {:error, :not_authorized}

Policy.scope(Post, :read, moderator) |> Repo.all()
#=> [ ... posts the moderator can read ]
      

CNC machining

In order to bring manufacturing in-house, we've been consistently expanding our machining capabilities at Keycult for years.

What started with a foam-cutting CNC router that we assembled ourselves ended in a massive horizontal machining center.

Ciphercult — Cipher card

I designed a physical, collaborative, community challenge that I referred to as a cipher card. It was two-sided, cast-bronze, enamel infilled, and the size of a playing card. One side was (seemingly) decorative, while the other was a large grid of 100+ letters and numbers.

We had 100 of them produced and sent them out randomly over the course of a month or so. People flocked to a Discord server to work together, figure out the cipher, and decode each individual card as they cropped up (each one was unique). Definitely the most fun community-oriented project I worked on for Keycult.

Keycult No. 1 (private community group buy)