watwa.re

How we built mietencheck.de

In the spring of 2023 my good friend Jonas and I were wondering how we could use our tech bro powers to solve a societal issue with a technical solution lol.
No wait, ChatGPT can you rephrase that without the cyncism?

...we could leverage our combined tech skills to address a societal issue with a meaningful technical solution.

Hrmph, that just made me more cynical 🫥

Anyway, point is: the rents are too damn high in metros like our Berlin, and until we figure out how to build enough housing or improve taxation, we'd prefer rents for existing housing to be affordable by non-tech bros' & sis' as well.

Germany has rent control for tight housing markets on a federal level, also known as die Mietpreisbremse (internet ❤️ germancompounds). The details of how rent is calculated depends on your local state, but with the result of the calculation you have the backing of the law to annoy your landlord.
Berlin had an automatic version of that for a good year, called der Mietendeckel, where you did not have to start the fight yourselves, landlords were legally bound to set the price right. Unfortunately good state UX is against the german consitution, so it was ruled unlawful and we're back to the Mietenbremse.

Our idea was to improve the Mietpreisbremse process by automating lookups of relevant data, unifiying various forms and simplifiying/streamlining the questions asked. Jonas was (and still seems to be) keen to dive into all the relevant forms, legislation and clarifiying court documents. In the begining I was also supporting that process where I could, which lead to Ship of Theseus-adjacent discussions about questions like "What is a bathroom?".

Towards the end of 2023 we united forces with Deutsche Wohnen & Co. enteignen (DWE), a grassroots initiative that created a referendum for expropriating large real-estate companies. The result: 60% public support with high voter turnout. The senate ignored the result, thus the initiative is still active and seeking a second, legally binding, referendum.
DWE had been working on a similar solution to ours, but had just started. So we onboarded their volunteers to our project, increasing our team size and our legal literacy.

The fruit of our collective labor is mietencheck.de, which you should check out if you're renting in Berlin.


An early topic of conversation for this project was our astonishment about the lack of tooling for creating complex conditional forms. There are a plethora of form builders, but conditional questions are often an afterthought with clunky UI.

We tried to do better in our code, by keeping the flow of questions, and their conditionality clear and declarative. Initially we expressed this by nesting React elements like so:

<>
  {contractDateRange == "uncertain" && [
    <FormStep
      key="contractAfter2015"
      field="contractAfter2015"
      label="Did you sign the rental agreement after June 1, 2015?"
    />,
    values.contractAfter2015 == "no" && <Exit />,
  ]}
  {values.isSigned == "no" && (
    <FormStep
      field="netColdRent"
      label="What is the net cold rent per month in euros?"
    />
  )}
</>

At some point it became clear that we needed to inspect the list of displayed questions to do things like showing an overview of what has been answered so far. So we switched to our own data structures:

const runFlow = (v: FormValues): Flow => [
  field("address"),
  !v.address?.rentIndex && exit("rent-index-missing"),

  field("isSigned"),
  v.isSigned == "yes"
    ? [
        field("contractDateRange"),
        v.contractDateRange === "before2015" && exit("new-rent"),

        v.contractDateRange === "uncertain" && [
          field("contractAfter2015"),
          v.contractAfter2015 == "no" && exit("new-rent"),
        ],
        field("rentType"),
        field("netColdRent"),
      ]
    : field("netColdRent"),
];

This kept us going for a few months but trade-off frustrations amounted:

  • 🎉 we separated question conditionality from the actual text of the question and its answer choices to improve high-level clarity
    • 👎 thereby adding a layer of indirection to most edits
  • 🎉 we made it easy to use all of JS' conditionality operators
    • 👎 complex nested conditions still lacked clarity

Meanwhile our primary source of truth, the design in Figma, was laughing at us with its supreme 2 dimensional clarity.

A flowchart connecting various questions around renting

This would be a perfect on-ramp for a rant about the inadequacy of code and its one-dimensionality but we did something better than rant: We built the tool we were yearning for.

Floma (short for "flow machine") is a web-based editor for creating conditional question-answer flows and a JS runtime for executing those flows. With it more people than just developers, can edit the contents and flow of conditional forms. It provides greater legibility than code and thus became our single source of truth, replacing our beloved hand-crafted diagrams.

A flowchart connecting various questions around renting

Since Floma is neither intended to be a UI builder nor a full-fledged general purpose no-code environment, we put an extra emphasis on interop by having it output the flow as a JSON that can be easily embedded into existing applications with our small (~5kb) JS runtime. Next to it, it also generates TypeScript types with all the questions and their possible answers, to ensure smooth and safe interop.

If your kink for the german language has not been exhausted yet, you can check out our german-only (for now) landing page for Floma, and hear me talk about it. I am happy to do personal explanation/onboarding calls in a language of your choosing, so please reach out if you have a use-case, know of one or are just curious to learn more.