Direkt zum Inhalt

Artikel · Entwurf

Vom Idee-Sketch zur Plattform: die Log+Key-Architektur, sieben Jahre später

Log+Key sollte eine kleine Inventar-Web-App werden. Wir haben uns gegen Monolith, gegen Microservices und gegen schicke Frameworks entschieden — und sind stattdessen bei einer ganz simplen Trennung gelandet, die seit sechs Jahren trägt.

Dominik Knipprath 11. Juni 2026 5 min Lesezeit

Wenn ich heute mit anderen Teams über Plattform-Architektur rede, kommt früh oder spät die Frage: “Was würdet ihr machen, wenn ihr Log+Key heute neu starten würdet?” Und meine ehrliche Antwort ist: ziemlich genau das Gleiche.

Das ist deswegen überraschend, weil zwischen “wir entscheiden über den Stack” und “wir betreiben das jetzt seit sechs Jahren produktiv” sehr viel Software-Trend liegt. Microservices. GraphQL Federation. tRPC. Edge Functions. Serverless Postgres. Wir haben jedes davon evaluiert — und uns dagegen entschieden.

Was uns trägt, sind drei ziemlich konservative Entscheidungen, die wir im Sommer 2018 in einem Café in Aachen auf eine Serviette gemalt haben.

Entscheidung 1: Headless-CMS als Datenmodell-Schicht

Die erste Entscheidung: wir bauen das Datenmodell nicht in Code, sondern in einem Headless-CMS.

Damals war das Directus, das gerade von Version 7 auf 8 wechselte (heute sind wir bei der aktuellen Linie). Die Begründung war banal: Inventar-Software bedeutet, dass jede Organisation ihre eigenen Felder, Kategorien, Workflows, Berechtigungsmodelle braucht. Wenn wir das in Code verdrahten, baut sich alle drei Wochen ein neues “Special Feature für Kunde X” auf, das nicht in den Mainline-Branch passt.

Mit Directus als Datenmodell-Schicht kriegen wir:

  • Pro Kund:in eigene Custom-Felder, ohne Code-Branch.
  • Permissions per Rolle, konfigurierbar im Admin-UI.
  • Versionierte Schemas, wenn das Modell sich weiterentwickelt.
  • Eine REST- und eine GraphQL-API “for free” — wir mussten nie eine eigene API-Schicht schreiben.

Was wir uns damit eingehandelt haben: Directus ist nicht ein generisches PostgreSQL-Schema. Es ist ein Meta-Schema, das auf PostgreSQL aufsetzt. Wenn wir performance-kritische Abfragen schreiben, müssen wir manchmal an Directus vorbei direkt auf die DB gehen. Das passiert selten — aber es passiert, und es ist die einzige Stelle, an der die Architektur einen “Pfui-pfui-aber-pragmatisch”-Charakter bekommt.

Die alternative Welt — selbst gebautes Datenmodell in NestJS oder Laravel oder Rails — wäre für die ersten 6 Monate schneller gewesen. Aber wir wären jetzt nicht bei 70 Kund:innen mit individuellen Feldern. Wir wären bei 6 Kund:innen mit einer komplizierten Forks-Geschichte.

Entscheidung 2: Frontend als statischer Nuxt-Build pro Kund:in

Die zweite Entscheidung: wir bauen kein klassisches SaaS-Frontend, bei dem man sich einloggt und seine Subdomain bekommt. Stattdessen bekommt jede Kund:in einen eigenen, statisch gebauten Frontend-Build, der gegen ihre eigene Directus-Instanz läuft.

Das klingt umständlich. Es war es auch, am Anfang. Aber es hat drei Konsequenzen, die wir bis heute schätzen:

1. Skalierung ist trivial. Wenn ein Kunde wachsen will, kopieren wir den Build. Wenn ein Kunde abspringt, löschen wir ihn. Es gibt keinen “Multi-Tenant-Layer”, der bei 200 Kund:innen ein Performance-Problem wird. Jede Kund:in ist eine eigene kleine Welt.

2. Updates sind sicher. Wenn wir einen neuen Build deployen, betrifft er erst eine kleine Pilot-Kund:innen-Gruppe. Wenn dort etwas schiefläuft, machen nur die Probleme — die anderen 65 laufen unbeeindruckt weiter. Das ist anders als bei Multi-Tenant-SaaS, wo jeder Deploy potentiell alle betrifft.

3. Customization ist möglich, ohne den Mainline-Code zu verzweigen. Wir haben einen “Theme-Layer”, in dem ein Kunde sein Logo, seine Farben, manchmal sogar leicht abweichende Layouts bekommen kann. Das ist im statischen Build möglich, weil jeder Kunde sein eigenes Artefakt ist. In einem klassischen Multi-Tenant-Frontend würden wir uns das mit Feature-Flags und Theme-Konfigurationen erkaufen.

Der Preis: wir haben eine Pipeline gebaut, die Builds parametrisiert pro Kund:in. Das ist ein Stück Infrastruktur, das man pflegen muss. Aber es ist überschaubar, gut verstanden, und nie ist es eines unserer 5 schwierigsten Probleme.

Entscheidung 3: Etiketten-Hardware als Erstklassen-Bürger

Die dritte Entscheidung war damals nicht offensichtlich, hat aber das ganze Produkt geprägt: Log+Key denkt Hardware mit.

Konkret: QR-Etiketten und Barcode-Etiketten, die auf Gegenständen kleben, sind nicht ein “Plugin”, das man extra installiert. Sie sind der Default-Interaktionsweg mit dem System. Smartphone-Scanner, Etikettendrucker, robuste Etiketten (wir verschicken Materialproben mit dem Onboarding-Kit) sind Teil dessen, was Log+Key bietet — nicht nur Software.

Das wirkt nach Marketing-Detail, ist aber Architektur-relevant: wenn Hardware-Integration ein First-Class-Citizen ist, dann muss die Web-App offline-tolerant sein (Werkstätten haben schlechtes WLAN). Sie muss schnelle Multi-Scan-Workflows unterstützen (eine Schule inventarisiert 200 Tablets in einer Pause). Sie muss Etiketten-Designs zur Druckdatei rendern (verschiedene Drucker, verschiedene Materialien, verschiedene QR-Größen).

Hätten wir Hardware als optionalen Plugin-Bereich gebaut, hätten diese Anforderungen in einem Add-on gelandet, das immer ein bisschen halb funktioniert. So sind sie im Kern — und genau das ist das, was uns gegen die “wir wollten eigentlich auch was wie Log+Key bauen, aber haben dann nur die Software gebaut”-Konkurrenz absetzt.

Was wir nicht gebaut haben

Vielleicht aufschlussreicher als die Architektur-Entscheidungen, die wir getroffen haben, sind die, die wir bewusst nicht getroffen haben:

  • Microservices. Log+Key ist ein “Service” in zwei Teilen: Directus (für jede Kund:in eine Instanz) und Frontend (für jede Kund:in ein Build). Wir haben nie versucht, die Logik in 12 Microservices zu zerlegen. Das wäre ein typischer Berater-Vorschlag, hätte uns aber nur Operations-Komplexität gegeben.
  • Eigenes Auth-System. Wir nutzen Keycloak. Eigenes IAM zu bauen ist ein bekanntes Anti-Pattern, das wir nicht wiederholen wollten.
  • Eigene API-Layer. Directus liefert REST und GraphQL. Wir haben dem Frontend einen dünnen API-Adapter vorgeschaltet, mehr nicht. Keine Apollo-Gateway-Federation, kein BFF-Pattern, kein nichts.
  • Eigenes Hosting. Wir betreiben auf Cloud-Infrastruktur, nicht in einem eigenen Rechenzentrum. Das war 2018 weniger offensichtlich als heute. Aber es macht Operations einfach.

Jede dieser Nicht-Entscheidungen ist mindestens eine Stelle gewesen, an der ein berater-naher Vorschlag im Raum lag. Wir haben uns jedes Mal für die langweiligere Option entschieden. Und wir bereuen kein einziges Mal davon.

Warum das auch für die Westwerk-Website relevant ist

Diese Architektur-Geschichte erzähle ich, weil wir gerade unsere eigene Marketing-Website neu bauen — und wir die gleichen Entscheidungen treffen.

Astro statt Next.js (statisch, kein SSR-Overhead). Cloudflare Pages statt Vercel (EU-Hosting, einfache Operations). MDX im Repo statt CMS (kein Schema, das uns überholt). PostHog cookieless statt Google Analytics + Consent-Banner.

Jede dieser Entscheidungen ist ein bisschen langweiliger als der Trend-Stack. Und jede davon wird, vermute ich, in drei Jahren noch laufen — wenn andere Marketing-Sites schon das zweite Mal umgebaut wurden.

Das ist nicht Anti-Trend aus Prinzip. Es ist die ehrliche Anwendung von dem, was uns Log+Key gelehrt hat: Architektur ist ein Werkzeug, kein Selbstzweck. Die langweilige Wahl, die zwei Jahre trägt, ist meistens die richtige.

Mitlesen?

Frag uns, was wir gerade tun.

hallo@westwerk.ac