Skip to content

Von der Idee zur Architekturentscheidung

This content is not available in your language yet.

Manche Projekte beginnen nicht mit einem Kick-off, einem Jira-Epic oder einem Architekturdiagramm. Manchmal beginnt es mit einem Gespräch unter Nachbarn.

In diesem Fall ging es um Tischtennisturniere im lokalen Verein. Genauer: um Kinderturniere, bei denen Spieler eingeteilt, Gruppen gebildet, Begegnungen geplant, Ergebnisse erfasst und am Ende Sieger bestimmt werden müssen. Klingt erstmal überschaubar. Und genau das macht die Idee interessant.

Denn auf den ersten Blick ist es kein riesiges Produkt. Keine Plattform. Kein Ökosystem. Kein Enterprise-Portal mit fünfzehn Rollen, drei Mandanten und einer Roadmap bis 2031. Es ist erstmal ein konkretes Problem aus der echten Welt:

Wie kann ein Verein ein Tischtennisturnier einfacher vorbereiten und am Turniertag sauber durchführen?

Der MVP soll zunächst bewusst klein bleiben.

Es soll Spieler geben, die mit wenigen Daten gepflegt werden können: Vorname, Name, ein initialer Ranking-Wert und optional ein Geburtsdatum, falls später Altersgruppen relevant werden.

Aus diesen Spielern soll ein Turnier erstellt werden können. Für den Start reicht ein sehr konkreter Ablauf: Spieler auswählen, Gruppen bilden, starke Spieler anhand ihres Rankings fair auf die Gruppen verteilen und die übrigen Spieler per Drag & Drop zuordnen.

Am Turniertag selbst wird es fachlich spannender. In den Gruppen sollen wechselnde Doppel-Paarungen entstehen. Die Spieler treten also nicht dauerhaft mit demselben Partner an, sondern sollen über mehrere Spiele hinweg möglichst fair durchgemischt werden. Ergebnisse werden erfasst, Siege gezählt und am Ende qualifizieren sich die besten Spieler für die nächste Runde.

Dazu kommt später vielleicht noch eine kleine Live-Ansicht für Eltern oder Zuschauer. Aber das ist nicht der Startpunkt. Der Startpunkt ist der Turnierablauf selbst.

Mein erster Gedanke war naheliegend, aber vielleicht auch ein bisschen zu sehr aus Gewohnheit geboren:

Neues Microfrontend, Host + Remote im bestehenden Nx-Monorepo, Angular im Frontend, NestJS im Backend, SCS-Struktur, Keycloak-Realm, Rollenmodell, eigene Services, eigene Datenbank.

Das klingt erstmal nicht falsch. Im Gegenteil: Die Infrastruktur ist vorhanden, die Konzepte sind bekannt, die bestehenden Projekte im Architektur-Labor folgen ähnlichen Mustern. Ein neues SCS wäre schnell angelegt, die vorhandenen CI/CD- und Deployment-Mechanismen könnten wiederverwendet werden.

Aber genau an dieser Stelle lohnt sich der zweite Blick.

Nur weil eine Architektur möglich ist, ist sie noch nicht angemessen.

Für diesen MVP gibt es zunächst kein unabhängiges Team pro fachlichem Bereich. Es gibt keinen Bedarf, einzelne Frontend-Teile unabhängig voneinander zu deployen. Es gibt auch noch keine fachliche Notwendigkeit, Spieler, Turniere, Ergebnisse und Historie als getrennte Services zu betreiben.

Das Produkt ist klein, der fachliche Kern ist zusammenhängend und der wichtigste Wert liegt nicht in verteilter Architektur, sondern in einem funktionierenden Turnierablauf.

Die eigentliche Komplexität steckt nicht darin, ein Microfrontend sauber in einen Host einzuhängen. Die eigentliche Komplexität steckt in Fragen wie:

  • Wie werden Spieler fair auf Gruppen verteilt?
  • Wie entstehen wechselnde Doppel-Paarungen?
  • Wie einfach kann ein Kampfrichter am Turniertag Ergebnisse erfassen?
  • Wie bleibt der Ablauf verständlich, wenn es schnell gehen muss?
  • Wie wenig personenbezogene Daten brauchen wir wirklich?

Damit verschiebt sich die Architekturfrage deutlich.

Die Entscheidung: einfacher starten, aber nicht beliebig

Abschnitt betitelt „Die Entscheidung: einfacher starten, aber nicht beliebig“

Die Entscheidung für den MVP lautet daher:

Keine Microfrontend-Architektur für den Start. Stattdessen eine klassische Angular-Standalone-App und ein Backend als modularer Deployment-Monolith.

Das bedeutet konkret:

  • eine Angular-App
  • eine API
  • ein Backend-Service
  • eine Datenbank
  • eine klare externe Schnittstelle
  • intern aber eine saubere fachliche Struktur

Der wichtige Punkt ist: Deployment-Monolith bedeutet nicht Code-Suppe.

Die Anwendung wird als eine Einheit gebaut und betrieben. Aber innerhalb dieser Einheit werden die fachlichen Bereiche bewusst getrennt. Spielerpflege, Turniervorbereitung, Turniertag, Spielplanung, Ergebniserfassung, Tabellenberechnung und Historie sollen nicht in einem großen technischen Mischordner landen.

Die Struktur soll so gewählt werden, dass spätere Trennung möglich bleibt, falls sie irgendwann wirklich gebraucht wird.

Nicht heute. Nicht aus Prinzip. Sondern dann, wenn das Produkt Gründe dafür liefert.

Im Frontend soll die Anwendung nicht nach technischen Kategorien wie components, services und models organisiert werden. Das führt bei wachsenden Anwendungen oft dazu, dass fachliche Zusammenhänge auseinandergerissen werden.

Stattdessen wird die App vertikal nach Use Cases strukturiert.

Ein erster Schnitt könnte so aussehen:

player-management
tournament-list
tournament-setup
tournament-day
tournament-history

Jeder Bereich bündelt das, was für diesen fachlichen Ablauf relevant ist. Die Turniervorbereitung enthält also nicht nur Komponenten, sondern auch ihre Routen, ihren lokalen Zustand, ihre View-Models und ihre API-Anbindung. Der Turniertag bekommt ebenfalls seinen eigenen Bereich, weil dort andere Anforderungen gelten: schnelle Bedienung, klare Darstellung, Ergebnis-Erfassung, aktuelle Tabelle.

Das Ziel ist nicht, möglichst viele Ordner zu erzeugen. Das Ziel ist, dass ein Use Case lokal verständlich bleibt.

Auch im Backend startet das Projekt bewusst einfach.

Es braucht für den MVP keine Landschaft aus mehreren Services. Ein Backend-Service mit einer eigenen Datenbank reicht. Trotzdem wird die Fachlichkeit nicht beliebig vermischt.

Ein möglicher interner Schnitt:

players
tournaments
tournament-setup
match-scheduling
match-results
standings
history

Diese Module können zunächst gemeinsam deployed werden. Sie können gemeinsam in einer Datenbank leben. Aber sie sollten klare Verantwortlichkeiten haben.

players verwaltet Spieler.

tournament-setup kümmert sich um Auswahl und Gruppeneinteilung.

match-scheduling enthält die Logik für wechselnde Paarungen.

match-results erfasst Ergebnisse.

standings berechnet Tabellen und Qualifikationen.

history stellt abgeschlossene Turniere dar.

Das ist kein verteiltes System. Aber es ist auch kein großer Ball aus zufällig zusammengewürfelter Logik.

Das Projekt entsteht bewusst in meinem Architektur-Labor.

Nicht, weil ein kleines Vereinsturnier zwingend eine große Laborumgebung braucht. Sondern weil dort bereits viele Dinge vorhanden sind, die für Experimente und kleine Produkte wertvoll sind:

  • bestehende Infrastruktur
  • bestehende CI/CD-Mechanismen
  • vorhandene Deployment-Erfahrung
  • bekannte Angular- und NestJS-Konventionen
  • wiederverwendbare Entwicklungsumgebung
  • ein Kontext, den auch KI-gestützte Entwicklung bereits kennt

Gerade der letzte Punkt ist nicht zu unterschätzen. Wenn ein Projekt in einer bekannten Struktur entsteht, können Architekturentscheidungen, Code-Konventionen und bestehende Muster besser wiederverwendet werden. Das reduziert Reibung.

Außerdem senkt die vorhandene Infrastruktur die Kosten. Ich muss für einen MVP nicht erst eine neue Plattform aufbauen, sondern kann vorhandene Bausteine nutzen. Gleichzeitig zwingt mich das Projekt nicht, die gesamte Plattformarchitektur zu übernehmen.

Das ist ein wichtiger Unterschied:

Infrastruktur wiederverwenden heißt nicht, jede Architekturentscheidung wiederholen zu müssen.

Der initiale Stack sieht damit bewusst unspektakulär aus:

Frontend:
Angular Standalone App
Angular Material
CDK Drag & Drop
vertikale Feature-Struktur
Backend:
NestJS API
NestJS Service
PostgreSQL
modularer Monolith
Auth:
Keycloak, aber zunächst nur mit den wirklich notwendigen Rollen
Betrieb:
bestehende Labor-Infrastruktur
bestehende CI/CD- und Docker-Mechanismen

Das ist kein spektakulärer Stack. Und genau das ist der Punkt.

Für den Start soll nicht die Architektur im Mittelpunkt stehen, sondern der fachliche Durchstich: Spieler pflegen, Turnier anlegen, Gruppen bilden, Begegnungen planen, Ergebnisse erfassen, Sieger sehen.

Wenn dieser Ablauf trägt, kann die Anwendung wachsen. Vielleicht mit einer Live-Ansicht für Eltern. Vielleicht mit einer besseren Ranking-Logik. Vielleicht mit mehreren Turnierformaten. Vielleicht irgendwann mit einer stärkeren technischen Trennung.

Aber der MVP muss das noch nicht alles beantworten.

Er muss nur gut genug geschnitten sein, damit diese Fragen später beantwortet werden können, ohne dass man alles wegwerfen muss.

Die erste Architekturentscheidung dieses Projekts ist damit eigentlich eine Anti-Entscheidung:

Kein Microfrontend für den Start. Keine künstliche Service-Landschaft. Keine Architektur, nur weil sie verfügbar ist.

Stattdessen:

Ein bewusst einfacher Deployment-Monolith mit klarer innerer Struktur.

Das ist weniger glamourös als ein großes Architekturdiagramm. Aber für diesen MVP vermutlich deutlich gesünder.