docs(c4): migrate architecture diagrams to draw.io and refine container/workflow visualizations
- Replaced outdated `.puml` and `.mermaid` diagrams with modernized `.drawio` versions for enhanced clarity. - Added `container_diagram.drawio` to depict offline-first architecture and backend synchronization workflow. - Introduced `workflow_turnieranlage.drawio` to visualize the tournament creation process (3-step wizard). - Archived legacy diagrams under `docs/01_Architecture/_archive` for reference.
This commit is contained in:
@@ -1,26 +0,0 @@
|
||||
@startuml C4_Context
|
||||
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Context.puml
|
||||
|
||||
title Systemkontext-Diagramm für Meldestelle
|
||||
|
||||
Person(eventOrganizer, "Veranstaltungsorganisator", "Organisiert und verwaltet Reitsportveranstaltungen")
|
||||
Person(administrator, "Administrator", "Verwaltet Systemkonfiguration und Stammdaten")
|
||||
Person(member, "Mitglied", "Meldet sich für Veranstaltungen an und verwaltet persönliche Informationen")
|
||||
Person(horseOwner, "Pferdebesitzer", "Registriert und verwaltet Pferdeinformationen")
|
||||
|
||||
System(meldestelle, "Meldestelle", "Modulares System zur Verwaltung von Pferdesportveranstaltungen, einschließlich Registrierung von Pferden, Mitgliedern und Veranstaltungen")
|
||||
|
||||
System_Ext(paymentProvider, "Zahlungsanbieter", "Verarbeitet Zahlungen für Veranstaltungsanmeldungen")
|
||||
System_Ext(emailSystem, "E-Mail-System", "Sendet Benachrichtigungen und Bestätigungen")
|
||||
System_Ext(federationSystem, "Reitsportverband-System", "Bietet Validierung von Mitgliedschaften und Pferden")
|
||||
|
||||
Rel(eventOrganizer, meldestelle, "Erstellt und verwaltet Veranstaltungen mit")
|
||||
Rel(administrator, meldestelle, "Konfiguriert und administriert")
|
||||
Rel(member, meldestelle, "Meldet sich für Veranstaltungen an und aktualisiert persönliche Informationen mit")
|
||||
Rel(horseOwner, meldestelle, "Registriert und verwaltet Pferde mit")
|
||||
|
||||
Rel(meldestelle, paymentProvider, "Verarbeitet Zahlungen über")
|
||||
Rel(meldestelle, emailSystem, "Sendet Benachrichtigungen über")
|
||||
Rel(meldestelle, federationSystem, "Validiert Mitgliedschaften und Pferde mit")
|
||||
|
||||
@enduml
|
||||
@@ -1,75 +0,0 @@
|
||||
@startuml C4_Container
|
||||
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Container.puml
|
||||
|
||||
title Container-Diagramm für Meldestelle
|
||||
|
||||
Person(eventOrganizer, "Veranstaltungsorganisator", "Organisiert und verwaltet Reitsportveranstaltungen")
|
||||
Person(administrator, "Administrator", "Verwaltet Systemkonfiguration und Stammdaten")
|
||||
Person(member, "Mitglied", "Meldet sich für Veranstaltungen an und verwaltet persönliche Informationen")
|
||||
Person(horseOwner, "Pferdebesitzer", "Registriert und verwaltet Pferdeinformationen")
|
||||
|
||||
System_Boundary(meldestelle, "Meldestelle") {
|
||||
Container(desktopApp, "Desktop-Anwendung", "Kotlin, Compose Multiplatform", "Bietet eine umfangreiche Benutzeroberfläche für Administratoren und Veranstaltungsorganisatoren")
|
||||
Container(webApp, "Web-Anwendung", "Kotlin, Compose Multiplatform", "Bietet eine Weboberfläche für Mitglieder und Pferdebesitzer")
|
||||
|
||||
Container(apiGateway, "API-Gateway", "Kotlin, Spring Cloud Gateway", "Leitet Anfragen an entsprechende Dienste weiter, verwaltet Authentifizierung und Autorisierung")
|
||||
|
||||
Container(masterdataService, "Stammdaten-Dienst", "Kotlin, Spring Boot", "Verwaltet Stammdaten wie Standorte, Disziplinen usw.")
|
||||
Container(membersService, "Mitglieder-Dienst", "Kotlin, Spring Boot", "Verwaltet Mitgliederregistrierung und -profile")
|
||||
Container(horsesService, "Pferde-Dienst", "Kotlin, Spring Boot", "Verwaltet Pferderegistrierung und -informationen")
|
||||
Container(eventsService, "Veranstaltungs-Dienst", "Kotlin, Spring Boot", "Verwaltet Veranstaltungserstellung, -planung und -anmeldungen")
|
||||
|
||||
ContainerDb(postgresql, "PostgreSQL", "Datenbank", "Speichert alle persistenten Daten")
|
||||
ContainerDb(redis, "Redis", "Cache", "Bietet Caching für häufig abgerufene Daten")
|
||||
Container(kafka, "Kafka", "Message Broker", "Verarbeitet ereignisgesteuerte Kommunikation zwischen Diensten")
|
||||
Container(keycloak, "Keycloak", "Authentifizierungsserver", "Verwaltet Benutzerauthentifizierung und -autorisierung")
|
||||
|
||||
Container(monitoring, "Monitoring", "Prometheus, Grafana, Zipkin", "Bietet Überwachung, Metriken und verteiltes Tracing")
|
||||
}
|
||||
|
||||
System_Ext(paymentProvider, "Zahlungsanbieter", "Verarbeitet Zahlungen für Veranstaltungsanmeldungen")
|
||||
System_Ext(emailSystem, "E-Mail-System", "Sendet Benachrichtigungen und Bestätigungen")
|
||||
System_Ext(federationSystem, "Reitsportverband-System", "Bietet Validierung von Mitgliedschaften und Pferden")
|
||||
|
||||
Rel(eventOrganizer, desktopApp, "Verwendet")
|
||||
Rel(administrator, desktopApp, "Verwendet")
|
||||
Rel(member, webApp, "Verwendet")
|
||||
Rel(horseOwner, webApp, "Verwendet")
|
||||
|
||||
Rel(desktopApp, apiGateway, "Stellt API-Aufrufe an", "HTTPS/JSON")
|
||||
Rel(webApp, apiGateway, "Stellt API-Aufrufe an", "HTTPS/JSON")
|
||||
|
||||
Rel(apiGateway, masterdataService, "Leitet Anfragen weiter an", "HTTPS/JSON")
|
||||
Rel(apiGateway, membersService, "Leitet Anfragen weiter an", "HTTPS/JSON")
|
||||
Rel(apiGateway, horsesService, "Leitet Anfragen weiter an", "HTTPS/JSON")
|
||||
Rel(apiGateway, eventsService, "Leitet Anfragen weiter an", "HTTPS/JSON")
|
||||
Rel(apiGateway, keycloak, "Authentifiziert mit", "HTTPS/JSON")
|
||||
|
||||
Rel(masterdataService, postgresql, "Liest von und schreibt in")
|
||||
Rel(membersService, postgresql, "Liest von und schreibt in")
|
||||
Rel(horsesService, postgresql, "Liest von und schreibt in")
|
||||
Rel(eventsService, postgresql, "Liest von und schreibt in")
|
||||
|
||||
Rel(masterdataService, redis, "Speichert Daten im Cache")
|
||||
Rel(membersService, redis, "Speichert Daten im Cache")
|
||||
Rel(horsesService, redis, "Speichert Daten im Cache")
|
||||
Rel(eventsService, redis, "Speichert Daten im Cache")
|
||||
|
||||
Rel(masterdataService, kafka, "Veröffentlicht und abonniert Ereignisse")
|
||||
Rel(membersService, kafka, "Veröffentlicht und abonniert Ereignisse")
|
||||
Rel(horsesService, kafka, "Veröffentlicht und abonniert Ereignisse")
|
||||
Rel(eventsService, kafka, "Veröffentlicht und abonniert Ereignisse")
|
||||
|
||||
Rel(masterdataService, monitoring, "Sendet Metriken und Traces an")
|
||||
Rel(membersService, monitoring, "Sendet Metriken und Traces an")
|
||||
Rel(horsesService, monitoring, "Sendet Metriken und Traces an")
|
||||
Rel(eventsService, monitoring, "Sendet Metriken und Traces an")
|
||||
Rel(apiGateway, monitoring, "Sendet Metriken und Traces an")
|
||||
|
||||
Rel(eventsService, paymentProvider, "Verarbeitet Zahlungen über", "HTTPS/JSON")
|
||||
Rel(membersService, emailSystem, "Sendet Benachrichtigungen über", "SMTP")
|
||||
Rel(eventsService, emailSystem, "Sendet Benachrichtigungen über", "SMTP")
|
||||
Rel(membersService, federationSystem, "Validiert Mitgliedschaften mit", "HTTPS/JSON")
|
||||
Rel(horsesService, federationSystem, "Validiert Pferde mit", "HTTPS/JSON")
|
||||
|
||||
@enduml
|
||||
@@ -1,63 +0,0 @@
|
||||
@startuml C4_Component
|
||||
!include https://raw.githubusercontent.com/plantuml-stdlib/C4-PlantUML/master/C4_Component.puml
|
||||
|
||||
title Komponenten-Diagramm für Veranstaltungs-Dienst
|
||||
|
||||
Container_Boundary(apiGateway, "API-Gateway") {
|
||||
Component(apiGatewayRouting, "Routing-Komponente", "Ktor Routing", "Leitet Anfragen an entsprechende Dienste weiter")
|
||||
Component(apiGatewayAuth, "Authentifizierungs-Komponente", "Ktor Auth", "Verwaltet Authentifizierung und Autorisierung")
|
||||
}
|
||||
|
||||
Container_Boundary(eventsService, "Veranstaltungs-Dienst") {
|
||||
Component(eventsApi, "Veranstaltungs-API", "Kotlin, Spring Web", "Definiert die REST-API-Endpunkte für die Veranstaltungsverwaltung")
|
||||
|
||||
Component(eventsApplication, "Veranstaltungs-Anwendung", "Kotlin, Spring", "Enthält Anwendungsdienste und Anwendungsfälle")
|
||||
Component(eventCommandHandlers, "Veranstaltungs-Befehlshandler", "Kotlin", "Verarbeitet Befehle zum Erstellen und Ändern von Veranstaltungen")
|
||||
Component(eventQueryHandlers, "Veranstaltungs-Abfragehandler", "Kotlin", "Verarbeitet Abfragen zum Abrufen von Veranstaltungsinformationen")
|
||||
|
||||
Component(eventsDomain, "Veranstaltungs-Domäne", "Kotlin", "Enthält Domänenmodelle und Geschäftslogik")
|
||||
Component(eventAggregate, "Veranstaltungs-Aggregat", "Kotlin", "Kern-Domänenentität, die eine Veranstaltung repräsentiert")
|
||||
Component(participantAggregate, "Teilnehmer-Aggregat", "Kotlin", "Kern-Domänenentität, die einen Teilnehmer repräsentiert")
|
||||
Component(eventDomainServices, "Veranstaltungs-Domänendienste", "Kotlin", "Domänendienste für komplexe Geschäftslogik")
|
||||
|
||||
Component(eventsInfrastructure, "Veranstaltungs-Infrastruktur", "Kotlin, Spring Data", "Enthält Infrastrukturimplementierungen")
|
||||
Component(eventRepository, "Veranstaltungs-Repository", "Kotlin, Spring Data JPA", "Speichert und ruft Veranstaltungsdaten ab")
|
||||
Component(eventMessagePublisher, "Veranstaltungs-Nachrichtenveröffentlicher", "Kotlin, Spring Kafka", "Veröffentlicht Domänenereignisse an Kafka")
|
||||
Component(externalServiceClients, "Externe Dienst-Clients", "Kotlin, WebClient", "Clients für externe Dienste")
|
||||
}
|
||||
|
||||
ContainerDb(postgresql, "PostgreSQL", "Datenbank", "Speichert alle persistenten Daten")
|
||||
Container(kafka, "Kafka", "Message Broker", "Verarbeitet ereignisgesteuerte Kommunikation zwischen Diensten")
|
||||
Container(redis, "Redis", "Cache", "Bietet Caching für häufig abgerufene Daten")
|
||||
|
||||
System_Ext(paymentProvider, "Zahlungsanbieter", "Verarbeitet Zahlungen für Veranstaltungsanmeldungen")
|
||||
System_Ext(emailSystem, "E-Mail-System", "Sendet Benachrichtigungen und Bestätigungen")
|
||||
|
||||
Rel(apiGatewayRouting, eventsApi, "Leitet Anfragen weiter an", "HTTPS/JSON")
|
||||
Rel(apiGatewayAuth, eventsApi, "Stellt Authentifizierungskontext bereit für")
|
||||
|
||||
Rel(eventsApi, eventsApplication, "Verwendet")
|
||||
Rel(eventsApplication, eventCommandHandlers, "Verwendet")
|
||||
Rel(eventsApplication, eventQueryHandlers, "Verwendet")
|
||||
|
||||
Rel(eventCommandHandlers, eventsDomain, "Verwendet")
|
||||
Rel(eventQueryHandlers, eventsDomain, "Verwendet")
|
||||
Rel(eventCommandHandlers, eventsInfrastructure, "Verwendet")
|
||||
Rel(eventQueryHandlers, eventsInfrastructure, "Verwendet")
|
||||
|
||||
Rel(eventsDomain, eventAggregate, "Enthält")
|
||||
Rel(eventsDomain, participantAggregate, "Enthält")
|
||||
Rel(eventsDomain, eventDomainServices, "Enthält")
|
||||
|
||||
Rel(eventsInfrastructure, eventRepository, "Enthält")
|
||||
Rel(eventsInfrastructure, eventMessagePublisher, "Enthält")
|
||||
Rel(eventsInfrastructure, externalServiceClients, "Enthält")
|
||||
|
||||
Rel(eventRepository, postgresql, "Liest von und schreibt in")
|
||||
Rel(eventMessagePublisher, kafka, "Veröffentlicht Nachrichten an")
|
||||
Rel(eventQueryHandlers, redis, "Speichert Ergebnisse im Cache")
|
||||
|
||||
Rel(externalServiceClients, paymentProvider, "Stellt API-Aufrufe an", "HTTPS/JSON")
|
||||
Rel(externalServiceClients, emailSystem, "Sendet E-Mails über", "SMTP")
|
||||
|
||||
@enduml
|
||||
@@ -1,158 +0,0 @@
|
||||
@startuml
|
||||
skinparam handwritten false
|
||||
skinparam monochrome false
|
||||
skinparam packageStyle rectangle
|
||||
skinparam shadowing false
|
||||
hide empty members
|
||||
|
||||
title Domain Model: Umbenennung & Erweiterung (Soll-Zustand)
|
||||
|
||||
package "Event Management Context" {
|
||||
class Veranstaltung <<Tenant Boundary>> {
|
||||
+ id: UUID
|
||||
+ name: String
|
||||
+ ort: String
|
||||
+ startDatum: LocalDate
|
||||
+ endDatum: LocalDate
|
||||
-- ZNS.zip Upload (Stammdaten) --
|
||||
}
|
||||
|
||||
class Austragungsplatz {
|
||||
+ id: UUID
|
||||
+ name: String (z.B. "Waldarena")
|
||||
+ typ: String ("Austragungsplatz", "Vorbereitungsplatz")
|
||||
+ sparte: SparteE [0..1]
|
||||
}
|
||||
|
||||
class Turnier {
|
||||
+ id: UUID
|
||||
+ turnierNummer: String (z.B. "26128")
|
||||
+ sparte: SparteE
|
||||
+ kategorie: TurnierkategorieE
|
||||
+ nennschluss: DateTime
|
||||
+ einschraenkungen: List<TeilnehmerKreisE>
|
||||
-- n2-xxxxx.dat Upload --
|
||||
+ turnierbeauftragterId: UUID
|
||||
}
|
||||
|
||||
class Ausschreibung {
|
||||
+ id: UUID
|
||||
+ titel: String
|
||||
+ status: AusschreibungsStatusE
|
||||
}
|
||||
}
|
||||
|
||||
package "Billing Context" {
|
||||
class TurnierArtikel {
|
||||
+ id: UUID
|
||||
+ name: String (z.B. "Ansage", "Heu")
|
||||
+ preis: Money
|
||||
+ typ: String ("AUTOMATISCH", "MANUELL")
|
||||
}
|
||||
|
||||
class Konto {
|
||||
+ id: UUID
|
||||
+ saldo: Money
|
||||
}
|
||||
}
|
||||
|
||||
package "Competition Context" {
|
||||
class Bewerb {
|
||||
+ id: UUID
|
||||
+ bewerbNummer: Int (z.B. 14)
|
||||
+ bezeichnung: String (z.B. "Standardspringprüfung")
|
||||
+ beschreibung: String (z.B. "Pony Einsteiger Cup")
|
||||
+ klasse: String (z.B. "LM")
|
||||
+ richtverfahren: PruefungsTypE
|
||||
+ aufgabe: String (z.B. "R1")
|
||||
+ geldpreisAusbezahlt: Boolean
|
||||
+ reitdauerMinuten: Int
|
||||
+ umbauMinuten: Int
|
||||
+ besichtigungMinuten: Int
|
||||
--
|
||||
+ teilungsTyp: AbteilungsTeilungsTypE (+ MANUELL)
|
||||
}
|
||||
|
||||
class RichterEinsatz {
|
||||
+ funktionaerId: UUID
|
||||
+ position: String (z.B. "C", "Aufsicht")
|
||||
}
|
||||
|
||||
class Abteilung {
|
||||
+ id: UUID
|
||||
+ abteilungsNummer: Int
|
||||
+ bezeichnung: String
|
||||
}
|
||||
}
|
||||
|
||||
package "Registration Context" {
|
||||
class Nennung {
|
||||
+ id: UUID
|
||||
+ status: NennStatusE
|
||||
+ istNachnennung: Boolean
|
||||
+ reiterId: UUID
|
||||
+ pferdId: UUID
|
||||
}
|
||||
|
||||
class NennungsTransfer {
|
||||
+ id: UUID
|
||||
+ ursprungsNennungId: UUID
|
||||
+ neueNennungId: UUID
|
||||
}
|
||||
}
|
||||
|
||||
package "Actor Context (Masterdata)" {
|
||||
class Reiter {
|
||||
+ id: UUID
|
||||
+ name: String
|
||||
}
|
||||
class Pferd {
|
||||
+ id: UUID
|
||||
+ name: String
|
||||
}
|
||||
class Funktionaer {
|
||||
+ id: UUID
|
||||
+ name: String
|
||||
}
|
||||
}
|
||||
|
||||
Veranstaltung "1" *-- "N" Austragungsplatz
|
||||
Veranstaltung "1" *-- "N" TurnierArtikel
|
||||
Veranstaltung "1" *-- "N" Turnier
|
||||
|
||||
Turnier "1" *-- "1" Ausschreibung
|
||||
|
||||
Turnier "1" *-- "N" Bewerb
|
||||
Bewerb "1" *-- "N" Abteilung
|
||||
Bewerb "1" *-- "N" RichterEinsatz
|
||||
|
||||
Bewerb "N" --> "1" Austragungsplatz : "findet statt auf"
|
||||
|
||||
Abteilung "1" <-- "N" Nennung : "teilt zu"
|
||||
Bewerb "1" <.. "N" Nennung : "meldet für (Denormalisiert)"
|
||||
|
||||
Nennung "1" <-- "N" NennungsTransfer : "dokumentiert Storno/Umbuchung"
|
||||
|
||||
TurnierArtikel "1" <-- "N" Konto : "bucht"
|
||||
|
||||
|
||||
note right of Bewerb
|
||||
**Namens-Konvention (Das "Dom"-Präfix):**
|
||||
Aktuell heißt diese Klasse im Code z.B. `DomBewerb` (in entries-domain)
|
||||
und `Bewerb` (in entries-service/Repository).
|
||||
Der Prefix `Dom` wurde zur Unterscheidung
|
||||
von DTOs (Data Transfer Objects) und
|
||||
DB-Entities genutzt.
|
||||
|
||||
Ist es clever das zu ändern?
|
||||
-> Ja! In Clean Architecture sollte die
|
||||
Kern-Domäne den "sauberen" Namen tragen
|
||||
(`Bewerb`). Die DB-Klasse heißt dann `BewerbEntity`
|
||||
bzw. `BewerbTable` und das Transfer-Objekt `BewerbDto`.
|
||||
Das gleiche gilt für `DomVeranstaltung` -> `Veranstaltung`,
|
||||
`DomTurnier` -> `Turnier`, `DomAusschreibung` -> `Ausschreibung`,
|
||||
`DomAbteilung` -> `Abteilung`, `DomNennung` -> `Nennung`
|
||||
und `DomNennungsTransfer` -> `NennungsTransfer`.
|
||||
end note
|
||||
|
||||
@enduml
|
||||
@@ -1,80 +0,0 @@
|
||||
@startuml
|
||||
!define table(x) entity x << (T, white) >>
|
||||
!define primary_key(x) <b><color:#b8861b><&key></color> x</b>
|
||||
!define foreign_key(x) <color:#aaaaaa><&key></color> x
|
||||
|
||||
skinparam linetype ortho
|
||||
|
||||
table(Turnier) {
|
||||
primary_key(turnier_id)
|
||||
--
|
||||
name: varchar
|
||||
start_datum: date
|
||||
end_datum: date
|
||||
ort: varchar
|
||||
kategorie_oeto: varchar
|
||||
}
|
||||
|
||||
table(Bewerb) {
|
||||
primary_key(bewerb_id)
|
||||
--
|
||||
foreign_key(turnier_id)
|
||||
nummer: varchar
|
||||
disziplin: varchar
|
||||
klasse: varchar
|
||||
nenngeld: decimal
|
||||
}
|
||||
|
||||
table(Person) {
|
||||
primary_key(person_id)
|
||||
--
|
||||
vorname: varchar
|
||||
nachname: varchar
|
||||
lizenznummer: varchar
|
||||
}
|
||||
|
||||
table(Pferd) {
|
||||
primary_key(pferd_id)
|
||||
--
|
||||
foreign_key(besitzer_person_id)
|
||||
name: varchar
|
||||
lebensnummer: varchar
|
||||
}
|
||||
|
||||
table(Nennung) {
|
||||
primary_key(nennung_id)
|
||||
--
|
||||
foreign_key(bewerb_id)
|
||||
foreign_key(person_id)
|
||||
foreign_key(pferd_id)
|
||||
status: varchar
|
||||
nennungs_datum: timestamp
|
||||
}
|
||||
|
||||
table(Startplatz) {
|
||||
primary_key(startplatz_id)
|
||||
--
|
||||
foreign_key(nennung_id)
|
||||
startnummer: int
|
||||
startzeit: time
|
||||
status: varchar
|
||||
}
|
||||
|
||||
table(Ergebnis) {
|
||||
primary_key(ergebnis_id)
|
||||
--
|
||||
foreign_key(startplatz_id)
|
||||
wertnote: decimal
|
||||
fehler: int
|
||||
zeit: time
|
||||
platzierung: int
|
||||
}
|
||||
|
||||
Turnier ||--o{ Bewerb
|
||||
Bewerb }o--o{ Nennung
|
||||
Person }o--o{ Nennung
|
||||
Pferd }o--o{ Nennung
|
||||
Person }o..o{ Pferd
|
||||
Nennung ||--|{ Startplatz
|
||||
Startplatz ||--|{ Ergebnis
|
||||
@enduml
|
||||
@@ -0,0 +1,66 @@
|
||||
<mxfile host="Electron" modified="2026-04-07T12:00:00.000Z" agent="Lead Architect" version="21.0.0" type="device">
|
||||
<diagram id="c4-container" name="C4 Container Diagram">
|
||||
<mxGraphModel dx="1200" dy="800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
|
||||
<mxCell id="user" value="Veranstalter / Meldestelle" style="shape=umlActor;verticalLabelPosition=bottom;verticalAlign=top;html=1;outlineConnect=0;" vertex="1" parent="1">
|
||||
<mxGeometry x="40" y="240" width="30" height="60" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- KMP Desktop App Container -->
|
||||
<mxCell id="container_app" value="<b>Desktop-Anwendung (Offline-First)</b><br><i>Kotlin, Compose Multiplatform</i><br><br>Bietet die gesamte Meldestellen-Oberfläche, offline-fähig." style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;verticalAlign=top;align=left;spacingTop=4;spacingLeft=8;" vertex="1" parent="1">
|
||||
<mxGeometry x="160" y="200" width="280" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Local DB -->
|
||||
<mxCell id="db_local" value="<b>Lokale Datenbank</b><br><i>SQLite / Room</i><br><br>Speichert alle Turniere, Nennungen lokal für den Offline-Betrieb." style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#ffe6cc;strokeColor=#d79b00;align=left;spacingTop=4;spacingLeft=8;" vertex="1" parent="1">
|
||||
<mxGeometry x="200" y="400" width="200" height="100" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Backend System Boundary -->
|
||||
<mxCell id="system_backend" value="Cloud Backend / API" style="swimlane;whiteSpace=wrap;html=1;startSize=30;fillColor=#f5f5f5;fontColor=#333333;strokeColor=#666666;" vertex="1" parent="1">
|
||||
<mxGeometry x="600" y="80" width="360" height="460" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Backend Containers -->
|
||||
<mxCell id="container_api" value="<b>REST API Services</b><br><i>Ktor / Spring Boot</i><br><br>Bietet die Synchronisations-Schnittstellen für die Desktop-App." style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;verticalAlign=top;align=left;spacingTop=4;spacingLeft=8;" vertex="1" parent="system_backend">
|
||||
<mxGeometry x="40" y="60" width="280" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Remote DB -->
|
||||
<mxCell id="db_remote" value="<b>Zentrale Datenbank</b><br><i>PostgreSQL</i><br><br>Speichert alle Mandanten und Stammdaten." style="shape=cylinder3;whiteSpace=wrap;html=1;boundedLbl=1;backgroundOutline=1;size=15;fillColor=#ffe6cc;strokeColor=#d79b00;align=left;spacingTop=4;spacingLeft=8;" vertex="1" parent="system_backend">
|
||||
<mxGeometry x="80" y="260" width="200" height="100" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- External -->
|
||||
<mxCell id="ext_zns" value="<b>ZNS (OEPS)</b><br><br>Externe Stammdaten (ZIP) und Nennungen (DAT)." style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;verticalAlign=top;align=left;spacingTop=4;spacingLeft=8;" vertex="1" parent="1">
|
||||
<mxGeometry x="1040" y="140" width="200" height="100" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Edges -->
|
||||
<mxCell id="e_user_app" value="nutzt" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=0.5;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="user" target="container_app">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<mxCell id="e_app_local" value="liest/schreibt" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="1" source="container_app" target="db_local">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<mxCell id="e_app_api" value="synchronisiert via HTTPS" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="container_app" target="container_api">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<mxCell id="e_api_db" value="liest/schreibt" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" edge="1" parent="system_backend" source="container_api" target="db_remote">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<mxCell id="e_zns_app" value="Upload (ZIP/DAT)" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=1;entryY=0.25;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="ext_zns" target="container_app">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
@@ -1,33 +0,0 @@
|
||||
C4Container
|
||||
title Container Diagram for Meldestelle System
|
||||
|
||||
Person(user, "User", "Meldestelle Staff")
|
||||
|
||||
System_Boundary(c1, "Meldestelle Platform") {
|
||||
|
||||
Container(webapp, "Single Page App / Desktop App", "Kotlin/Compose", "Provides UI for users")
|
||||
|
||||
Container(gateway, "API Gateway", "Spring Cloud Gateway", "Entry point, Routing, Resilience")
|
||||
|
||||
Container(ping_service, "Ping Service", "Spring Boot", "Handles Ping/Pong & Sync Tests")
|
||||
|
||||
ContainerDb(ping_db, "Ping DB", "PostgreSQL", "Stores Ping Events")
|
||||
ContainerDb(valkey, "Cache", "Valkey (Redis)", "Session Store, Rate Limiting")
|
||||
|
||||
Container(consul, "Service Discovery", "Consul", "Service Registry")
|
||||
Container(zipkin, "Tracing", "Zipkin", "Distributed Tracing")
|
||||
}
|
||||
|
||||
System_Ext(keycloak, "Keycloak", "IAM")
|
||||
|
||||
Rel(user, webapp, "Uses", "HTTPS")
|
||||
Rel(webapp, gateway, "API Requests", "JSON/HTTPS")
|
||||
Rel(webapp, keycloak, "Auth", "OIDC")
|
||||
|
||||
Rel(gateway, ping_service, "Proxies", "HTTP")
|
||||
Rel(gateway, consul, "Discover", "HTTP")
|
||||
Rel(gateway, valkey, "Rate Limit", "Redis Protocol")
|
||||
|
||||
Rel(ping_service, ping_db, "Persist", "JDBC")
|
||||
Rel(ping_service, zipkin, "Trace", "HTTP")
|
||||
Rel(ping_service, consul, "Register", "HTTP")
|
||||
@@ -1,21 +0,0 @@
|
||||
C4Context
|
||||
title System Context Diagram for Meldestelle System
|
||||
|
||||
Person(user, "Meldestelle User", "Nutzer der Web/Desktop App")
|
||||
|
||||
System_Boundary(meldestelle, "Meldestelle System") {
|
||||
System(webapp, "Web/Desktop App", "Kotlin Multiplatform (Compose)", "Frontend für Benutzer")
|
||||
System(gateway, "API Gateway", "Spring Cloud Gateway", "Routing, Auth, Rate Limiting")
|
||||
System(ping, "Ping Service", "Spring Boot", "Tracer Bullet / Health Check Service")
|
||||
System(keycloak, "Identity Provider", "Keycloak", "Authentifizierung & Autorisierung")
|
||||
}
|
||||
|
||||
System_Ext(mail, "Mail Server", "SMTP", "Versendet E-Mails")
|
||||
|
||||
Rel(user, webapp, "Uses", "HTTPS")
|
||||
Rel(webapp, gateway, "API Calls", "HTTPS/JSON (OAuth2)")
|
||||
Rel(webapp, keycloak, "Authenticates", "OIDC")
|
||||
Rel(gateway, ping, "Routes to", "HTTP")
|
||||
Rel(gateway, keycloak, "Validates Token", "JWT")
|
||||
|
||||
UpdateLayoutConfig($c4ShapeInRow="3", $c4BoundaryInRow="1")
|
||||
@@ -0,0 +1,34 @@
|
||||
<mxfile host="Electron" modified="2026-04-07T12:00:00.000Z" agent="Lead Architect" version="21.0.0" type="device">
|
||||
<diagram id="workflow" name="Workflow Turnieranlage">
|
||||
<mxGraphModel dx="1200" dy="800" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
|
||||
<!-- Step 1 -->
|
||||
<mxCell id="step1" value="<b>Schritt 1: Veranstaltung</b><br><br>1. Stammdaten (Name, Ort, Datum)<br>2. ZNS.zip Upload (Reiter/Pferde)<br>3. Austragungsplätze anlegen<br>4. Preisliste (Artikel) anlegen" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#ffe6cc;strokeColor=#d79b00;verticalAlign=top;align=left;spacingTop=4;spacingLeft=8;" vertex="1" parent="1">
|
||||
<mxGeometry x="80" y="80" width="240" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Step 2 -->
|
||||
<mxCell id="step2" value="<b>Schritt 2: Turnier(e)</b><br><br>1. Turnier-Nr (26128) &amp; Reglement<br>2. Sparte &amp; Kategorie (CSN-C)<br>3. Turnierbeauftragter (TB) wählen<br>4. Nennschluss &amp; Gebühren" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;verticalAlign=top;align=left;spacingTop=4;spacingLeft=8;" vertex="1" parent="1">
|
||||
<mxGeometry x="400" y="80" width="240" height="120" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Step 3 -->
|
||||
<mxCell id="step3" value="<b>Schritt 3: Bewerbe</b><br><br>1. Identifikation (Klasse, Aufgabe)<br>2. Finanzen (Startgeld, Preisgeld)<br>3. Zeitplan (Platz, Dauer, Umbau)<br>4. Richter-Zuweisung<br>5. Teilungsregel (z.B. NACH_LIZENZ)" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=#82b366;verticalAlign=top;align=left;spacingTop=4;spacingLeft=8;" vertex="1" parent="1">
|
||||
<mxGeometry x="720" y="80" width="240" height="140" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<!-- Edges -->
|
||||
<mxCell id="edge1" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="step1" target="step2">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
|
||||
<mxCell id="edge2" value="1..N" style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="step2" target="step3">
|
||||
<mxGeometry relative="1" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
Reference in New Issue
Block a user