tooling: make .junie/.gemini docs-first (remove legacy guidelines)
This commit is contained in:
@@ -0,0 +1,30 @@
|
||||
# ADR-0000: Vorlage für Architekturentscheidungsaufzeichnungen
|
||||
|
||||
## Status
|
||||
|
||||
[Vorgeschlagen | Akzeptiert | Veraltet | Ersetzt]
|
||||
|
||||
Falls sie ersetzt, fügen Sie einen Verweis auf die neue ADR ein: `[ADR-XXX](XXX-filename.md)`
|
||||
|
||||
## Kontext
|
||||
|
||||
Beschreiben Sie den Kontext und die Problemstellung, z. B. in freier Form mit zwei bis drei Sätzen. Sie können das
|
||||
Problem auch in Form einer Frage formulieren.
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Beschreiben Sie die getroffene Entscheidung.
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
Beschreiben Sie den resultierenden Kontext nach Anwendung der Entscheidung. Alle Konsequenzen sollten hier aufgeführt
|
||||
werden, nicht nur die "positiven". Eine bestimmte Entscheidung kann positive, negative und neutrale Konsequenzen haben,
|
||||
die alle das Team und das Projekt in der Zukunft beeinflussen.
|
||||
|
||||
## Betrachtete Alternativen
|
||||
|
||||
Welche anderen Optionen wurden in Betracht gezogen und warum wurden sie nicht gewählt?
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [Link zu relevanter Dokumentation, Diskussionen usw.]
|
||||
@@ -0,0 +1,75 @@
|
||||
# ADR-0001: Modulare Architektur
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert
|
||||
|
||||
## Kontext
|
||||
|
||||
Das Meldestelle-System wurde ursprünglich als monolithische Anwendung entwickelt. Mit zunehmender Komplexität und Größe
|
||||
des Systems traten mehrere Herausforderungen auf:
|
||||
|
||||
1. Der Quellcode wurde schwer zu warten und zu verstehen
|
||||
2. Entwicklungsteams mussten sich eng koordinieren, was die Entwicklung verlangsamte
|
||||
3. Die gesamte Anwendung musste skaliert werden, auch wenn nur bestimmte Teile mehr Ressourcen benötigten
|
||||
4. Technologieentscheidungen wurden durch die monolithische Architektur eingeschränkt
|
||||
|
||||
Das Team musste entscheiden, ob es mit dem monolithischen Ansatz fortfahren oder zu einer modularenen Architektur
|
||||
migrieren sollte.
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Wir haben uns entschieden, von einer monolithischen Struktur zu einer modularen Architektur zu migrieren und das System
|
||||
in die folgenden Module zu organisieren:
|
||||
|
||||
- **core**: Gemeinsame Kernkomponenten
|
||||
- **masterdata**: Stammdatenverwaltung
|
||||
- **members**: Mitgliederverwaltung
|
||||
- **horses**: Pferderegistrierung
|
||||
- **events**: Veranstaltungsverwaltung
|
||||
- **infrastructure**: Gemeinsame Infrastrukturkomponenten
|
||||
- **client**: Client-Anwendungen
|
||||
|
||||
Jedes Domänenmodul (masterdata, members, horses, events) folgt einem Clean-Architecture-Ansatz mit separaten API-,
|
||||
Anwendung-, Domänen-, Infrastruktur- und Service-Schichten.
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positive
|
||||
|
||||
- **Verbesserte Wartbarkeit**: Kleinere, fokussierte Module sind leichter zu verstehen und zu warten
|
||||
- **Unabhängige Entwicklung**: Teams können an verschiedenen Modulen mit minimaler Koordination arbeiten
|
||||
- **Selektive Skalierung**: Einzelne Module können basierend auf ihren spezifischen Anforderungen skaliert werden
|
||||
- **Technologieflexibilität**: Verschiedene Module können je nach Bedarf unterschiedliche Technologien verwenden
|
||||
- **Klare Grenzen**: Domänengrenzen sind explizit definiert, was die konzeptionelle Integrität des Systems verbessert
|
||||
|
||||
### Negative
|
||||
|
||||
- **Erhöhte Komplexität**: Die Gesamtsystemarchitektur ist komplexer
|
||||
- **Deployment-Overhead**: Mehr Komponenten müssen bereitgestellt und verwaltet werden
|
||||
- **Leistungsüberlegungen**: Modulübergreifende Kommunikation fügt Latenz hinzu
|
||||
- **Migrationsaufwand**: Erheblicher Aufwand erforderlich, um von der monolithischen Struktur zu migrieren
|
||||
|
||||
### Neutral
|
||||
|
||||
- **Teamorganisation**: Teams müssen um Module statt um Features herum organisiert werden
|
||||
- **Dokumentationsbedarf**: Umfassendere Dokumentation ist erforderlich, um das System als Ganzes zu verstehen
|
||||
|
||||
## Betrachtete Alternativen
|
||||
|
||||
### Erweiterter Monolith
|
||||
|
||||
Wir haben in Betracht gezogen, die interne Struktur des Monolithen mit besseren Modulgrenzen zu verbessern, ihn aber als
|
||||
eine einzige bereitstellbare Einheit zu behalten. Dies wäre einfacher bereitzustellen gewesen, hätte aber die Probleme
|
||||
mit der Skalierung und Technologieflexibilität nicht gelöst.
|
||||
|
||||
### Microservices
|
||||
|
||||
Wir haben einen feingranularen Microservices-Ansatz mit vielen kleineren Diensten in Betracht gezogen. Dies hätte
|
||||
maximale Flexibilität geboten, aber für unsere aktuellen Bedürfnisse übermäßige Komplexität und betrieblichen Overhead
|
||||
eingeführt.
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [Modular Monoliths von Simon Brown](https://meldestelle-pro.youtrack.cloud/api/files/526-8?sign=MTc2MjU2MDAwMDAwMHwyLTF8NTI2LTh8QldrSXd1MHoyUlE1T3lZSjBDNVh4Ry1zcGZZM1lWSlE0VXN2M2FQSXNDbw0K&updated=1762338956551)
|
||||
- [Clean Architecture von Robert C. Martin](https://meldestelle-pro.youtrack.cloud/api/files/526-10?sign=MTc2MjU2MDAwMDAwMHwyLTF8NTI2LTEwfF9XbVdSakVpSW5HV1VjalY3UjhCMGFub2NIQXdPTUkyM3FFTnNTdGNIRmsNCg&updated=1762339225451)
|
||||
@@ -0,0 +1,78 @@
|
||||
# ADR-0002: Domain-Driven Design
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert
|
||||
|
||||
## Kontext
|
||||
|
||||
Mit der Weiterentwicklung des Meldestelle-Systems zur Bewältigung komplexer Geschäftsregeln für die Verwaltung von
|
||||
Reitsportveranstaltungen standen wir vor folgenden Herausforderungen:
|
||||
|
||||
1. Aufrechterhaltung einer klaren Trennung zwischen Geschäftslogik und technischen Belangen
|
||||
2. Sicherstellung, dass das System das Verständnis der Domänenexperten vom Problemraum genau widerspiegelt
|
||||
3. Schaffung einer gemeinsamen Sprache zwischen technischen und nicht-technischen Stakeholdern
|
||||
4. Organisation des Codes in einer Weise, die die Geschäftsdomänen widerspiegelt
|
||||
|
||||
Wir benötigten einen architektonischen Ansatz, der diese Herausforderungen adressiert und eine solide Grundlage für die
|
||||
in [ADR-0001](0001-modular-architecture-de.md) beschriebene modulare Architektur bietet.
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Wir haben uns entschieden, Domain-Driven Design (DDD)-Prinzipien für die Organisation unseres Quellcodes und die
|
||||
Gestaltung unseres Systems zu übernehmen. Dies umfasst:
|
||||
|
||||
1. **Ubiquitäre Sprache**: Entwicklung einer gemeinsamen Sprache, die von Domänenexperten und Entwicklern geteilt wird
|
||||
2. **Bounded Contexts**: Definition expliziter Grenzen zwischen verschiedenen Domänenbereichen (masterdata, members, horses, events)
|
||||
3. **Schichtenarchitektur**: Organisation jedes Domänenmoduls in Schichten:
|
||||
|
||||
- Domänenschicht: Enthält Domänenmodelle, Entitäten, Wertobjekte und Domänendienste
|
||||
- Anwendungsschicht: Enthält Anwendungsdienste, Anwendungsfälle und Befehls-/Abfragehandler
|
||||
- Infrastrukturschicht: Enthält technische Implementierungen von Repositories, Messaging usw.
|
||||
- API-Schicht: Definiert die Schnittstellen für die Interaktion mit der Domäne
|
||||
|
||||
4. **Aggregate**: Identifizierung von Aggregat-Roots, die Konsistenzgrenzen aufrechterhalten
|
||||
5. **Repositories**: Verwendung des Repository-Musters zur Abstraktion des Datenzugriffs
|
||||
6. **Domänen-Events**: Verwendung von Events zur Kommunikation zwischen Bounded Contexts
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positive
|
||||
|
||||
- **Business-Technologie-Ausrichtung**: Die Codestruktur spiegelt direkt die Geschäftsdomänen wider
|
||||
- **Verbesserte Kommunikation**: Ubiquitäre Sprache erleichtert die Kommunikation zwischen technischen und nicht-technischen Stakeholdern
|
||||
- **Wartbarkeit**: Klare Trennung der Belange macht den Code leichter zu warten
|
||||
- **Testbarkeit**: Domänenlogik kann unabhängig von Infrastrukturbelangen getestet werden
|
||||
- **Flexibilität**: Änderungen in einem Bounded Context haben minimale Auswirkungen auf andere
|
||||
|
||||
### Negative
|
||||
|
||||
- **Lernkurve**: DDD-Konzepte erfordern Zeit, um sie richtig zu erlernen und anzuwenden
|
||||
- **Initialer Entwicklungsaufwand**: Mehr Vorabdesign und Diskussion ist erforderlich
|
||||
- **Potenzielle Überentwicklung**: Risiko, komplexe DDD-Muster anzuwenden, wo einfachere Lösungen ausreichen würden
|
||||
|
||||
### Neutral
|
||||
|
||||
- **Teamorganisation**: Teams benötigen Domänenwissen sowie technische Fähigkeiten
|
||||
- **Dokumentationsbedarf**: Domänenmodelle und Bounded Contexts müssen gut dokumentiert sein
|
||||
|
||||
## Betrachtete Alternativen
|
||||
|
||||
### Transaction Script Pattern
|
||||
|
||||
Wir haben die Verwendung eines einfacheren Transaction Script Patterns in Betracht gezogen, bei dem die Geschäftslogik
|
||||
um Prozeduren statt um Domänenobjekte organisiert ist. Dies wäre anfänglich einfacher zu implementieren gewesen, wäre
|
||||
aber mit zunehmender Komplexität der Geschäftslogik schwieriger zu warten geworden.
|
||||
|
||||
### Anemic Domain Model
|
||||
|
||||
Wir haben die Verwendung eines anämischen Domänenmodells in Betracht gezogen, bei dem Domänenobjekte einfache
|
||||
Datencontainer sind und die Geschäftslogik in separaten Serviceklassen liegt. Dies wäre für Entwickler mit
|
||||
CRUD-basiertem Hintergrund vertrauter gewesen, hätte aber nicht die Vorteile der Kapselung und der reichhaltigen
|
||||
Domänenmodellierung geboten.
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [Domain-Driven Design von Eric Evans](https://meldestelle-pro.youtrack.cloud/api/files/526-11?sign=MTc2MjU2MDAwMDAwMHwyLTF8NTI2LTExfE9KWGJodXhlT0Q0UEdYREpfNllaV1RXakU4YUZYbXZJb1JIdjJDVWVnZkUNCg&updated=1762339700786)
|
||||
- [Implementing Domain-Driven Design von Vaughn Vernon](https://meldestelle-pro.youtrack.cloud/api/files/526-14?sign=MTc2MjU2MDAwMDAwMHwyLTF8NTI2LTE0fEx6NXJCT2NrMFNWMHRfc1pIbVRTc04xQ1Q2OEtEdzdMc1djaTNIMmRCNFENCg&updated=1762340142201)
|
||||
- [Clean Architecture von Robert C. Martin](https://meldestelle-pro.youtrack.cloud/api/files/526-10?sign=MTc2MjU2MDAwMDAwMHwyLTF8NTI2LTEwfF9XbVdSakVpSW5HV1VjalY3UjhCMGFub2NIQXdPTUkyM3FFTnNTdGNIRmsNCg&updated=1762339225451)
|
||||
@@ -0,0 +1,91 @@
|
||||
# ADR-0003: Microservices-Architektur
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert
|
||||
|
||||
## Kontext
|
||||
|
||||
Nach der Entscheidung, eine modulare Architektur ([ADR-0001](0001-modular-architecture-de.md)) und Domain-Driven
|
||||
Design ([ADR-0002](0002-domain-driven-design-de.md)) zu übernehmen, mussten wir die Deployment-Strategie für unsere
|
||||
Module festlegen. Zu den wichtigsten Überlegungen gehörten:
|
||||
|
||||
1. Unabhängige Skalierbarkeit verschiedener Teile des Systems
|
||||
2. Deployment-Unabhängigkeit, um Teams zu ermöglichen, Änderungen ohne Koordination mit anderen Teams zu veröffentlichen
|
||||
3. Technologieunabhängigkeit, um verschiedenen Diensten die Verwendung unterschiedlicher Technologien nach Bedarf zu
|
||||
ermöglichen
|
||||
4. Resilienz, um sicherzustellen, dass Ausfälle in einem Teil des Systems nicht das gesamte System beeinträchtigen
|
||||
5. Klare Zuständigkeitsgrenzen, die mit den Team-Verantwortlichkeiten übereinstimmen
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Wir haben uns entschieden, eine Microservices-Architektur zu implementieren, bei der jedes Domänenmodul als separater
|
||||
Dienst bereitgestellt wird:
|
||||
|
||||
- **masterdata-service**: Verwaltet Stammdaten wie Standorte, Disziplinen usw.
|
||||
- **members-service**: Verwaltet Mitgliederregistrierung und -profile
|
||||
- **horses-service**: Verwaltet Pferderegistrierung und -informationen
|
||||
- **events-service**: Verwaltet Veranstaltungserstellung, -planung und -anmeldungen
|
||||
|
||||
Jeder Dienst:
|
||||
|
||||
- Hat sein eigenes Datenbankschema
|
||||
- Ist unabhängig bereitstellbar
|
||||
- Kommuniziert mit anderen Diensten über klar definierte APIs und nachrichtenbasierte Kommunikation
|
||||
- Ist für seine eigene Domänenlogik gemäß DDD-Prinzipien verantwortlich
|
||||
|
||||
Wir haben auch unterstützende Infrastrukturdienste implementiert:
|
||||
|
||||
- **gateway**: API-Gateway für Routing und Authentifizierung
|
||||
- **auth**: Authentifizierung- und Autorisierungsdienst (Keycloak)
|
||||
- **cache**: Caching-Dienst (Redis)
|
||||
- **messaging**: Message Broker für die Kommunikation zwischen Diensten (Kafka)
|
||||
- **monitoring**: Überwachung- und Beobachtbarkeitsdienste
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positive
|
||||
|
||||
- **Unabhängige Skalierbarkeit**: Jeder Dienst kann basierend auf seinen spezifischen Lastanforderungen skaliert werden
|
||||
- **Deployment-Unabhängigkeit**: Teams können Änderungen an ihren Diensten bereitstellen, ohne sich mit anderen Teams
|
||||
abstimmen zu müssen
|
||||
- **Technologieflexibilität**: Verschiedene Dienste können je nach Bedarf unterschiedliche Technologien verwenden
|
||||
- **Resilienz**: Ausfälle in einem Dienst beeinträchtigen nicht unbedingt andere
|
||||
- **Klare Zuständigkeit**: Jeder Dienst hat klare Zuständigkeitsgrenzen, die mit den Team-Verantwortlichkeiten
|
||||
übereinstimmen
|
||||
- **Kleinere Codebasen**: Jeder Dienst hat eine kleinere, fokussierte Codebasis
|
||||
|
||||
### Negative
|
||||
|
||||
- **Komplexität verteilter Systeme**: Microservices bringen die Herausforderungen verteilter Systeme mit sich
|
||||
- **Betrieblicher Mehraufwand**: Mehr Dienste müssen bereitgestellt, überwacht und gewartet werden
|
||||
- **Herausforderungen bei der Datenkonsistenz**: Die Aufrechterhaltung der Datenkonsistenz über Dienste hinweg erfordert
|
||||
sorgfältiges Design
|
||||
- **Netzwerklatenz**: Die Kommunikation zwischen Diensten fügt Latenz hinzu
|
||||
- **Testkomplexität**: End-to-End-Tests werden komplexer
|
||||
|
||||
### Neutral
|
||||
|
||||
- **Teamorganisation**: Teams müssen um Dienste statt um Features herum organisiert werden
|
||||
- **Dokumentationsbedarf**: Dienstschnittstellen und -interaktionen müssen gut dokumentiert sein
|
||||
|
||||
## Betrachtete Alternativen
|
||||
|
||||
### Modularer Monolith
|
||||
|
||||
Wir haben die Implementierung eines modularen Monolithen in Betracht gezogen, bei dem alle Module als eine einzige
|
||||
Anwendung bereitgestellt werden, jedoch mit klaren Modulgrenzen. Dies wäre einfacher bereitzustellen gewesen und hätte
|
||||
die Herausforderungen verteilter Systeme vermieden, hätte aber nicht die Vorteile der unabhängigen Skalierbarkeit und
|
||||
Bereitstellung geboten.
|
||||
|
||||
### Service-basierte Architektur
|
||||
|
||||
Wir haben eine Dienst-basierte Architektur mit weniger bzw. größeren Diensten in Betracht gezogen, die mehrere
|
||||
Domänenbereiche umfassen würden. Dies hätte den betrieblichen Overhead reduziert, aber es schwieriger gemacht, klare
|
||||
Domänengrenzen und unabhängige Skalierbarkeit aufrechtzuerhalten.
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [Microservices von Martin Fowler](https://meldestelle-pro.youtrack.cloud/api/files/526-16?sign=MTc2MjU2MDAwMDAwMHwyLTF8NTI2LTE2fFViVXRuTGdXcFhIcFRwdG03ZHlSZEZ5ZEc2MG5VVVB3SGJ4OUFRRG82QlENCg&updated=1762340608616)
|
||||
- [Building Microservices von Sam Newman](https://meldestelle-pro.youtrack.cloud/api/files/526-17?sign=MTc2MjU2MDAwMDAwMHwyLTF8NTI2LTE3fDdjaXJoZ0NlWlQ1MW9tZ0UwdC1fLVZEZ0pUcFF6QnNScTcxN0Z6YlVUazQNCg&updated=1762340788707)
|
||||
- [Microservices Patterns von Chris Richardson](https://meldestelle-pro.youtrack.cloud/api/files/526-20?sign=MTc2MjU2MDAwMDAwMHwyLTF8NTI2LTIwfDM5S08yMXVENmFRa1NPaEROQlR1N1Nvc0lWWUJXU0hCR1JYTVJXSDA2RGcNCg&updated=1762340989301)
|
||||
@@ -0,0 +1,84 @@
|
||||
# ADR-0004: Ereignisgesteuerte Kommunikation
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert
|
||||
|
||||
## Kontext
|
||||
|
||||
Mit der Einführung einer Microservices-Architektur ([ADR-0003](0003-microservices-architecture-de.md)) mussten wir die
|
||||
effektivste Art der Kommunikation zwischen den Diensten bestimmen. Zu den wichtigsten Überlegungen gehörten:
|
||||
|
||||
1. Lose Kopplung zwischen Diensten, um ihre Unabhängigkeit zu erhalten
|
||||
2. Asynchrone Verarbeitungsfähigkeiten zur Verbesserung der Systemresilienz und Skalierbarkeit
|
||||
3. Zuverlässige Kommunikation, um sicherzustellen, dass wichtige Informationen nicht verloren gehen
|
||||
4. Unterstützung für komplexe Workflows, die mehrere Dienste umfassen
|
||||
5. Fähigkeit, den Zustand des Systems für Audit- und Debugging-Zwecke zu rekonstruieren
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Wir haben uns entschieden, ein ereignisgesteuertes Kommunikationsmuster mit Apache Kafka als Message Broker zu
|
||||
implementieren. Die wichtigsten Aspekte dieses Ansatzes umfassen:
|
||||
|
||||
1. **Domänen-Ereignisse**: Dienste veröffentlichen Domänen-Ereignisse, wenn signifikante Zustandsänderungen auftreten
|
||||
2. **Event Sourcing**: Für kritische Daten speichern wir alle Ereignisse, die zum aktuellen Zustand geführt haben
|
||||
3. **Nachrichtenbasierte Kommunikation**: Dienste kommunizieren hauptsächlich über asynchrone Nachrichten
|
||||
4. **Choreographie**: Komplexe Workflows werden durch Ereignis-Choreographie statt Orchestrierung implementiert
|
||||
5. **Ereignis-Schema-Registry**: Wir führen eine Registry von Ereignis-Schemas durch, um Kompatibilität zu gewährleisten
|
||||
|
||||
Die Implementierung umfasst:
|
||||
|
||||
- Kafka als zentraler Message Broker
|
||||
- Schema-Registry zur Verwaltung von Ereignis-Schemas
|
||||
- Ereignis-Handler in jedem Dienst zur Verarbeitung von Ereignissen aus anderen Diensten
|
||||
- Ereignis-Publisher in jedem Dienst zur Veröffentlichung von Domänen-Ereignissen
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positive
|
||||
|
||||
- **Lose Kopplung**: Dienste sind entkoppelt und teilen nur die Ereignis-Verträge
|
||||
- **Skalierbarkeit**: Asynchrone Verarbeitung ermöglicht bessere Skalierbarkeit unter Last
|
||||
- **Resilienz**: Dienste können weiter funktionieren, auch wenn andere Dienste nicht verfügbar sind
|
||||
- **Audit-Trail**: Event Sourcing bietet einen vollständigen Audit-Trail aller Zustandsänderungen
|
||||
- **Flexibilität**: Neue Konsumenten können hinzugefügt werden, ohne Publisher zu modifizieren
|
||||
|
||||
### Negative
|
||||
|
||||
- **Eventuelle Konsistenz**: Das System ist letztendlich konsistent, was schwer zu verstehen sein kann
|
||||
- **Komplexität**: Ereignisgesteuerte Systeme sind komplexer zu entwerfen, zu implementieren und zu debuggen
|
||||
- **Reihenfolgegarantien**: Die korrekte Reihenfolge von Ereignissen sicherzustellen kann herausfordernd sein
|
||||
- **Idempotenz**: Dienste müssen doppelte Ereignisse korrekt behandeln
|
||||
- **Lernkurve**: Entwickler müssen ereignisgesteuerte Muster und Praktiken erlernen
|
||||
|
||||
### Neutral
|
||||
|
||||
- **Überwachungsbedarf**: Umfassende Überwachung ist erforderlich, um den Ereignisfluss zu verfolgen
|
||||
- **Testansatz**: Teststrategien müssen asynchrones Verhalten berücksichtigen
|
||||
|
||||
## Betrachtete Alternativen
|
||||
|
||||
### Synchrone REST-APIs
|
||||
|
||||
Wir haben die Verwendung synchroner REST-APIs als primären Kommunikationsmechanismus in Betracht gezogen. Dies wäre
|
||||
einfacher zu implementieren und zu debuggen gewesen, hätte aber zu einer engeren Kopplung zwischen Diensten und
|
||||
verringerter Resilienz geführt.
|
||||
|
||||
### Request-Response-Messaging
|
||||
|
||||
Wir haben ein Request-Response-Messaging-Muster in Betracht gezogen, bei dem Dienste Anfragen senden und auf Antworten
|
||||
warten. Dies hätte einige der Vorteile asynchroner Kommunikation geboten und gleichzeitig ein vertrautes
|
||||
Request-Response-Modell beibehalten, hätte aber das Publish-Subscribe-Muster nicht so effektiv unterstützt.
|
||||
|
||||
### GraphQL-Federation
|
||||
|
||||
Wir haben die Verwendung von GraphQL-Federation zur Zusammensetzung von APIs aus mehreren Diensten in Betracht gezogen.
|
||||
Dies hätte eine einheitliche API für Clients geboten, hätte aber eine enge Kopplung zwischen Diensten beibehalten und
|
||||
asynchrone Workflows nicht so effektiv unterstützt.
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [Enterprise Integration Patterns](https://meldestelle-pro.youtrack.cloud/api/files/526-22?sign=MTc2MjU2MDAwMDAwMHwyLTF8NTI2LTIyfGNVMDU5cXJTbi0wRDRvWngwLXhTc0RDTzZZOTZBaTFtQzBpZ3RVYjBxTVkNCg&updated=1762342095790)
|
||||
- [Event-Driven Architecture von Martin Fowler](https://meldestelle-pro.youtrack.cloud/api/files/526-24?sign=MTc2MjU2MDAwMDAwMHwyLTF8NTI2LTI0fDJsSEFZbnJzRWpCOWlkU3BIZ0ZOTDRIeDlmY0F2NUhMZklseE9WNnBhWkUNCg&updated=1762342654487)
|
||||
- [Apache Kafka Dokumentation](https://kafka.apache.org/documentation/)
|
||||
- [Event Sourcing Pattern](https://meldestelle-pro.youtrack.cloud/api/files/526-26?sign=MTc2MjU2MDAwMDAwMHwyLTF8NTI2LTI2fEZURXo4SVVIbmtwcUExVFlab3BLZkVyRFlZS3B1bTFNX1ROMFR4aElBMW8NCg&updated=1762343212733)
|
||||
@@ -0,0 +1,100 @@
|
||||
# ADR-0005: Polyglotte Persistenz
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert
|
||||
|
||||
## Kontext
|
||||
|
||||
Als Teil unserer Microservices-Architektur ([ADR-0003](0003-microservices-architecture-de.md)) mussten wir die am besten
|
||||
geeignete Datenspeicherstrategie bestimmen. Verschiedene Teile unseres Systems haben unterschiedliche Anforderungen an
|
||||
die Datenspeicherung:
|
||||
|
||||
1. Einige Daten erfordern starke Konsistenz und komplexe Beziehungen
|
||||
2. Einige Daten müssen mit sehr geringer Latenz abgerufen werden
|
||||
3. Einige Daten sind ereignisbasiert und müssen in einem Zeitreihenformat gespeichert werden
|
||||
4. Verschiedene Dienste haben unterschiedliche Datenzugriffsmuster
|
||||
|
||||
Ein Einheitsansatz für die Datenspeicherung würde Kompromisse erzwingen, die die Leistung, Skalierbarkeit oder
|
||||
Entwicklungsproduktivität beeinträchtigen könnten.
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Wir haben uns entschieden, eine polyglotte Persistenzstrategie zu implementieren, die verschiedene
|
||||
Datenspeichertechnologien für verschiedene Anwendungsfälle nutzt:
|
||||
|
||||
1. **PostgresQL**: Als primäre relationale Datenbank zur Speicherung strukturierter Daten mit komplexen Beziehungen
|
||||
|
||||
- Wird von allen Domänendiensten für ihre primäre Datenspeicherung verwendet
|
||||
- Jeder Dienst hat sein eigenes Datenbankschema, um Isolation zu gewährleisten
|
||||
|
||||
2. **Redis**: Als verteilter Cache für schnellen Datenzugriff
|
||||
|
||||
- Wird für das Caching häufig abgerufener Daten verwendet
|
||||
- Wird für die Sitzungsspeicherung verwendet
|
||||
- Wird für Rate-Limiting verwendet
|
||||
|
||||
3. **Kafka**: Als Event-Store für Event Sourcing
|
||||
|
||||
- Wird zur Speicherung von Domänenereignissen für Event Sourcing verwendet
|
||||
- Ermöglicht Event-Replay zum Wiederaufbau des Zustands
|
||||
|
||||
4. **Elasticsearch** (geplant): für Volltextsuchfunktionen
|
||||
|
||||
- Wird für erweiterte Suchfunktionen über mehrere Domänen hinweg verwendet werden
|
||||
|
||||
Jeder Dienst ist für die Verwaltung seiner eigenen Datenspeicherung verantwortlich, und Dienste dürfen nicht direkt auf
|
||||
die Datenbanken anderer Dienste zugreifen.
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positive
|
||||
|
||||
- **Optimierte Leistung**: Jede Art von Daten wird in der am besten geeigneten Speichertechnologie gespeichert
|
||||
- **Skalierbarkeit**: Verschiedene Speichertechnologien können unabhängig voneinander basierend auf ihren spezifischen
|
||||
Anforderungen skaliert werden
|
||||
- **Flexibilität**: Teams können die beste Speichertechnologie für ihre spezifischen Anwendungsfälle wählen
|
||||
- **Resilienz**: Probleme mit einer Speichertechnologie beeinträchtigen nicht unbedingt andere
|
||||
|
||||
### Negative
|
||||
|
||||
- **Betriebliche Komplexität**: Mehrere Speichertechnologien müssen bereitgestellt, überwacht und gewartet werden
|
||||
- **Herausforderungen bei der Datenkonsistenz**: Die Aufrechterhaltung der Konsistenz über verschiedene
|
||||
Speichertechnologien hinweg erfordert sorgfältiges Design
|
||||
- **Lernkurve**: Teams müssen mit mehreren Speichertechnologien vertraut sein
|
||||
- **Komplexität bei Backup und Wiederherstellung**: Verschiedene Speichertechnologien haben unterschiedliche Backup- und
|
||||
Wiederherstellungsverfahren
|
||||
|
||||
### Neutral
|
||||
|
||||
- **Daten-Governance**: Umfassende Daten-Governance ist über alle Speichertechnologien hinweg erforderlich
|
||||
- **Überwachungsbedarf**: Jede Speichertechnologie erfordert ihren eigenen Überwachungsansatz
|
||||
|
||||
## Betrachtete Alternativen
|
||||
|
||||
### Einzelne Datenbank für alle Dienste
|
||||
|
||||
Wir haben die Verwendung einer einzelnen PostgresQL-Datenbank mit separaten Schemas für jeden Dienst in Betracht
|
||||
gezogen. Dies hätte den Betrieb vereinfacht, hätte aber einen Single Point of Failure geschaffen und hätte es uns nicht
|
||||
ermöglicht, für verschiedene Datenzugriffsmuster zu optimieren.
|
||||
|
||||
### Datenbank pro Dienst, gleiche Technologie
|
||||
|
||||
Wir haben die Verwendung von PostgresQL für alle Dienste, aber mit separaten Datenbanken in Betracht gezogen. Dies hätte
|
||||
Dienstisolation geboten und gleichzeitig den Betrieb vereinfacht, hätte es uns aber nicht ermöglicht, für verschiedene
|
||||
Datenzugriffsmuster zu optimieren.
|
||||
|
||||
### Vollständig verteilter NoSQL-Ansatz
|
||||
|
||||
Wir haben die Verwendung eines vollständig verteilten NoSQL-Ansatzes mit Technologien wie Cassandra oder MongoDB für die
|
||||
gesamte Datenspeicherung in Betracht gezogen. Dies hätte eine ausgezeichnete Skalierbarkeit geboten, hätte aber die
|
||||
Modellierung komplexer Beziehungen erschwert und hätte signifikante Änderungen an unseren Entwicklungspraktiken
|
||||
erfordert.
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [Polyglot Persistence von Martin Fowler](https://meldestelle-pro.youtrack.cloud/api/files/526-28?sign=MTc2MjU2MDAwMDAwMHwyLTF8NTI2LTI4fERaVkFWVmlEbVJJbTVZSFE2SWlrbmRydHNaeDdxZUFaRExpdkNxbk9wVEkNCg&updated=1762343428460)
|
||||
- [PostgresQL Dokumentation](https://www.postgresql.org/docs/)
|
||||
- [Redis Dokumentation](https://redis.io/documentation)
|
||||
- [Apache Kafka Dokumentation](https://kafka.apache.org/documentation/)
|
||||
- [Elasticsearch Dokumentation](https://www.elastic.co/docs/solutions/search)
|
||||
@@ -0,0 +1,90 @@
|
||||
# ADR-0006: Authentifizierung und Autorisierung mit Keycloak
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert
|
||||
|
||||
## Kontext
|
||||
|
||||
Als Teil unserer Microservices-Architektur ([ADR-0003](0003-microservices-architecture-de.md)) benötigten wir eine
|
||||
robuste und zentralisierte Lösung für Authentifizierung und Autorisierung. Zu den wichtigsten Anforderungen gehörten:
|
||||
|
||||
1. Single Sign-On (SSO) über alle Dienste und Anwendungen hinweg
|
||||
2. Unterstützung für mehrere Authentifizierungsmethoden (Benutzername/Passwort, OAuth, SAML)
|
||||
3. Feingranulare Autorisierung mit rollenbasierter Zugriffssteuerung (RBAC)
|
||||
4. Benutzerverwaltungsfunktionen einschließlich Selbstregistrierung und Profilmanagement
|
||||
5. Integration mit externen Identitätsanbietern
|
||||
6. Sicherheits-Best-Practices einschließlich Passwortrichtlinien und Kontosperrung
|
||||
7. Tokenbasierte Authentifizierung für die Kommunikation zwischen Diensten
|
||||
|
||||
Die Implementierung dieser Funktionen von Grund auf wäre zeitaufwändig und fehleranfällig und würde Ressourcen von
|
||||
unserer Kerngeschäftsfunktionalität abziehen.
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Wir haben uns entschieden, Keycloak (Version 26.4.2) als unsere Identitäts- und Zugriffsverwaltungslösung zu verwenden.
|
||||
Keycloak ist eine Open-Source-Identitäts- und Zugriffsverwaltungslösung, die Folgendes bietet:
|
||||
|
||||
1. **Benutzerauthentifizierung**: Mehrere Authentifizierungsmethoden und -abläufe
|
||||
2. **Benutzerföderation**: Integration mit LDAP, Active Directory und anderen Benutzerspeichern
|
||||
3. **Identitätsvermittlung**: Integration mit externen Identitätsanbietern (Google, Facebook usw.)
|
||||
4. **Single Sign-On**: Über alle Anwendungen und Dienste hinweg
|
||||
5. **Feingranulare Autorisierung**: Rollen- und attributbasierte Zugriffssteuerung
|
||||
6. **Benutzerverwaltung**: Selbstregistrierung, Profilmanagement, Passwortrichtlinien
|
||||
7. **Tokenbasierte Authentifizierung**: JWT-Tokens für die Kommunikation zwischen Diensten
|
||||
|
||||
Unsere Implementierung umfasst:
|
||||
|
||||
- Keycloak-Server, der als containerised Dienst bereitgestellt wird
|
||||
- Integration mit unserem API-Gateway für die Token-Validierung
|
||||
- Client-Adapter für unsere Dienste und Anwendungen
|
||||
- Benutzerdefinierte Themes und E-Mail-Vorlagen
|
||||
- Rollen- und Gruppendefinitionen, die auf unser Domänenmodell abgestimmt sind
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positive
|
||||
|
||||
- **Umfassende Lösung**: Keycloak bietet eine vollständige Identitäts- und Zugriffsverwaltungslösung
|
||||
- **Standards-Konformität**: Keycloak implementiert Industriestandards (OAuth 2.0, OpenID Connect, SAML)
|
||||
- **Reduzierter Entwicklungsaufwand**: Wir müssen Authentifizierung und Autorisierung nicht von Grund auf implementieren
|
||||
- **Sicherheit**: Keycloak folgt Sicherheits-Best-Practices und wird aktiv gewartet
|
||||
- **Flexibilität**: Keycloak unterstützt mehrere Authentifizierungsmethoden und Identitätsanbieter
|
||||
|
||||
### Negative
|
||||
|
||||
- **Betriebliche Komplexität**: Keycloak fügt einen weiteren Dienst hinzu, der bereitgestellt und gewartet werden muss
|
||||
- **Lernkurve**: Teams müssen Keycloak-Konzepte und APIs erlernen
|
||||
- **Leistungsüberlegungen**: Die Token-Validierung fügt den Anfragen einen gewissen Overhead hinzu
|
||||
- **Abhängigkeit**: Wir sind für Authentifizierung und Autorisierung von Keycloak abhängig
|
||||
|
||||
### Neutral
|
||||
|
||||
- **Konfigurationsbedarf**: Keycloak erfordert sorgfältige Konfiguration, um mit unseren Sicherheitsanforderungen
|
||||
übereinzustimmen
|
||||
- **Upgrade-Management**: Keycloak-Upgrades müssen sorgfältig verwaltet werden
|
||||
|
||||
## Betrachtete Alternativen
|
||||
|
||||
### Eigener Authentifizierungsdienst
|
||||
|
||||
Wir haben in Betracht gezogen, unseren eigenen Authentifizierungsdienst zu entwickeln. Dies hätte uns vollständige
|
||||
Kontrolle über die Implementierung gegeben, hätte aber erheblichen Entwicklungsaufwand und laufende Wartung erfordert.
|
||||
|
||||
### Auth0
|
||||
|
||||
Wir haben die Verwendung von Auth0, einer kommerziellen Identity-as-a-Service (IDaaS)-Lösung, in Betracht gezogen. Auth0
|
||||
hätte ähnliche Funktionen wie Keycloak mit weniger betrieblichem Overhead geboten, hätte aber laufende Kosten und
|
||||
potenzielle Anbieterabhängigkeit mit sich gebracht.
|
||||
|
||||
### Spring Security mit JWT
|
||||
|
||||
Wir haben die Verwendung von Spring Security mit JWT-Tokens für Authentifizierung und Autorisierung in Betracht gezogen.
|
||||
Dies hätte sich gut in unsere Spring-basierten Dienste integriert, hätte aber mehr Entwicklungsaufwand erfordert und
|
||||
hätte nicht die umfassenden Identitätsverwaltungsfunktionen von Keycloak geboten.
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [Keycloak Dokumentation](https://www.keycloak.org/documentation)
|
||||
- [OAuth 2.0 und OpenID Connect](https://oauth.net/2/)
|
||||
- [JWT (JSON Web Tokens)](https://jwt.io/)
|
||||
@@ -0,0 +1,92 @@
|
||||
# ADR-0007: API-Gateway-Muster
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert
|
||||
|
||||
## Kontext
|
||||
|
||||
Mit unserer Microservices-Architektur ([ADR-0003](0003-microservices-architecture-de.md)) standen wir vor mehreren
|
||||
Herausforderungen im Zusammenhang mit der Client-Service-Kommunikation:
|
||||
|
||||
1. Clients müssten die Standorte und Schnittstellen mehrerer Dienste kennen
|
||||
2. Verschiedene Clients (Web, Desktop, Mobil) müssten mehrere Aufrufe an verschiedene Dienste tätigen
|
||||
3. Authentifizierung und Autorisierung müssten konsistent über alle Dienste hinweg implementiert werden
|
||||
4. Querschnittsbelange wie Rate-Limiting, Logging und Monitoring müssten in jedem Dienst implementiert werden
|
||||
5. API-Versionierung und Abwärtskompatibilität müssten über alle Dienste hinweg verwaltet werden
|
||||
6. Die Netzwerksicherheit wäre komplexer, wenn mehrere Dienste direkt exponiert würden
|
||||
|
||||
Wir benötigten eine Lösung, die die Client-Service-Kommunikation vereinfachen und gleichzeitig diese Herausforderungen
|
||||
adressieren würde.
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Wir haben uns entschieden, das API-Gateway-Muster mit Spring Cloud Gateway (Spring Boot) zu implementieren. Das
|
||||
API-Gateway dient als einziger Eingangspunkt für alle Client-Anfragen und bietet die folgenden Funktionen:
|
||||
|
||||
1. **Anfrage-Routing**: Deklaratives Routing auf Basis von Prädikaten und Filtern
|
||||
2. **Authentifizierung und Autorisierung**: Integration mit
|
||||
Keycloak ([ADR-0006](0006-authentication-authorization-keycloak-de.md)), Validierung über JWKs; Kontext-Propagation
|
||||
zu Backends
|
||||
3. **Rate-Limiting**: Token-Bucket/Burst-Limits via Gateway-Filter (optional Redis-gestützt)
|
||||
4. **Anfrage/Antwort-Transformation**: Manipulation von Headern/Body per Global/Gateway-Filtern
|
||||
5. **Logging und Monitoring**: Micrometer/Prometheus, strukturierte Logs, verteiltes Tracing
|
||||
6. **Caching**: Selektiv per Downstream oder Reverse-Proxy; Gateway-seitig per Filter möglich
|
||||
7. **API-Dokumentation**: Aggregation/Weiterleitung von OpenAPI-Dokumentation
|
||||
8. **Service-Discovery**: Integration mit Consul/Eureka
|
||||
|
||||
Unsere Implementierung umfasst:
|
||||
|
||||
- Eine Spring-Cloud-Gateway-Applikation (Spring Boot), containerized
|
||||
- Integration mit Keycloak für Authentifizierung und Autorisierung
|
||||
- Benutzerdefinierte Global/Gateway-Filter für Rate-Limiting, Logging, Monitoring
|
||||
- Micrometer/Actuator für Metriken und Health
|
||||
- Service-Discovery-Integration
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positive
|
||||
|
||||
- **Vereinfachte Client-Entwicklung**: Clients müssen nur mit einem einzigen Endpunkt kommunizieren
|
||||
- **Konsistente Sicherheit**: Authentifizierung und Autorisierung werden konsistent gehandhabt
|
||||
- **Zentralisierte Querschnittsbelange**: Rate-Limiting, Logging und Monitoring werden einmal implementiert
|
||||
- **Verbesserte Sicherheit**: Interne Dienste werden nicht direkt Clients ausgesetzt
|
||||
- **Flexibilität**: Das Gateway kann Anfragen und Antworten für verschiedene Clients anpassen
|
||||
|
||||
### Negative
|
||||
|
||||
- **Single Point of Failure**: Das Gateway wird zu einer kritischen Komponente, die hochverfügbar sein muss
|
||||
- **Leistung-Overhead**: Anfragen durchlaufen einen zusätzlichen Netzwerk-Hop
|
||||
- **Komplexität**: Das Gateway muss eine breite Palette von Funktionalitäten handhaben
|
||||
- **Entwicklung-Engpass**: Änderungen am Gateway können Koordination über Teams hinweg erfordern
|
||||
|
||||
### Neutral
|
||||
|
||||
- **Deployment-Überlegungen**: Das Gateway muss angemessen bereitgestellt und skaliert werden
|
||||
- **Versionierungsstrategie**: API-Versionierung muss immer noch verwaltet werden, wenn auch an einem Ort
|
||||
|
||||
## Betrachtete Alternativen
|
||||
|
||||
### Direkte Client-zu-Service-Kommunikation
|
||||
|
||||
Wir haben in Betracht gezogen, Clients die direkte Kommunikation mit Diensten zu ermöglichen. Dies hätte den
|
||||
Netzwerk-Hop durch das Gateway eliminiert, hätte aber die Client-Entwicklung komplexer gemacht und hätte die
|
||||
Implementierung von Querschnittsbelangen in jedem Dienst erfordert.
|
||||
|
||||
### Backend for Frontend (BFF)-Muster
|
||||
|
||||
Wir haben die Implementierung separater Backend for Frontend (BFF)-Dienste für jeden Client-Typ in Betracht gezogen.
|
||||
Dies hätte mehr klientenspezifische Optimierungen ermöglicht, hätte aber den Entwicklungs- und Betriebsaufwand erhöht.
|
||||
|
||||
### Service Mesh
|
||||
|
||||
Wir haben die Verwendung eines Service Mesh wie Istio oder Linkerd zur Handhabung der Service-zu-Service-Kommunikation
|
||||
in Betracht gezogen. Dies hätte viele der gleichen Vorteile für die Service-zu-Service-Kommunikation geboten, hätte aber
|
||||
die Herausforderungen der Client-zu-Service-Kommunikation nicht so effektiv adressiert.
|
||||
|
||||
## Referenzen
|
||||
|
||||
- <https://spring.io/projects/spring-cloud-gateway>
|
||||
- <https://docs.spring.io/spring-boot/docs/current/reference/html/actuator.html>
|
||||
- <https://www.keycloak.org/documentation>
|
||||
- <https://microservices.io/patterns/apigateway.html>
|
||||
@@ -0,0 +1,99 @@
|
||||
# ADR-0008: Multiplatform-Client-Anwendungen
|
||||
|
||||
## Status
|
||||
|
||||
Akzeptiert
|
||||
|
||||
## Kontext
|
||||
|
||||
Unser System benötigt Client-Anwendungen für verschiedene Benutzerrollen und Plattformen:
|
||||
|
||||
1. Desktop-Anwendungen für Administratoren und Veranstaltungsorganisatoren, die umfangreiche Funktionalität benötigen
|
||||
2. Web-Anwendungen für Mitglieder und Pferdebesitzer, die von verschiedenen Geräten aus auf das System zugreifen müssen
|
||||
3. Potenzielle zukünftige mobile Anwendungen für den Zugriff unterwegs
|
||||
|
||||
Die Entwicklung und Wartung separater Codebasen für jede Plattform würde erfordern:
|
||||
|
||||
- Doppelte Implementierung von Geschäftslogik und UI-Komponenten
|
||||
- Mehrere Teams mit unterschiedlicher Plattformexpertise
|
||||
- Koordination, um eine konsistente Benutzererfahrung über Plattformen hinweg zu gewährleisten
|
||||
- Höhere Wartungskosten, da Funktionen und Fehlerbehebungen mehrfach implementiert werden müssten
|
||||
|
||||
Wir benötigten eine Lösung, die es uns ermöglicht, Code über Plattformen hinweg zu teilen und gleichzeitig auf jeder
|
||||
Plattform eine native Benutzererfahrung zu bieten.
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Wir haben uns entschieden, Kotlin Multiplatform und Compose Multiplatform für unsere Client-Anwendungen zu verwenden:
|
||||
|
||||
1. **Kotlin Multiplatform**: Ermöglicht die gemeinsame Nutzung von Geschäftslogik, Datenmodellen und API-Client-Code
|
||||
über Plattformen hinweg
|
||||
2. **Compose Multiplatform**: Bietet ein deklaratives UI-Framework, das auf Desktop-, Web- und mobilen Plattformen
|
||||
funktioniert
|
||||
|
||||
Unsere Implementierung umfasst:
|
||||
|
||||
- **common-ui**: Gemeinsame UI-Komponenten und Geschäftslogik
|
||||
- **desktop-app**: Desktop-Anwendung für Administratoren und Veranstaltungsorganisatoren
|
||||
- **web-app**: Web-Anwendung für Mitglieder und Pferdebesitzer
|
||||
|
||||
Die Architektur folgt einem Model-View-ViewModel (MVVM)-Muster:
|
||||
|
||||
- **Model**: Gemeinsame Datenmodelle und Repository-Implementierungen
|
||||
- **ViewModel**: Gemeinsame Geschäftslogik und Zustandsverwaltung
|
||||
- **View**: Plattformspezifische UI-Implementierungen mit Compose Multiplatform
|
||||
|
||||
Wir verwenden einen modularen Ansatz, bei dem plattformspezifischer Code minimiert wird und der größte Teil des Codes
|
||||
über Plattformen hinweg geteilt wird.
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
### Positive
|
||||
|
||||
- **Codesharing**: Wesentliche Teile des Codes werden über Plattformen hinweg geteilt, was Duplizierung reduziert
|
||||
- **Konsistente Benutzererfahrung**: UI-Komponenten und Verhalten sind über Plattformen hinweg konsistent
|
||||
- **Einheitliche Sprache**: Kotlin wird für alle Plattformen verwendet, was die Entwicklung vereinfacht
|
||||
- **Reduzierter Wartungsaufwand**: Fehlerbehebungen und Funktionen können einmal implementiert und über Plattformen
|
||||
hinweg angewendet werden
|
||||
- **Team-Effizienz**: Entwickler können mit demselben Skillset an mehreren Plattformen arbeiten
|
||||
|
||||
### Negative
|
||||
|
||||
- **Lernkurve**: Kotlin Multiplatform und Compose Multiplatform haben eine Lernkurve
|
||||
- **Reife**: Compose Multiplatform entwickelt sich noch weiter, besonders für Web-Targets
|
||||
- **Leistungsüberlegungen**: Es kann im Vergleich zu Plattform nativen Lösungen zu Leistungs-Overhead kommen
|
||||
- **Plattformspezifische Funktionen**: Einige plattformspezifische Funktionen können schwieriger zu implementieren sein
|
||||
- **Debugging-Komplexität**: Das Debugging über Plattformen hinweg kann komplexer sein
|
||||
|
||||
### Neutral
|
||||
|
||||
- **Komplexität des Build-Systems**: Das Build-System ist mit Multiplatform-Targets komplexer
|
||||
- **Abhängigkeitsverwaltung**: Die Verwaltung von Abhängigkeiten über Plattformen hinweg erfordert sorgfältige
|
||||
Überlegungen
|
||||
|
||||
## Betrachtete Alternativen
|
||||
|
||||
### Separate native Anwendungen
|
||||
|
||||
Wir haben die Entwicklung separater nativer Anwendungen für jede Plattform in Betracht gezogen (Java/JavaFX für Desktop,
|
||||
JavaScript/React für Web). Dies hätte die beste Leistung und Zugriff auf Plattformfunktionen geboten, hätte aber eine
|
||||
doppelte Implementierung von Geschäftslogik und UI-Komponenten erfordert.
|
||||
|
||||
### React Native
|
||||
|
||||
Wir haben die Verwendung von React Native für Mobile und Web mit einer separaten Desktop-Anwendung in Betracht gezogen.
|
||||
Dies hätte Codesharing zwischen Mobile und Web ermöglicht, hätte aber immer noch eine separate Desktop-Lösung erfordert
|
||||
und hätte JavaScript-Expertise erfordert.
|
||||
|
||||
### Flutter
|
||||
|
||||
Wir haben die Verwendung von Flutter für alle Plattformen in Betracht gezogen. Flutter bietet gute
|
||||
plattformübergreifende Unterstützung, hätte aber das Erlernen von Dart erfordert und hätte weniger Integration mit
|
||||
unseren Kotlin-basierten Backend-Diensten gehabt.
|
||||
|
||||
## Referenzen
|
||||
|
||||
- [Kotlin Multiplatform Dokumentation](https://kotlinlang.org/docs/multiplatform.html)
|
||||
- [Compose Multiplatform Dokumentation](https://www.jetbrains.com/lp/compose-multiplatform/)
|
||||
- [MVVM-Architekturmuster](https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93viewmodel)
|
||||
- [Kotlin Multiplatform Mobile](https://kotlinlang.org/lp/mobile/)
|
||||
@@ -0,0 +1,35 @@
|
||||
# ADR-0009: Final KMP Architecture
|
||||
|
||||
Status: Accepted
|
||||
|
||||
Kontext
|
||||
|
||||
Wir schließen die Architektur-Entscheidungen für das Frontend als Kotlin Multiplatform (KMP) Projekt ab und bestätigen die finalen Bausteine sowie die Modulaufteilung. Die Plattformen Web (JS/WASM) und JVM/Desktop werden unterstützt.
|
||||
|
||||
Entscheidung
|
||||
|
||||
1. Plattformen: Kotlin Multiplatform mit Targets Web (JS/WASM) und JVM/Desktop.
|
||||
2. Dependency Injection: Koin als DI-Framework für gemeinsame und plattformspezifische Layer.
|
||||
3. Persistenz (Offline-First): SQLDelight als lokale Datenbank (Single Source of Truth), synchronisiert im Hintergrund.
|
||||
4. Modulaufteilung im Frontend:
|
||||
- shells: Ausführbare App-Shells (Bootstrap/Assembler, DI-Start, Plattformintegration)
|
||||
- features: Vertikale Slices mit UI, Domain-Logik und Navigation pro Feature
|
||||
- core: Gemeinsame Basis (design-system, domain, network, local-db, navigation)
|
||||
5. Kommunikation: Features reden nicht direkt miteinander; Navigation + Shared-Domain-Modelle in core/domain.
|
||||
|
||||
Begründung
|
||||
|
||||
- KMP erlaubt maximale Codewiederverwendung über Web und JVM bei konsistentem Tooling.
|
||||
- Koin bietet leichtgewichtige, idiomatische DI ohne Code-Generierung, geeignet für KMP.
|
||||
- SQLDelight liefert typsichere Queries, portable Schemas und ist für Offline-First praxiserprobt.
|
||||
- Die Trennung in shells/features/core fördert klare Zuständigkeiten, Testbarkeit und schrittweise Erweiterbarkeit.
|
||||
|
||||
Konsequenzen
|
||||
|
||||
- Projektstruktur und Gradle-Module folgen strikt der Aufteilung in `shells`, `features`, `core`.
|
||||
- Der `apiClient` (core/network) wird via Koin als Named Binding injiziert; manuelles Setzen von Authorization-Headern ist untersagt.
|
||||
- UI liest aus der lokalen Datenbank (SQLDelight); Synchronisation erfolgt über Hintergrundjobs.
|
||||
|
||||
Status / Nacharbeiten
|
||||
|
||||
- Diese ADR konsolidiert die KMP-Entscheidung und ersetzt frühere verstreute Notizen. Weitere Details (z. B. konkrete Module, Pfade) sind in `docs/ARCHITECTURE.md` dokumentiert.
|
||||
@@ -0,0 +1,13 @@
|
||||
Architecture Decision Records (ADRs)
|
||||
|
||||
Dieses Verzeichnis enthält Architekturentscheidungen in kurzer, überprüfbarer Form.
|
||||
|
||||
Namensschema: ADR-XXX-title.md mit fortlaufender Nummerierung.
|
||||
|
||||
- ADR-001 Koin als DI
|
||||
- ADR-002 SQLDelight als Offline-DB
|
||||
- ADR-003 Optimistic Locking (409) als Konfliktstrategie
|
||||
- ADR-004 Freshness UI (Ampel)
|
||||
- ADR-005 Core Domain & Feature Isolation
|
||||
|
||||
Siehe Template: ADR-000-template.md.
|
||||
Reference in New Issue
Block a user