323 lines
18 KiB
Markdown
323 lines
18 KiB
Markdown
# Technische Architektur
|
|
|
|
Stand: 2026-04-08
|
|
Status: Verbindlicher Architektur-Master
|
|
Dokumentklasse: normative
|
|
|
|
## 1. Zweck und Geltung
|
|
|
|
Dieses Dokument ist die verbindliche Architekturvorgabe fuer die Entwicklung hochmodularer Webportale in diesem Repository. Es steuert Analyse, Implementierung, Refactoring und Review durch Mensch und LLM.
|
|
|
|
Verbindliche Betriebsregel:
|
|
|
|
- Entwicklung und erste Integration erfolgen lokal auf `feature/<thema>` im lokalen Docker-Stack.
|
|
- `main` ist der gemeinsame, auf DEV betriebene Integrationsstand. Ein Feature wird erst nach lokaler Verifikation und expliziter Freigabe nach `main` gemergt.
|
|
- PROD wird ausschliesslich durch das bestehende Release-Skript mit einem expliziten Release-Tag eines in DEV getesteten `main`-Commits ausgerollt und nur nach expliziter User-Freigabe angefasst.
|
|
|
|
Es definiert verbindlich:
|
|
|
|
- Modul-, Prozess-, Frontend-, API- und Datenbankgrenzen
|
|
- Ownership und oeffentliche Schnittstellen
|
|
- Standard-Scope fuer Analyse und Implementierung
|
|
- Wiederverwendungs- und Redundanzregeln
|
|
- Regeln fuer neue Module, Submodule und zentrale Bausteine
|
|
|
|
Dieses Dokument ist kein Inventar konkreter Tabellen, Prozesse, Dateien oder Runtime-Artefakte. Solche Details liegen in den zustaendigen Modul-, Prozess- oder DB-Vertraegen.
|
|
|
|
## 2. Architekturprinzipien
|
|
|
|
### 2.1 Module
|
|
|
|
Ein Modul ist ein fachlich oder technisch gekapselter Contract, nicht nur eine Verzeichnisstruktur.
|
|
|
|
Verbindliche Regel:
|
|
|
|
- jedes Modul besitzt genau eine klar abgegrenzte Primaerverantwortung
|
|
- jedes Modul kapselt seine Domain-Logik, Datenzugriffe, externen Schnittstellen, internen Datenstrukturen und Speicherdetails
|
|
- jedes Modul definiert eine explizite oeffentliche Schnittstelle fuer andere Module
|
|
- jedes Modul besitzt definierte Owned Artefakte und Schreibrechte
|
|
- interne Implementierungen anderer Module duerfen nicht direkt genutzt werden
|
|
- jede Modulgrenze muss als potenzielle spaetere Service-Grenze behandelbar bleiben
|
|
|
|
### 2.2 Prozesse
|
|
|
|
Ein Prozess ist ein sequenzieller Hauptablauf innerhalb genau eines owning Hauptmoduls.
|
|
|
|
Verbindliche Regel:
|
|
|
|
- ein Hauptmodul besitzt beliebig viele Hauptprozesse; jeder Hauptprozess gehoert genau einem Hauptmodul
|
|
- ein Hauptprozess darf Submodule desselben Hauptmoduls nutzen
|
|
- fachliche Hauptprozesse ueber Hauptmodulgrenzen hinweg sind nicht zulaessig
|
|
- Batching, Parallelisierung, Retry, Resume, Fehlerklassifikation, Statusermittlung und Ergebnisvertrag gehoeren in den owning Prozessvertrag
|
|
- zusaetzliche harte Schreib-, Feld- oder Datenbankschranken sind nur zulaessig, wenn sie explizit im Prozess- oder DB-Vertrag festgelegt sind
|
|
|
|
Verbindliche Kettenarten:
|
|
|
|
- asynchrone Prozessketten: ein Startprozess stoesst Folgeprozesse an, diese laufen als eigene Runs weiter
|
|
- synchrone Prozessketten: Subprozesse haengen direkt aneinander; jeder Schritt stoesst nur den naechsten an
|
|
- der Kettenmodus muss pro Prozessvertrag explizit festgelegt sein
|
|
- die Wahl des Kettenmodus erfolgt jeweils nach fachlichem Sinn und Prozessvertrag
|
|
|
|
Aktive Prozesswahrheit:
|
|
|
|
`docs/modules/<modul>/<submodul>/processes/`
|
|
|
|
Verbindliche Regel:
|
|
|
|
- Prozess- und Sub-Prozess-Dokumente unter diesem Pfad sind die aktive fachliche Wahrheit
|
|
- Prozessnomenklatur folgt `component.subcomponent.process_name`
|
|
- jeder Hauptprozess und jeder Sub-Prozess besitzt genau einen owning Modulpfad
|
|
- `docs/system_components/` darf fuer aktive Prozessreferenzen nicht verwendet werden
|
|
|
|
### 2.3 Implementierung
|
|
|
|
Module, Prozesse und Sub-Prozesse sind technisch so scharf wie moeglich zu trennen.
|
|
|
|
Verbindliche Regel:
|
|
|
|
- jedes Modul besitzt eine interne API oder Zugriffsschicht
|
|
- Cross-Modul-Kommunikation erfolgt nur ueber definierte Modul-Schnittstellen
|
|
- direkte Zugriffe auf interne Implementierungen oder Daten anderer Module sind verboten
|
|
- neue APIs im geschuetzten Bereich sind standardmaessig `protected`; die Abo-Pruefung greift vor jeder Datenlieferung
|
|
- Module, Prozesse und Sub-Prozesse muessen getrennt entwickelbar, testbar, ausrollbar, ueberwachbar, debugbar und optimierbar sein
|
|
- technische Kopplung zwischen Prozessen und Sub-Prozessen ist auf das notwendige Minimum zu reduzieren
|
|
- Module duerfen keine impliziten Abhaengigkeiten besitzen, die eine spaetere Extraktion verhindern
|
|
|
|
### 2.4 Frontend
|
|
|
|
Das Frontend ist bewusst minimalistisch. Ziel ist eine kleine Zahl konsistenter, wiederverwendbarer UI-Bausteine statt vieler seiten- oder feature-spezifischer Sonderkomponenten.
|
|
|
|
Verbindliche Regel:
|
|
|
|
- Seiten und Views komponieren Daten, Layouts und Komponenten, erzeugen aber keine Fachlogik
|
|
- UI-Komponenten duerfen keine fachliche Primaerlogik, fachliche Dateninterpretation oder eigenstaendige Fachwahrheit besitzen
|
|
- fachliche UI-Komponenten, fachliche Darstellungsregeln und fachlich interpretierende UI-Logik gehoeren zum owning Fachmodul
|
|
- fachlich neutrale UI-Komponenten, Layout-Komponenten, Formatierungshelfer, Interaktionsmuster und Frontend-Utilities gehoeren nach `shared`
|
|
- neue oder geaenderte Frontend-Komponenten muessen zuerst gegen bestehende Komponenten, Patterns und `shared`-Bausteine geprueft werden
|
|
- Varianten bestehender Komponenten sind ueber Props, Konfiguration oder dokumentierte Erweiterungspunkte umzusetzen, nicht durch Copy-Paste
|
|
- Sortierung, Filterung und Suche werden serverseitig im owning Modul bzw. in der API umgesetzt; das Frontend rendert nur die Ergebnisse
|
|
- Karten, Tabellen, Filter, Tabs, Buttons, Statusanzeigen, Ladezustaende, Empty States, Fehlermeldungen und Detailansichten sind als wiederverwendbare Patterns zu behandeln
|
|
- seitenlokale Sonderkomponenten sind nur zulaessig, wenn sie nachweislich nicht sinnvoll wiederverwendbar sind
|
|
- API-Responses duerfen frontendnah komponiert sein, aber keine Fachlogik aus dem owning Modul in API oder Frontend verschieben
|
|
- Seiten mit externen Redirect- oder Callback-Flows muessen Browser-History und Ruecksprungverhalten bewusst behandeln; der verbindliche Detailvertrag liegt zentral unter `docs/modules/shared/ui_foundation/`.
|
|
|
|
### 2.4.1 Mehrsprachigkeit
|
|
|
|
Mehrsprachigkeit ist ein verbindlicher Teil der Frontend-Architektur und gilt identisch fuer statische Texte, dynamisch gerenderte Texte und interaktive UI-Elemente.
|
|
|
|
Verbindliche Regel:
|
|
|
|
- jeder sichtbare GUI-String muss ueber einen i18n-Key aufgeloest werden, unabhaengig davon, ob er serverseitig, clientseitig oder aus einer API-Komposition gerendert wird
|
|
- dazu gehoeren insbesondere Navigationslabels, Tab-Titel, Buttontexte, Menuepunkte, Tooltips, Hilfetexte, Platzhalter, Empty States, Ladezustände, Fehlermeldungen, Bestätigungsdialoge, ARIA-Labels und sonstige Screenreader-Texte
|
|
- source-code-Defaults sind nur Fallback- bzw. Seed-Werte; die Anzeige-Wahrheit wird pro Locale aus dem i18n-Store bezogen
|
|
- interaktive Elemente muessen sichtbare Beschriftung und funktionalen Wert strikt trennen: der angezeigte Text ist uebersetzbar, der Wert fuer State, Transport, Routing, Filterung und Backend-Verarbeitung bleibt technisch stabil und locale-unabhaengig
|
|
- Auswahlwerte, Keys, IDs, Data-Attribute, Option-Keys, Tab-Keys und sonstige Steuerungswerte duerfen nicht aus uebersetzten Labels abgeleitet werden
|
|
- Locale-Wechsel darf ausschliesslich die Anzeigeschicht wechseln; Funktion, Auswahlzustand, Navigation, Filterlogik und Datenuebergabe muessen identisch weiter funktionieren
|
|
- wenn Text im DOM sichtbar ist, gilt er als GUI-String und unterliegt dieser Regel auch dann, wenn er clientseitig zusammengesetzt wird
|
|
- zusammengesetzte UI-Texte duerfen keine fachliche Logik enthalten; sie kombinieren nur locale-gebundene Textbausteine mit stabilen technischen Werten
|
|
|
|
## 3. Modulmodell
|
|
|
|
### 3.1 Zulaessige Modulbereiche
|
|
|
|
Fachliche Hauptmodule:
|
|
|
|
- `company`
|
|
- `ratings`
|
|
- `groups`
|
|
- `lists`
|
|
|
|
Technische Modulbereiche:
|
|
|
|
- `system`
|
|
- `shared`
|
|
|
|
Verbindliche Regel:
|
|
|
|
- fachliche Hauptmodule besitzen Business-Logik und fachliche Ownership
|
|
- `system` enthaelt nur technische Runtime-, Start-, Trigger- und Laufzeitlogik
|
|
- `shared` enthaelt nur fachlich neutrale, wiederverwendbare technische Bausteine
|
|
- konkrete Submodule, Prozesse, Artefakte und Schnittstellen werden in Modulvertraegen dokumentiert, nicht in diesem Architektur-Master
|
|
|
|
### 3.2 `shared`
|
|
|
|
`shared` ist der zentrale technische Querschnittsbereich.
|
|
|
|
Verbindliche Regel:
|
|
|
|
- `shared` darf keine Business-Logik, Fachwahrheit oder primaere fachliche Ownership besitzen
|
|
- `shared` darf Services, Komponenten, Helper, technische Schnittstellen, UI-nahe und API-nahe Bausteine bereitstellen
|
|
- ein Baustein gehoert nur nach `shared`, wenn er fachlich neutral ist und keine Verantwortung eines Fachmoduls uebernimmt
|
|
- fachliche Regeln, Dateninterpretation, Statuslogik und Entscheidungen bleiben im owning Fachmodul
|
|
- technische Querschnittslogik ohne fachlichen Inhalt muss in `shared` oder einem dort dokumentierten zentralen Baustein liegen, sobald Wiederverwendung ueber mehr als eine Stelle absehbar ist
|
|
|
|
### 3.3 `admin`
|
|
|
|
`admin` ist kein Hauptmodul und besitzt keine fachliche Ownership.
|
|
|
|
Verbindliche Regel:
|
|
|
|
- Admin-Funktionen sind nur Bedienoberflaechen auf bestehende Hauptmodule
|
|
- Admin-spezifische Fachlogik liegt im owning Hauptmodul
|
|
- ein separates fachliches Modul `admin` ist nicht zulaessig
|
|
|
|
### 3.4 `public/api/`
|
|
|
|
`public/api/` ist die HTTP-Service- und Kompositionsschicht des modularen Monolithen.
|
|
|
|
Verbindliche Regel:
|
|
|
|
- `public/api/` besitzt keine fachliche Primaerverantwortung
|
|
- `public/api/` darf Modul- oder Submodul-Schnittstellen fuer konkrete Frontend-User-Stories zusammensetzen
|
|
- `public/api/` bleibt duenn und enthaelt nur HTTP-nahe und technische Kompositionslogik
|
|
- fachliche Ownership darf nicht aus Modulen in `public/api/` wandern
|
|
|
|
## 4. Datenbankgrenze
|
|
|
|
Die Plattform nutzt aktuell genau eine gemeinsame Datenbank. Diese gemeinsame Datenbank hebt Modul- und Ownership-Grenzen nicht auf.
|
|
|
|
Verbindliche Regel:
|
|
|
|
- jede Tabelle, View, materialisierte View und DB-Funktion besitzt genau eine primaere Ownership
|
|
- primaere Ownership folgt genau einem Hauptmodul oder einem technischen Shared-Bereich
|
|
- fachliche Beziehungen sowie Ownership- und Berechtigungsschluessel verwenden stabile interne Entitaets-IDs; veraenderliche Attribute wie E-Mail, Username oder Anzeigename duerfen dafuer nicht verwendet werden
|
|
- nur das owning Modul definiert Struktur, Write-Logik, Constraints und fachliche Semantik eines DB-Artefakts
|
|
- direkte Cross-Modul-Writes in fremde Owned Tabellen sind verboten
|
|
- andere Module duerfen fremde Artefakte nur ueber definierte Schnittstellen des owning Moduls nutzen
|
|
- physische DB-Splits sind kein aktueller Standard und beduerfen einer expliziten Architekturentscheidung
|
|
|
|
Operative DB-Referenz:
|
|
|
|
`docs/database/module_db_ownership.md`
|
|
|
|
Verbindliche Regel:
|
|
|
|
- konkrete DB-Artefaktlisten gehoeren in die DB-Ownership-Dokumentation, nicht in diesen Architektur-Master
|
|
- bei Analyse, Refactoring und Implementierung wird der DB-Scope zuerst ueber Modul plus Owned DB-Artefakte bestimmt
|
|
- fremde DB-Artefakte duerfen nur bei deklarierter Leseabhaengigkeit, FK-Beziehung oder Integrationspruefung in den Scope aufgenommen werden
|
|
|
|
## 5. Dokumentation und Lesescope
|
|
|
|
Aktive Dokumentation ist komponentennah.
|
|
|
|
Verbindliche Regel:
|
|
|
|
- aktive Modul- und Submodul-Dokumentation liegt unter `docs/modules/<modul>/...`
|
|
- aktive technische Shared-Dokumentation liegt unter `docs/modules/shared/...`
|
|
- technische Runtime-Dokumentation liegt unter `docs/modules/system/...`
|
|
- fachliche Hauptprozesse liegen innerhalb des owning Modulbaums
|
|
- historische oder abgeloeste Dokumentation liegt ausserhalb des aktiven Modulbaums
|
|
- `docs/technical_architecture.md` bleibt der einzige aktive Architektur-Master
|
|
|
|
Standard-Lesescope:
|
|
|
|
- Arbeit an einem Modul: `docs/technical_architecture.md` plus `docs/modules/<modul>/...`
|
|
- Arbeit an einem Submodul: `docs/technical_architecture.md` plus `docs/modules/<modul>/<submodul>/...`
|
|
- `docs/modules/shared/...`: nur bei betroffener Shared-Schnittstelle oder moeglicher Wiederverwendung
|
|
- `docs/modules/system/...`: nur bei Runtime-, Queue-, Scheduler-, Trigger- oder Supervisor-Themen
|
|
- andere Module: nur bei explizitem Integrationsbedarf
|
|
|
|
## 6. Wiederverwendung und Redundanzverbot
|
|
|
|
Vor jeder Aenderung an App, Frontend, UI-Komponenten, UI-Patterns, API, Prozesslogik, Datenzugriff, Infrastruktur oder Dokumentation ist Wiederverwendung vor Neuerstellung zu pruefen.
|
|
|
|
Ziel ist eine Architektur ohne redundante Fachlogik, technische Inselloesungen, doppelte UI-Komponenten oder mehrfach gepflegte Varianten desselben Musters.
|
|
|
|
Verbindliche Regel:
|
|
|
|
- zuerst bestehende Muster, Komponenten, Services, Modul-Schnittstellen und `shared`-Bausteine pruefen
|
|
- vorhandene passende Muster muessen wiederverwendet, erweitert oder als zentrale Schnittstelle bereitgestellt werden
|
|
- fachliche Inhalte gehoeren immer in das owning Fachmodul und werden von dort ueber definierte Schnittstellen bereitgestellt
|
|
- fachliche Logik darf nicht in `shared`, `public/api/`, `admin`, Skripte oder fachfremde Bereiche ausgelagert oder dupliziert werden
|
|
- fachlich neutrale technische Logik gehoert nach `shared`, sofern sie wiederverwendbar ist oder Wiederverwendung absehbar ist
|
|
- Frontend-Darstellung, Interaktionslogik, Layout, Formatierung und Zustandsdarstellung sind als bestehende oder neue zentrale UI-Komponenten beziehungsweise UI-Patterns in `shared` zu pruefen
|
|
- neue `shared`-Bausteine sind nur zulaessig, wenn sie keine Fachwahrheit enthalten, keine fachliche Primaerverantwortung uebernehmen und wiederverwendbar sind
|
|
- technische Querschnittsbausteine duerfen Module entkoppeln, aber keine fachlichen Entscheidungen aus owning Modulen herausziehen
|
|
- neue Loesungen sind nur zulaessig, wenn kein passendes bestehendes Muster, keine passende Modul-Schnittstelle und kein geeigneter `shared`-Baustein existiert
|
|
- Quickfixes, Workarounds, Copy-Paste-Varianten, seitenlokale UI-Duplikate und isolierte Sonderlogik fuer Einzelstellen sind verboten
|
|
- Redundanzvermeidung muss bei Analyse, Umsetzung, Review und Refactoring aktiv nachgewiesen werden koennen
|
|
|
|
## 7. Verbotene Strukturen
|
|
|
|
Nicht zulaessig sind:
|
|
|
|
- Module als reine Ordner ohne Contract
|
|
- direkte Cross-Modul-Zugriffe auf DB-Tabellen, interne Implementierungen oder Daten anderer Module
|
|
- versteckte oder implizite Modulabhaengigkeiten
|
|
- Vermischung mehrerer Primaerverantwortungen innerhalb eines Moduls
|
|
- parallele Fachlogik ausserhalb des owning Moduls
|
|
- redundante fachliche, technische oder UI-Loesungen, obwohl ein bestehendes Modul, eine Schnittstelle, ein Pattern oder ein `shared`-Baustein erweitert werden koennte
|
|
- neue generische Frameworks oder Orchestrator-Umbauten ohne explizite Architekturentscheidung
|
|
- implizite Schutz-, Schreib- oder Datenbankschranken ohne Prozess- oder DB-Vertrag
|
|
|
|
## 8. Erweiterungsregeln
|
|
|
|
Neue Hauptmodule, Submodule oder zentrale Bausteine duerfen nur eingefuehrt werden, wenn bestehende Strukturen die Verantwortung nicht sauber tragen koennen.
|
|
|
|
Prueffragen vor jeder Erweiterung:
|
|
|
|
1. Welches bestehende Hauptmodul ist primaer betroffen?
|
|
2. Reicht eine neue Datei, ein neues Submodul oder eine neue Schnittstelle im owning Hauptmodul aus?
|
|
3. Handelt es sich um fachlich neutrale Wiederverwendung, die nach `shared` gehoert?
|
|
4. Entsteht wirklich eine neue Primaerverantwortung mit eigenen Owned Artefakten und Schreibrechten?
|
|
5. Bleibt der Handshake zum Rest des Systems auf minimale Scope-Identifier begrenzt?
|
|
6. Reduziert der neue Schnitt Kopplung und Redundanz, statt sie zu erhoehen?
|
|
|
|
Verbindliche Regel:
|
|
|
|
- neue Hauptmodule sind nur zulaessig, wenn eine neue fachliche oder technische Primaerverantwortung entsteht, die nicht sauber in `company`, `ratings`, `groups`, `lists`, `system` oder `shared` aufgeht
|
|
- neue Submodule sind nur zulaessig, wenn innerhalb eines bestehenden Hauptmoduls eine klar isolierbare Verantwortung mit eigener Schnittstelle entsteht
|
|
- neue Prozess- und Sub-Prozess-Dokumente werden im owning Modulpfad angelegt und folgen `component.subcomponent.process_name`
|
|
- `admin`, `public/api/`, `scripts/` oder `lib/` begruenden kein neues fachliches Hauptmodul
|
|
- Bequemlichkeit, Dateigroesse oder kurzfristiger Umbauaufwand rechtfertigen kein neues Hauptmodul
|
|
- vor jeder normativen Architektur- oder Modulerweiterung muss dieses Dokument aktualisiert werden
|
|
|
|
## 9. Aenderungsregel
|
|
|
|
Jede strukturelle Aenderung an Hauptmodulen, Modulgrenzen, Prozesszuordnungen, Frontend-Prinzipien, API-Grenzen, DB-Ownership oder primaeren Ownership-Prinzipien muss zuerst in diesem Dokument normativ festgelegt und danach in Detaildokumenten nachgezogen werden.
|
|
|
|
Verbindlich ist:
|
|
|
|
- `docs/technical_architecture.md` ist der einzige aktive Architektur-Master des Repositories
|
|
- andere Dokumente duerfen diese Architektur erklaeren, anwenden oder historisieren, aber keine konkurrierende Master-Struktur definieren
|
|
- konkrete Inventare wie Tabellenlisten, Submodullisten, Prozesslisten oder Runtime-Artefakte werden in Detaildokumenten gepflegt und nicht hier dupliziert
|
|
|
|
## 10. Projektspezifische Architekturvorgaben
|
|
|
|
Dieses Kapitel enthaelt Architekturentscheidungen, die fuer dieses Projekt
|
|
gelten und nicht Teil der allgemeinen, projektuebergreifend wiederverwendbaren
|
|
Modularitaet sind.
|
|
|
|
### 10.1 Fachliches Hauptmodul `market_management`
|
|
|
|
Dieses Projekt besitzt zusaetzlich das fachliche Hauptmodul
|
|
`market_management`. Seine fachliche Ownership, Datenstruktur und
|
|
Schnittstellen werden in den Modulvertraegen unter
|
|
`docs/modules/market_management/` dokumentiert.
|
|
|
|
### 10.2 GUI-/MCP-Paritaet
|
|
|
|
Die MCP-Schnittstelle ist im Grundsatz funktional paritaetisch zur GUI. Ein
|
|
MCP-Nutzer ist hinsichtlich der fachlichen Nutzung einem GUI-Nutzer
|
|
gleichzustellen.
|
|
|
|
Verbindliche Regel:
|
|
|
|
- jede fachliche Funktion, die technisch ueber das GUI-Interface verfuegbar
|
|
ist, muss auch ueber die MCP-Schnittstelle ausfuehrbar sein
|
|
- die Paritaet bezieht sich auf die technischen Moeglichkeiten des Interfaces,
|
|
nicht nur auf aktuell im GUI dargestellte Funktionen; technisch vorhandene,
|
|
im GUI nicht angezeigte Funktionen muessen trotzdem ueber MCP verfuegbar sein
|
|
- alle fachlichen Lese-, Anlege-, Aenderungs-, Archivierungs- und
|
|
Reaktivierungsmoeglichkeiten des GUI-Interfaces muessen im MCP-Interface
|
|
abgebildet sein
|
|
- GUI und MCP verwenden dieselben fachlichen Validierungen, Berechtigungen,
|
|
Statusregeln und Ownership-Grenzen; fachliche Logik darf nicht doppelt in
|
|
GUI und MCP implementiert werden
|
|
- jede Erweiterung oder Aenderung eines GUI-Anwendungsfalls erfordert zwingend
|
|
die gleichzeitige Pruefung und, falls erforderlich, Anpassung des MCP-Interfaces
|
|
- ein MCP-Nutzer darf gegenueber einem gleich berechtigten GUI-Nutzer weder
|
|
fachlich eingeschraenkt noch durch abweichende Regeln bevorzugt werden
|
|
- die Paritaet betrifft die fachliche Funktion und den Datenzugriff, nicht die
|
|
visuelle Darstellung oder den Interaktionsablauf der GUI
|