Fix: Test-Commit für VCS-Integration (MP-8) (#15)
* MP-8 OTHER Implementiere JWT-Authentifizierungs-Filter im Gateway * Fix(ci): Update upload-artifact action to v4 * Fix(ci): Add start command for Keycloak and failure logs * Fix(ci): Remove invalid 'command' property from Keycloak service * Fix(ci): Use KC_DEV_MODE env var to start Keycloak * Fix(ci): Keycloak service was removed from GitHub Actions services and replaced with a manual docker run step that starts Keycloak with the start-dev command. * dev(ci): vereinheitliche Keycloak auf 26.4.2; aktiviere Health im CI (MP-8) * Fix(ci): Stabilize Keycloak startup in integration tests via matrix - Add `dev-file` Keycloak variant to matrix for stability fallback. - Improve wait logic and health checks for Keycloak and Postgres. - Unify Keycloak version to 26.4.2 across codebase. - Add log dumps on failure. * Fix(ci): Die betroffene Datei docs/Visionen-Ideen/Infrastruktur-Strategie_DSGVO-Konformität.md endet aktuell mit genau einer leeren Zeile (Zeile 87). Das entspricht der Regel MD047 („Files should end with a single newline character“). Damit ist deine Korrektur korrekt. * Fix(ci): Repository-wide auto-fix for Markdown files was implemented with a GitHub Actions workflow and a local helper script. EditorConfig and markdownlint ignore files were added to ensure consistent formatting. Instructions for using the auto-fix both via GitHub Actions and locally were provided. * fix(gradle): build.gradle.kts jsBrowser testTask disabled * fix(gradle): build.gradle.kts jsBrowser testTask disabled * Fix(ci): Stabilize integration tests with Keycloak matrix build (MP-8) Introduces a matrix strategy (`keycloak_db: [postgres, dev-file]`) in the integration-tests workflow to mitigate flaky Keycloak starts when using the Postgres service container. - Adds a `dev-file` Keycloak variant for stability fallback. - Improves wait logic and health checks for Keycloak/Postgres. - Unifies Keycloak version to 26.4.2 across codebase (Dockerfile, Compose, ADR, README, tests). - Adds log dumps on failure in CI. - Ensures `KC_HEALTH_ENABLED=true` is set. - Updates related documentation (README, Schlachtplan). - Includes broader Docker SSoT cleanup (versions.toml as source, script updates, env file cleanup, validator hardening). This resolves recurring CI failures related to Keycloak startup and ensures required checks for PRs (#15) are reliable, while also improving overall Docker build consistency. * feat(docs, ci): Implement YouTrack SSoT strategy with Dokka sync (MP-8) - Add Dokka multi-module Gradle configuration and KDoc style guide. - Add GitHub Actions workflow (docs-kdoc-sync.yml) and Python script (youtrack-sync-kb.py) to sync Dokka GFM output to YouTrack KB. - Extend front-matter schema (bc, doc_type) and update relevant pages/stubs. - Adapt CI scripts (validate-frontmatter, check-docs-drift, ci-docs link ignore). - Update README.md to reference YouTrack KB. * feat(docs, ci): Implement YouTrack SSoT strategy with Dokka sync (MP-8) - Add Dokka multi-module Gradle configuration and KDoc style guide. - Add GitHub Actions workflow (docs-kdoc-sync.yml) and Python script (youtrack-sync-kb.py) to sync Dokka GFM output to YouTrack KB. - Extend front-matter schema (bc, doc_type) and update relevant pages/stubs. - Adapt CI scripts (validate-frontmatter, check-docs-drift, ci-docs link ignore). - Update README.md to reference YouTrack KB. * Fix(ci): Replace OpenAPI validator with Spectral Replaces the deprecated 'char0n/swagger-editor-validate' action, which failed due to sandbox issues in GitHub Actions, with the modern '@stoplight/spectral-cli'. This ensures robust OpenAPI specification validation without requiring a headless browser environment. The 'generate-api-docs' job now depends on the successful completion of the Spectral validation. Part of resolving CI failures for PR #15 (MP-8). * Fix(ci): Specify spectral:oas ruleset for OpenAPI validation (MP-8) * Fix(ci): Remove explicit ruleset argument for Spectral validation (MP-8) * Fix(ci): Added a .spectral.yaml file to fix Spectral linting errors. Corrected markdown lint issues in two documentation files. Updated README.md with a new guidelines section to fix link validation errors. * Fix(ci): Markdownlint errors were fixed by adding required blank lines. The Guidelines Validation error was resolved by updating the README.md link. The API Documentation Generator workflow was stabilized by updating paths, tasks, and validation steps. * Fix(ci): Alle vier fehlerhaften GitHub-Action-Prüfungen wurden behoben. Fehler in der OpenAPI-Spezifikation, Probleme mit der Markdown-Linting-Analyse und Validierungsfehler bei Querverweisen wurden korrigiert. Die README.md enthält nun alle erforderlichen Links zu den Richtlinien. * Fix(ci): Markdown linting errors in docs/api/README.md were fixed by specifying languages in fenced code blocks. OpenAPI specification errors in documentation.yaml were resolved by correcting example property types to strings. Cross-reference validation errors in README.md were fixed by adding the missing link to project-standards/coding-standards.md. * Fix(ci): Duplicate heading errors in docs/api/members-api.md were fixed. Cross-reference validation errors for docker-architecture.md were resolved. All originally reported issues passed validation successfully. * Fix(ci): The markdown heading levels in docs/api/members-api.md were corrected from h5 to h4 to fix linting errors. The missing cross-reference link from technology-guides/docker/docker-development.md to docker-overview.md was added. These fixes resolved the original validation and linting errors causing the process to fail. * Fix(ci): Duplicate heading warnings in docs/api/members-api.md were resolved. Cross-reference validation for docker-development.md to docker-architecture.md was fixed. A new unrelated warning about docker-production.md was identified but not addressed. * refactor(ci,docs): Simplify CI pipeline and migrate docs to YouTrack SSoT BREAKING CHANGE: Documentation structure radically simplified - Consolidate 9 GitHub Actions workflows into 1 main pipeline (ci-main.yml) - Remove redundant workflows: ci-docs, markdownlint-autofix, guidelines-validation, api-docs - Delete documentation migrated to YouTrack: api/, BCs/, Visionen-Ideen/, reference/, now/, overview/ - Keep only ADRs, C4 diagrams, and essential dev guides in repo - Update README.md with YouTrack KB links - Create new docs/README.md as documentation gateway - Relax markdown-lint config for pragmatic developer experience Kept workflows: - ssot-guard.yml (Docker SSoT validation) - docs-kdoc-sync.yml (KDoc → YouTrack sync) - integration-tests.yml (Integration tests) - deploy-proxmox.yml (Deployment) - youtrack-sync.yml (YouTrack integration) Related: MP-DOCS-001 * refactor(ci,docs): Simplify CI pipeline and migrate docs to YouTrack SSoT BREAKING CHANGE: Documentation structure radically simplified - Consolidate 9 GitHub Actions workflows into 1 main pipeline (ci-main.yml) - Remove redundant workflows: ci-docs, markdownlint-autofix, guidelines-validation, api-docs - Delete documentation migrated to YouTrack: api/, BCs/, Visionen-Ideen/, reference/, now/, overview/ - Keep only ADRs, C4 diagrams, and essential dev guides in repo - Update README.md with YouTrack KB links - Create new docs/README.md as documentation gateway - Relax markdown-lint config for pragmatic developer experience Kept workflows: - ssot-guard.yml (Docker SSoT validation) - docs-kdoc-sync.yml (KDoc → YouTrack sync) - integration-tests.yml (Integration tests) - deploy-proxmox.yml (Deployment) - youtrack-sync.yml (YouTrack integration) Related: MP-DOCS-001 * refactor(ci,docs): README.md und einige andere Dokumentationen überarbeitet. ports-and-urls.md hinzugefügt. Related: MP-DOCS-001 * refactor(ci,docs): Die Markdownlint-Fehler in README.md und docs/README.md wurden behoben, indem die Überschriftenebenen angepasst, überflüssige Satzzeichen am Ende entfernt und die notwendigen Leerzeilen um Überschriften, Listen, Tabellen und Codeblöcke eingefügt wurden. Das problematische Leerzeichen am Ende in docs/README.md wurde ebenfalls entfernt. Die Dateien entsprechen nun den vorgegebenen Markdownlint-Regeln und sollten die CI-Validierung bestehen. Related: MP-DOCS-001 * refactor(ci,docs): Docker guideline cross-references were fixed and normalized to lowercase labels. Validation scripts confirmed zero cross-reference warnings and consistent metadata. Documentation was updated with a changelog and enhanced README navigation. Related: MP-DOCS-001 * refactor(ci,docs): Docker guideline cross-references were fixed and normalized to lowercase labels. Validation scripts confirmed zero cross-reference warnings and consistent metadata. Documentation was updated with a changelog and enhanced README navigation. Related: MP-DOCS-001 * refactor(ci,docs): Dead links in docs/architecture/adr were fixed by updating URLs to stable sources and adding an ignore pattern for a placeholder link. Specific ADR files had their broken links replaced with valid ones. The markdown-link-check GitHub Action is expected to pass with zero dead links now. Related: MP-DOCS-001 * refactor(ci,docs): Links in ADR checked Related: MP-DOCS-001 * refactor(ci,docs): Links in ADR checked Related: MP-DOCS-001 * refactor(ci,docs): Markdown Regeln ausgebessert Related: MP-DOCS-001 * refactor(ci,docs): Markdown Regeln ausgebessert Related: MP-DOCS-001 * refactor(ci,docs): Markdown Regeln ausgebessert Related: MP-DOCS-001 * Chore: Rerun CI checks with updated branch protection rules
This commit is contained in:
@@ -1,16 +1,70 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"type": "object",
|
||||
"required": ["status", "summary"],
|
||||
"required": [
|
||||
"status",
|
||||
"summary"
|
||||
],
|
||||
"properties": {
|
||||
"modul": {"type": "string"},
|
||||
"status": {"type": "string", "enum": ["active", "draft", "deprecated"]},
|
||||
"summary": {"type": "string"},
|
||||
"last_reviewed": {"type": "string", "pattern": "^\\d{4}-\\d{2}-\\d{2}$"},
|
||||
"review_cycle": {"type": "string", "pattern": "^\\d+d$"},
|
||||
"yt_epic": {"type": "string", "pattern": "^[A-Z]+-\\d+$"},
|
||||
"yt_issues": {"type": "array", "items": {"type": "string", "pattern": "^[A-Z]+-\\d+$"}},
|
||||
"tags": {"type": "array", "items": {"type": "string"}}
|
||||
"modul": {
|
||||
"type": "string"
|
||||
},
|
||||
"status": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"active",
|
||||
"draft",
|
||||
"deprecated"
|
||||
]
|
||||
},
|
||||
"summary": {
|
||||
"type": "string"
|
||||
},
|
||||
"last_reviewed": {
|
||||
"type": "string",
|
||||
"pattern": "^\\d{4}-\\d{2}-\\d{2}$"
|
||||
},
|
||||
"review_cycle": {
|
||||
"type": "string",
|
||||
"pattern": "^\\d+d$"
|
||||
},
|
||||
"yt_epic": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z]+-\\d+$"
|
||||
},
|
||||
"yt_issues": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"pattern": "^[A-Z]+-\\d+$"
|
||||
}
|
||||
},
|
||||
"tags": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"bc": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"members",
|
||||
"horses",
|
||||
"events",
|
||||
"masterdata",
|
||||
"infrastructure"
|
||||
]
|
||||
},
|
||||
"doc_type": {
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"how-to",
|
||||
"readme",
|
||||
"adr-link",
|
||||
"runbook",
|
||||
"api"
|
||||
]
|
||||
}
|
||||
},
|
||||
"additionalProperties": true
|
||||
}
|
||||
|
||||
@@ -0,0 +1,96 @@
|
||||
# Meldestelle - Dokumentation
|
||||
|
||||
## 📚 Single Source of Truth: YouTrack
|
||||
|
||||
Die Hauptdokumentation befindet sich in der **YouTrack Wissensdatenbank**:
|
||||
|
||||
👉 **[Meldestelle Command Center](https://meldestelle-pro.youtrack.cloud/articles/MP-A-24)**
|
||||
|
||||
### Was du in YouTrack findest
|
||||
|
||||
- 🏗️ **Bounded Context Dokumentation** (Members, Horses, Events, Masterdata)
|
||||
- 📡 **API-Referenz** (automatisch aus KDoc generiert)
|
||||
- 🚀 **Deployment-Guides** (Proxmox, Cloudflare, Nginx)
|
||||
- 🔐 **Sicherheit-Konfigurationen** (Keycloak, GitHub Secrets)
|
||||
- 💡 **Roadmap & Visionen**
|
||||
- 📊 **Architektur-Diagramme** (interaktiv)
|
||||
|
||||
---
|
||||
|
||||
## 📂 Was im Repository bleibt
|
||||
|
||||
### 1. Architecture Decision Records (ADRs)
|
||||
|
||||
Architekturentscheidungen sind Teil der Code-Historie und werden im Repository versioniert:
|
||||
|
||||
- [ADR Übersicht](architecture/adr)
|
||||
- [ADR-0001: Modulare Architektur](architecture/adr/0001-modular-architecture-de.md)
|
||||
- [ADR-0002: Domain-Driven Design](architecture/adr/0002-domain-driven-design-de.md)
|
||||
- [ADR-0003: Microservices](architecture/adr/0003-microservices-architecture-de.md)
|
||||
- [ADR-0004: Event-Driven Communication](architecture/adr/0004-event-driven-communication-de.md)
|
||||
- [ADR-0005: Polyglot Persistence](architecture/adr/0005-polyglot-persistence-de.md)
|
||||
- [ADR-0006: Authentication & Authorization (Keycloak)](architecture/adr/0006-authentication-authorization-keycloak-de.md)
|
||||
- [ADR-0007: API Gateway Pattern](architecture/adr/0007-api-gateway-pattern-de.md)
|
||||
- [ADR-0008: Multiplatform Client Applications](architecture/adr/0008-multiplatform-client-applications-de.md)
|
||||
|
||||
### 2. C4-Diagramme (PlantUML-Quellen)
|
||||
|
||||
Versionierte Diagramm-Quellen für Architekturdokumentation:
|
||||
|
||||
- [C4 Context](architecture/c4/01-context-de.puml)
|
||||
- [C4 Container](architecture/c4/02-container-de.puml)
|
||||
- [C4 Component - Events Service](architecture/c4/03-component-events-service-de.puml)
|
||||
|
||||
### 3. Developer Guides
|
||||
|
||||
Minimale Anleitungen für lokale Entwicklung:
|
||||
|
||||
- **[Lokales Setup](how-to/start-local.md)** – Projekt in 5 Minuten starten
|
||||
- **[KDoc Style Guide](how-to/kdoc-style.md)** – Documentations-Konventionen im Code
|
||||
- **[Branch-Schutz & PR-Workflow](how-to/branchschutz-und-pr-workflow.md)** – Git-Workflow
|
||||
|
||||
---
|
||||
|
||||
## 🔄 Automatische Synchronisation
|
||||
|
||||
Das Projekt nutzt automatisierte Workflows für Konsistenz:
|
||||
|
||||
- **KDoc → YouTrack**: [docs-kdoc-sync.yml](../.github/workflows/docs-kdoc-sync.yml) – Synchronisiert API-Dokumentation
|
||||
aus Code-Kommentaren nach YouTrack
|
||||
- **Docker SSoT**: [ssot-guard.yml](../.github/workflows/ssot-guard.yml) – Validiert Docker-Versionskonsistenz
|
||||
- **CI Pipeline**: [ci-main.yml](../.github/workflows/ci-main.yml) – Hauptpipeline für Build, Tests, Validierung
|
||||
|
||||
---
|
||||
|
||||
## 📋 Documentations-Workflow
|
||||
|
||||
### Für Code-Änderungen
|
||||
|
||||
1. KDoc im Code schreiben
|
||||
2. PR erstellen → CI validiert
|
||||
3. Nach Merge → KDoc-Sync pusht automatisch nach YouTrack
|
||||
|
||||
### Für Architektur-Entscheidungen
|
||||
|
||||
1. ADR in `docs/architecture/adr/` erstellen
|
||||
2. PR mit ADR-Review
|
||||
3. Nach Merge → Zusammenfassung in YouTrack verlinken
|
||||
|
||||
### Für Infrastruktur/Konfiguration
|
||||
|
||||
1. Dokumentation direkt in YouTrack erstellen
|
||||
2. Bei Code-relevanten Änderungen → im Commit-Message auf YouTrack-Artikel verweisen
|
||||
|
||||
---
|
||||
|
||||
## ❓ Fragen & Support
|
||||
|
||||
- **Technische Fragen**: [GitHub Discussions](https://github.com/StefanMoCoAt/meldestelle/discussions)
|
||||
- **Bugs**: [GitHub Issues](https://github.com/StefanMoCoAt/meldestelle/issues)
|
||||
- **Architektur-Diskussionen**: [YouTrack](https://meldestelle-pro.youtrack.cloud)
|
||||
- **Projekt-Dokumentation**: [YouTrack Wissensdatenbank](https://meldestelle-pro.youtrack.cloud/knowledge-bases)
|
||||
|
||||
---
|
||||
|
||||
**Hinweis**: Diese README wurde am 30. Oktober 2025 aktualisiert im Rahmen der Documentations-Migration nach YouTrack (
|
||||
siehe ADR-0009 - folgt).
|
||||
@@ -1,86 +0,0 @@
|
||||
# **Infrastruktur-Strategie zur DSGVO-Konformität für das Projekt "Meldestelle"**
|
||||
|
||||
Version: 1.0
|
||||
Datum: 17\. Oktober 2025
|
||||
Status: In Planung
|
||||
Ziel: Definition eines phasen basierten Ansatzes zur Entwicklung und zum Betrieb der "Meldestelle"-Anwendung, der von einer pragmatischen Entwicklungsphase zu einem vollständig DSGVO-konformen Produktionsbetrieb übergeht.
|
||||
|
||||
## **1\. Zusammenfassung & Zielsetzung**
|
||||
|
||||
Dieses Dokument beschreibt die zweistufige Strategie für die Infrastruktur des "Meldestelle"-Projekts. Ziel ist es, in der initialen Entwicklungs- und Testphase maximale Geschwindigkeit und Kosteneffizienz zu ermöglichen, während gleichzeitig ein klar definierter Pfad zur Erreichung vollständiger DSGVO-Konformität für den späteren Live-Betrieb sichergestellt wird.
|
||||
|
||||
Wir verfolgen einen pragmatischen Ansatz, der den Aufwand und die Kosten in jeder Phase an die tatsächlichen Risiken und Anforderungen anpasst.
|
||||
|
||||
## **2\. Grundprinzipien**
|
||||
|
||||
* **Pragmatismus vor Dogmatismus:** In der Entwicklungsphase nutzen wir etablierte, effiziente Cloud-Dienste, auch wenn diese rechtliche Grauzonen aufweisen, solange das Risiko minimal ist (keine externen personenbezogenen Daten).
|
||||
* **Containerisierung als Schlüssel:** Die gesamte Anwendung und ihre Infrastruktur wird von Anfang an in Docker-Containern betrieben. Dies gewährleistet maximale Portabilität und macht den späteren Wechsel der Hosting-Umgebung trivial.
|
||||
* **Automatisierung als Ziel:** Eine CI/CD-Pipeline ist von Beginn an integraler Bestandteil, um manuelle Fehler zu reduzieren und den Deployment-Prozess zu standardisieren.
|
||||
* **Klare Trennlinie:** Es gibt einen klar definierten "Point of no Return": Bevor die erste Zeile personenbezogener Daten von Dritten verarbeitet wird, muss die Migration zu Phase 2 abgeschlossen sein.
|
||||
|
||||
## **3\. Phasenplan**
|
||||
|
||||
### **Phase 1: Entwicklungs- & Feldversuchs-Phase (MVP)**
|
||||
|
||||
**Ziel:** Schnelle Entwicklung, Implementierung von Kernfunktionen, Durchführung von Tests und ersten Feldversuchen in einer kontrollierten Umgebung.
|
||||
|
||||
**Dauer:** Von Projektbeginn bis zum Abschluss der Feldversuche und vor der Aufnahme von echten Nutzerdaten.
|
||||
|
||||
**Technologie-Stack:**
|
||||
|
||||
* **Code-Hosting:** **GitHub** (US-Anbieter)
|
||||
* *Begründung:* Exzellente Entwickler-Tools, Marktführer, nahtlose Integrationen.
|
||||
* **CI/CD-Pipeline:** **GitHub Actions**
|
||||
* *Begründung:* Perfekte Integration mit dem Code-Hosting. Der rechenintensive Build-Prozess wird auf leistungsstarke Server von GitHub ausgelagert, was den lokalen Heimserver schont.
|
||||
* **Hosting-Infrastruktur:** **Proxmox Heimserver** (Intel N100 Mini-PC)
|
||||
* *Begründung:* Kostengünstige, flexible und kontrollierte Umgebung für Entwicklung und Tests.
|
||||
* **Externer Zugriff:** **Cloudflare Tunnel**
|
||||
* *Begründung:* Bietet hochsicheren Zugriff auf den Heimserver ohne offene Ports, verbirgt die private IP-Adresse und ist einfach zu verwalten.
|
||||
|
||||
**DSGVO-Bewertung dieser Phase:**
|
||||
|
||||
* **Status:** **Nicht streng DSGVO-konform.**
|
||||
* **Risiko:** **Akzeptabel und kontrolliert.**
|
||||
* **Begründung:** Personenbezogene Daten (Name/E-Mail des Entwicklers in Git-Commits) werden an einen US-Anbieter (GitHub/Microsoft) übertragen. Da in dieser Phase keine externen oder sensiblen personenbezogenen Daten im Code oder den Systemen verarbeitet werden, wird dieses Restrisiko bewusst in Kauf genommen. Die rechtliche Grundlage bilden die Standardvertragsklauseln (SCCs) und das Trans-Atlantic Data Privacy Framework (TADPF).
|
||||
|
||||
### **Phase 2: Go-Live & Betrieb (Produktionsumgebung)**
|
||||
|
||||
**Ziel:** Bereitstellung der Anwendung für die Öffentlichkeit in einer hochverfügbaren, sicheren und vollständig DSGVO-konformen Umgebung.
|
||||
|
||||
**Trigger für die Migration:** Der Abschluss der Feldversuche und die geplante Verarbeitung von personenbezogenen Daten von echten Nutzern.
|
||||
|
||||
**Technologie-Stack (Phase 2 \- Go-Live & Betrieb):**
|
||||
|
||||
* **Hosting-Infrastruktur:** **Virtual Private Server (VPS) bei einem EU-Anbieter** (z.B. Hetzner, Standort Deutschland).
|
||||
* *Begründung:* Gewährleistet, dass alle Daten und Prozesse die EU physisch nicht verlassen (Datenhoheit). Bietet professionelle Performance und Zuverlässigkeit.
|
||||
* **Code-Hosting & CI/CD:** **Self-hosted Forgejo**, installiert auf dem VPS.
|
||||
* *Begründung:* Forgejo ist eine leichtgewichtige, von der Community betriebene Open-Source-Alternative. Es bietet Git-Hosting und ein integriertes CI/CD-System (Forgejo Actions), das mit GitHub Actions kompatibel ist. Der gesamte Lebenszyklus des Codes (Speicherung, Bau, Test) findet auf dem eigenen Server in Deutschland statt.
|
||||
* **Container Registry:** Die in Forgejo integrierte Container Registry.
|
||||
* *Begründung:* Hält auch die fertigen Docker-Images innerhalb der eigenen, konformen Infrastruktur.
|
||||
* **Externer Zugriff:** Standard-Reverse-Proxy (z.B. Traefik oder Nginx) direkt auf dem VPS.
|
||||
* *Begründung:* Der Server hat eine öffentliche IP, ein Tunnel ist nicht mehr nötig. Der Proxy steuert den Zugriff auf die Anwendungs-Container.
|
||||
|
||||
### **DSGVO-Bewertung (Phase 2\)**
|
||||
|
||||
* **Status:** **Vollständig DSGVO-konform.**
|
||||
* **Risiko:** **Minimal.**
|
||||
* **Begründung:** Der gesamte Datenverarbeitungsprozess – von der Codezeile in **Forgejo**, über den Build-Prozess durch **Forgejo Actions**, bis zur laufenden Anwendung und den Nutzerdaten in der Datenbank – findet ausschließlich auf Servern in Deutschland unter eigener Kontrolle statt.
|
||||
|
||||
### **4\. Migrationsschritte von Phase 1 zu Phase 2**
|
||||
|
||||
1. **Infrastruktur aufsetzen:** Einen geeigneten VPS bei Hetzner mieten und mit einem schlanken Debian-System grundlegend absichern.
|
||||
2. **Forgejo installieren:** Forgejo als Docker-Container auf dem neuen VPS installieren und konfigurieren.
|
||||
3. **Code migrieren:** Das "Meldestelle"-Repository von GitHub auf die eigene Forgejo-Instanz spiegeln/umziehen.
|
||||
4. **Pipeline adaptieren:** Die GitHub Actions-Workflows in die Forgejo Actions-Konfiguration überführen. **Da Forgejo Actions weitgehend mit GitHub Actions kompatibel ist, ist dieser Schritt deutlich einfacher als eine vollständige Portierung zu einem anderen System.**
|
||||
5. **Anwendung deployen:** Die CI/CD-Pipeline in Forgejo erstmals ausführen, um die "Meldestelle"-Anwendung (Docker-Container) auf dem VPS zu deployen.
|
||||
6. **DNS-Umschaltung:** Die DNS-Einträge für mo-code.at (und Subdomains) bei Cloudflare vom Tunnel auf die neue, feste IP-Adresse des Hetzner-Servers umstellen.
|
||||
7. **Decommissioning:** Nach erfolgreichem Testbetrieb den Cloudflare Tunnel und die alten GitHub-Workflows deaktivieren.
|
||||
|
||||
## **5\. Zeit- und Kostenschätzung**
|
||||
|
||||
* **Phase 1:**
|
||||
* **Kosten:** Minimal (Stromkosten für Heimserver). Die genutzten Dienste (GitHub, Cloudflare) sind im Rahmen des Projekts kostenlos.
|
||||
* **Zeitaufwand:** Fokus liegt zu 100% auf der Anwendungsentwicklung.
|
||||
* **Phase 2:**
|
||||
* **Kosten:** Monatliche Gebühren für den VPS (ca. 15-30 €/Monat, je nach Größe).
|
||||
* **Zeitaufwand:** Für die Migration von Phase 1 zu 2 sollte ein dediziertes Zeitfenster von **ca. 1-2 Wochen** eingeplant werden, um alle Schritte sorgfältig durchzuführen und zu testen.
|
||||
@@ -1,400 +0,0 @@
|
||||
---
|
||||
modul: api-overview
|
||||
status: active
|
||||
last_reviewed: 2025-10-22
|
||||
review_cycle: 180d
|
||||
summary: Überblick und Einstieg in die REST‑APIs der Meldestelle.
|
||||
yt_epic: MP-1
|
||||
yt_issues: [MP-7]
|
||||
tags: [api, overview]
|
||||
---
|
||||
|
||||
# Meldestelle – REST‑API Dokumentation
|
||||
|
||||
## Überblick
|
||||
|
||||
Die Meldestelle-Anwendung bietet eine umfassende REST API für die Verwaltung von Pferdesportveranstaltungen. Die API folgt RESTful-Prinzipien und ist in modulare Services unterteilt, die jeweils spezifische Domänen abdecken.
|
||||
|
||||
## API-Architektur
|
||||
|
||||
### Modulare Service-Struktur
|
||||
|
||||
Die API ist in folgende Hauptmodule unterteilt:
|
||||
|
||||
```
|
||||
API Services
|
||||
├── Members API # Mitgliederverwaltung
|
||||
├── Horses API # Pferderegistrierung
|
||||
├── Events API # Veranstaltungsverwaltung
|
||||
└── Masterdata API # Stammdatenverwaltung
|
||||
├── Countries # Länderverwaltung
|
||||
├── States # Bundesländerverwaltung
|
||||
├── Age Classes # Altersklassenverwaltung
|
||||
└── Venues # Plätze/Austragungsorte
|
||||
```
|
||||
|
||||
### Technische Spezifikationen
|
||||
|
||||
- **Framework**: Spring Boot 3.x mit Spring Web MVC
|
||||
- **Dokumentation**: OpenAPI 3.0 (Swagger)
|
||||
- **Serialisierung**: JSON mit Jackson/Kotlinx Serialization
|
||||
- **Authentifizierung**: JWT Bearer Token
|
||||
- **Versionierung**: URL-basiert (/api/v1/)
|
||||
- **Content-Type**: application/json
|
||||
- **Zeichenkodierung**: UTF-8
|
||||
|
||||
## Basis-URL und Endpunkte
|
||||
|
||||
### Entwicklungsumgebung
|
||||
```
|
||||
Base URL: http://localhost:8081/api
|
||||
```
|
||||
|
||||
### Produktionsumgebung
|
||||
```
|
||||
Base URL: https://api.meldestelle.yourdomain.com/api
|
||||
```
|
||||
|
||||
## API-Module Übersicht
|
||||
|
||||
### 1. Members API
|
||||
**Basis-Pfad**: `/api/members`
|
||||
|
||||
Verwaltung von Vereinsmitgliedern und deren Mitgliedschaftsdaten.
|
||||
|
||||
**Hauptfunktionen**:
|
||||
- Mitgliederverwaltung (CRUD)
|
||||
- Mitgliedschaftsstatus-Tracking
|
||||
- Ablaufende Mitgliedschaften
|
||||
- Validierung von E-Mail und Mitgliedsnummer
|
||||
|
||||
**Controller**: `MemberController`
|
||||
**Endpunkte**: 12 REST-Endpunkte
|
||||
**Dokumentation**: [Members API](members-api.md)
|
||||
|
||||
### 2. Horses API
|
||||
**Basis-Pfad**: `/api/horses`
|
||||
|
||||
Registrierung und Verwaltung von Pferden mit umfassenden Identifikationsdaten.
|
||||
|
||||
**Hauptfunktionen**:
|
||||
- Pferderegistrierung (CRUD)
|
||||
- Identifikationsnummern-Verwaltung
|
||||
- OEPS/FEI-Registrierung
|
||||
- Besitzer- und Verantwortlichen-Zuordnung
|
||||
|
||||
**Controller**: `HorseController`
|
||||
**Endpunkte**: 15+ REST-Endpunkte
|
||||
|
||||
### 3. Events API
|
||||
**Basis-Pfad**: `/api/events`
|
||||
|
||||
Planung und Verwaltung von Pferdesportveranstaltungen.
|
||||
|
||||
**Hauptfunktionen**:
|
||||
- Veranstaltungsplanung (CRUD)
|
||||
- Terminverwaltung
|
||||
- Teilnehmerverwaltung
|
||||
- Öffentliche/Private Veranstaltungen
|
||||
|
||||
**Controller**: `VeranstaltungController`
|
||||
**Endpunkte**: 10+ REST-Endpunkte
|
||||
|
||||
### 4. Masterdata API
|
||||
**Basis-Pfad**: `/api/masterdata`
|
||||
|
||||
Verwaltung von Stammdaten für das gesamte System.
|
||||
|
||||
#### 4.1 Countries API
|
||||
**Pfad**: `/api/masterdata/countries`
|
||||
- Länderverwaltung mit ISO-Codes
|
||||
- EU/EWR-Mitgliedschaft
|
||||
- Mehrsprachige Ländernamen
|
||||
|
||||
#### 4.2 States API
|
||||
**Pfad**: `/api/masterdata/states`
|
||||
- Bundesländer/Kantone/Regionen
|
||||
- OEPS-Codes für österreichische Bundesländer
|
||||
- ISO 3166-2 Codes
|
||||
|
||||
#### 4.3 Age Classes API
|
||||
**Pfad**: `/api/masterdata/age-classes`
|
||||
- Altersklassen für verschiedene Sparten
|
||||
- Teilnahmeberechtigung
|
||||
- Geschlechts- und Spartenfilter
|
||||
|
||||
#### 4.4 Venues API
|
||||
**Pfad**: `/api/masterdata/venues`
|
||||
- Turnierplätze und Austragungsorte
|
||||
- Platztypen und Abmessungen
|
||||
- Bodenarten und Eignung
|
||||
|
||||
**Controller**: `CountryController`, `BundeslandController`, `AltersklasseController`, `PlatzController`
|
||||
**Endpunkte**: 37+ REST-Endpunkte
|
||||
|
||||
## Gemeinsame API-Konventionen
|
||||
|
||||
### HTTP-Status-Codes
|
||||
|
||||
| Status Code | Bedeutung | Verwendung |
|
||||
|-------------|-----------|------------|
|
||||
| 200 | OK | Erfolgreiche GET/PUT-Anfragen |
|
||||
| 201 | Created | Erfolgreiche POST-Anfragen |
|
||||
| 204 | No Content | Erfolgreiche DELETE-Anfragen |
|
||||
| 400 | Bad Request | Ungültige Anfragedaten |
|
||||
| 401 | Unauthorized | Fehlende/ungültige Authentifizierung |
|
||||
| 403 | Forbidden | Unzureichende Berechtigung |
|
||||
| 404 | Not Found | Ressource nicht gefunden |
|
||||
| 409 | Conflict | Duplikat oder Geschäftsregel-Verletzung |
|
||||
| 422 | Unprocessable Entity | Validierungsfehler |
|
||||
| 500 | Internal Server Error | Serverfehler |
|
||||
|
||||
### Standard-Response-Format
|
||||
|
||||
Alle API-Endpunkte verwenden ein einheitliches Response-Format:
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {},
|
||||
"success": true,
|
||||
"message": "Operation completed successfully",
|
||||
"errors": [],
|
||||
"timestamp": "2025-07-25T12:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### Erfolgreiche Antwort
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"id": "123e4567-e89b-12d3-a456-426614174000",
|
||||
"firstName": "Max",
|
||||
"lastName": "Mustermann",
|
||||
"email": "max@example.com"
|
||||
},
|
||||
"success": true,
|
||||
"message": null,
|
||||
"errors": [],
|
||||
"timestamp": "2025-07-25T12:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### Fehler-Antwort
|
||||
```json
|
||||
{
|
||||
"data": null,
|
||||
"success": false,
|
||||
"message": "Validation failed",
|
||||
"errors": [
|
||||
"Email address is required",
|
||||
"First name must not be empty"
|
||||
],
|
||||
"timestamp": "2025-07-25T12:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Paginierung
|
||||
|
||||
Für Listen-Endpunkte wird standardmäßig Paginierung unterstützt:
|
||||
|
||||
**Query-Parameter**:
|
||||
- `limit`: Maximale Anzahl Ergebnisse (Standard: 100, Maximum: 1000)
|
||||
- `offset`: Anzahl zu überspringende Ergebnisse (Standard: 0)
|
||||
|
||||
**Beispiel-Anfrage**:
|
||||
```
|
||||
GET /api/members?limit=50&offset=100
|
||||
```
|
||||
|
||||
**Paginierte Antwort**:
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"content": [],
|
||||
"page": 2,
|
||||
"size": 50,
|
||||
"totalElements": 1250,
|
||||
"totalPages": 25,
|
||||
"hasNext": true,
|
||||
"hasPrevious": true
|
||||
},
|
||||
"success": true,
|
||||
"timestamp": "2025-07-25T12:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Suchfunktionalität
|
||||
|
||||
Viele Endpunkte unterstützen Suchfunktionalität:
|
||||
|
||||
**Query-Parameter**:
|
||||
- `search`: Suchbegriff für Textfelder
|
||||
- `name`: Suche nach Namen (Teilübereinstimmung)
|
||||
- `active`: Filter für aktive/inaktive Einträge
|
||||
|
||||
**Beispiel**:
|
||||
```
|
||||
GET /api/members?search=Schmidt&active=true&limit=20
|
||||
```
|
||||
|
||||
### Sortierung
|
||||
|
||||
Sortierung wird über Query-Parameter gesteuert:
|
||||
|
||||
**Query-Parameter**:
|
||||
- `sort`: Sortierfeld (z.B. `name`, `createdAt`)
|
||||
- `order`: Sortierrichtung (`asc` oder `desc`)
|
||||
|
||||
**Beispiel**:
|
||||
```
|
||||
GET /api/members?sort=lastName&order=asc
|
||||
```
|
||||
|
||||
## Authentifizierung und Autorisierung
|
||||
|
||||
### JWT Bearer Token
|
||||
|
||||
Alle API-Endpunkte (außer öffentlichen) erfordern Authentifizierung über JWT Bearer Token:
|
||||
|
||||
```http
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
|
||||
### Rollen und Berechtigungen
|
||||
|
||||
| Rolle | Beschreibung | Berechtigungen |
|
||||
|-------|--------------|----------------|
|
||||
| ADMIN | Systemadministrator | Vollzugriff auf alle Ressourcen |
|
||||
| TRAINER | Trainer/Ausbilder | Zugriff auf Pferde und Veranstaltungen |
|
||||
| MEMBER | Vereinsmitglied | Zugriff auf eigene Daten |
|
||||
| GUEST | Gast | Nur Lesezugriff auf öffentliche Daten |
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
Zum Schutz der API vor Überlastung gelten folgende Limits:
|
||||
|
||||
- **Authentifizierte Benutzer**: 1000 Anfragen/Stunde
|
||||
- **Nicht authentifizierte Benutzer**: 100 Anfragen/Stunde
|
||||
- **Burst-Limit**: 50 Anfragen/Minute
|
||||
|
||||
Bei Überschreitung wird HTTP 429 (Too Many Requests) zurückgegeben.
|
||||
|
||||
## Fehlerbehandlung
|
||||
|
||||
### Validierungsfehler (422)
|
||||
|
||||
```json
|
||||
{
|
||||
"data": null,
|
||||
"success": false,
|
||||
"message": "Validation failed",
|
||||
"errors": [
|
||||
{
|
||||
"field": "email",
|
||||
"message": "Email address is invalid",
|
||||
"code": "INVALID_EMAIL"
|
||||
},
|
||||
{
|
||||
"field": "membershipNumber",
|
||||
"message": "Membership number already exists",
|
||||
"code": "DUPLICATE_MEMBERSHIP_NUMBER"
|
||||
}
|
||||
],
|
||||
"timestamp": "2025-07-25T12:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Geschäftsregel-Verletzungen (409)
|
||||
|
||||
```json
|
||||
{
|
||||
"data": null,
|
||||
"success": false,
|
||||
"message": "Business rule violation",
|
||||
"errors": [
|
||||
"Membership end date cannot be before start date"
|
||||
],
|
||||
"timestamp": "2025-07-25T12:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
## API-Dokumentation
|
||||
|
||||
### Swagger/OpenAPI
|
||||
|
||||
Die vollständige API-Dokumentation ist über Swagger UI verfügbar:
|
||||
|
||||
- **Entwicklung**: http://localhost:8080/swagger-ui.html
|
||||
- **Produktion**: https://api.meldestelle.at/swagger-ui.html
|
||||
|
||||
### Postman Collections
|
||||
|
||||
Postman Collections für alle API-Endpunkte sind verfügbar unter:
|
||||
- [docs/postman/](../postman/)
|
||||
|
||||
## Versionierung
|
||||
|
||||
Die API verwendet URL-basierte Versionierung:
|
||||
|
||||
- **Aktuelle Version**: v1
|
||||
- **Basis-URL**: `/api/v1/`
|
||||
- **Deprecated Versionen**: Werden 12 Monate unterstützt
|
||||
|
||||
## Monitoring und Observability
|
||||
|
||||
### Health Checks
|
||||
|
||||
```
|
||||
GET /actuator/health
|
||||
```
|
||||
|
||||
### Metriken
|
||||
|
||||
```
|
||||
GET /actuator/metrics
|
||||
GET /actuator/prometheus
|
||||
```
|
||||
|
||||
### API-Metriken
|
||||
|
||||
- Request-Anzahl pro Endpunkt
|
||||
- Response-Zeiten
|
||||
- Fehlerquoten
|
||||
- Rate-Limiting-Statistiken
|
||||
|
||||
## Entwicklung und Testing
|
||||
|
||||
### Lokale Entwicklung
|
||||
|
||||
```bash
|
||||
# API-Server starten
|
||||
./gradlew bootRun
|
||||
|
||||
# Swagger UI öffnen
|
||||
open http://localhost:8080/swagger-ui.html
|
||||
```
|
||||
|
||||
### API-Tests
|
||||
|
||||
```bash
|
||||
# Unit Tests
|
||||
./gradlew test
|
||||
|
||||
# Integration Tests
|
||||
./gradlew integrationTest
|
||||
|
||||
# API Tests mit Newman
|
||||
newman run docs/postman/meldestelle-api.postman_collection.json
|
||||
```
|
||||
|
||||
## Support und Kontakt
|
||||
|
||||
- **Dokumentation**: [docs/api/](.)
|
||||
- **Issue Tracker**: GitHub Issues
|
||||
- **API-Status**: https://status.meldestelle.at
|
||||
|
||||
---
|
||||
|
||||
**Letzte Aktualisierung**: 25. Juli 2025
|
||||
**API-Version**: v1.0
|
||||
**OpenAPI-Spezifikation**: 3.0.3
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "Events API",
|
||||
"description": "REST API für events Verwaltung",
|
||||
"version": "1.0.0",
|
||||
"contact": { "name": "Meldestelle Development Team" }
|
||||
},
|
||||
"servers": [
|
||||
{ "url": "http://localhost:8080", "description": "Entwicklungs-Server" },
|
||||
{ "url": "https://api.meldestelle.at", "description": "Produktions-Server" }
|
||||
],
|
||||
"paths": {},
|
||||
"components": {
|
||||
"securitySchemes": {
|
||||
"bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" }
|
||||
}
|
||||
},
|
||||
"security": [ { "bearerAuth": [] } ]
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "Horses API",
|
||||
"description": "REST API für horses Verwaltung",
|
||||
"version": "1.0.0",
|
||||
"contact": { "name": "Meldestelle Development Team" }
|
||||
},
|
||||
"servers": [
|
||||
{ "url": "http://localhost:8080", "description": "Entwicklungs-Server" },
|
||||
{ "url": "https://api.meldestelle.at", "description": "Produktions-Server" }
|
||||
],
|
||||
"paths": {},
|
||||
"components": {
|
||||
"securitySchemes": {
|
||||
"bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" }
|
||||
}
|
||||
},
|
||||
"security": [ { "bearerAuth": [] } ]
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "Masterdata API",
|
||||
"description": "REST API für masterdata Verwaltung",
|
||||
"version": "1.0.0",
|
||||
"contact": { "name": "Meldestelle Development Team" }
|
||||
},
|
||||
"servers": [
|
||||
{ "url": "http://localhost:8080", "description": "Entwicklungs-Server" },
|
||||
{ "url": "https://api.meldestelle.at", "description": "Produktions-Server" }
|
||||
],
|
||||
"paths": {},
|
||||
"components": {
|
||||
"securitySchemes": {
|
||||
"bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" }
|
||||
}
|
||||
},
|
||||
"security": [ { "bearerAuth": [] } ]
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
{
|
||||
"openapi": "3.0.3",
|
||||
"info": {
|
||||
"title": "Members API",
|
||||
"description": "REST API für members Verwaltung",
|
||||
"version": "1.0.0",
|
||||
"contact": { "name": "Meldestelle Development Team" }
|
||||
},
|
||||
"servers": [
|
||||
{ "url": "http://localhost:8080", "description": "Entwicklungs-Server" },
|
||||
{ "url": "https://api.meldestelle.at", "description": "Produktions-Server" }
|
||||
],
|
||||
"paths": {},
|
||||
"components": {
|
||||
"securitySchemes": {
|
||||
"bearerAuth": { "type": "http", "scheme": "bearer", "bearerFormat": "JWT" }
|
||||
}
|
||||
},
|
||||
"security": [ { "bearerAuth": [] } ]
|
||||
}
|
||||
@@ -1,633 +0,0 @@
|
||||
---
|
||||
modul: members-api
|
||||
status: active
|
||||
last_reviewed: 2025-10-22
|
||||
review_cycle: 180d
|
||||
summary: Dokumentation der Members‑API (Endpunkte, Parameter, Beispiele).
|
||||
yt_epic: MP-1
|
||||
yt_issues: []
|
||||
tags: [api, members]
|
||||
---
|
||||
|
||||
# Members‑API – Dokumentation
|
||||
|
||||
## Überblick
|
||||
|
||||
Die Members API bietet umfassende Funktionalität zur Verwaltung von Vereinsmitgliedern und deren Mitgliedschaftsdaten. Sie unterstützt vollständige CRUD-Operationen sowie spezialisierte Funktionen für Mitgliedschaftsverwaltung, Validierung und Statistiken.
|
||||
|
||||
## Basis-Informationen
|
||||
|
||||
- **Basis-URL**: `/api/members`
|
||||
- **Controller**: `MemberController`
|
||||
- **Authentifizierung**: JWT Bearer Token erforderlich
|
||||
- **Content-Type**: `application/json`
|
||||
- **Zeichenkodierung**: UTF-8
|
||||
|
||||
## Endpunkte Übersicht
|
||||
|
||||
| Methode | Endpunkt | Beschreibung |
|
||||
|---------|----------|--------------|
|
||||
| GET | `/api/members` | Alle Mitglieder abrufen |
|
||||
| GET | `/api/members/{id}` | Mitglied nach ID abrufen |
|
||||
| GET | `/api/members/by-membership-number/{membershipNumber}` | Mitglied nach Mitgliedsnummer |
|
||||
| GET | `/api/members/by-email/{email}` | Mitglied nach E-Mail |
|
||||
| GET | `/api/members/stats` | Mitgliederstatistiken |
|
||||
| POST | `/api/members` | Neues Mitglied erstellen |
|
||||
| PUT | `/api/members/{id}` | Mitglied aktualisieren |
|
||||
| DELETE | `/api/members/{id}` | Mitglied löschen |
|
||||
| GET | `/api/members/expiring-memberships` | Ablaufende Mitgliedschaften |
|
||||
| GET | `/api/members/by-date-range` | Mitglieder nach Datumsbereich |
|
||||
| GET | `/api/members/validate/email/{email}` | E-Mail-Eindeutigkeit prüfen |
|
||||
| GET | `/api/members/validate/membership-number/{membershipNumber}` | Mitgliedsnummer-Eindeutigkeit prüfen |
|
||||
|
||||
## Detaillierte Endpunkt-Dokumentation
|
||||
|
||||
### 1. Alle Mitglieder abrufen
|
||||
|
||||
```http
|
||||
GET /api/members
|
||||
```
|
||||
|
||||
Ruft eine Liste aller Mitglieder ab mit optionaler Filterung und Suche.
|
||||
|
||||
#### Query-Parameter
|
||||
|
||||
| Parameter | Typ | Standard | Beschreibung |
|
||||
|-----------|-----|----------|--------------|
|
||||
| `activeOnly` | boolean | `true` | Nur aktive Mitglieder anzeigen |
|
||||
| `limit` | integer | `100` | Maximale Anzahl Ergebnisse |
|
||||
| `offset` | integer | `0` | Anzahl zu überspringende Ergebnisse |
|
||||
| `search` | string | - | Suchbegriff für Mitgliedernamen |
|
||||
|
||||
#### Beispiel-Anfrage
|
||||
|
||||
```http
|
||||
GET /api/members?activeOnly=true&limit=50&search=Schmidt
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
|
||||
#### Erfolgreiche Antwort (200 OK)
|
||||
|
||||
```json
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"memberId": "123e4567-e89b-12d3-a456-426614174000",
|
||||
"firstName": "Max",
|
||||
"lastName": "Schmidt",
|
||||
"email": "max.schmidt@example.com",
|
||||
"phone": "+43 1 234 5678",
|
||||
"dateOfBirth": "1985-03-15",
|
||||
"membershipNumber": "M2024001",
|
||||
"membershipStartDate": "2024-01-01",
|
||||
"membershipEndDate": "2024-12-31",
|
||||
"isActive": true,
|
||||
"address": "Musterstraße 123, 1010 Wien",
|
||||
"emergencyContact": "Anna Schmidt, +43 1 234 5679",
|
||||
"createdAt": "2024-01-01T10:00:00Z",
|
||||
"updatedAt": "2024-07-25T12:37:00Z"
|
||||
}
|
||||
],
|
||||
"success": true,
|
||||
"message": null,
|
||||
"errors": [],
|
||||
"timestamp": "2025-07-25T12:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### Fehler-Antworten
|
||||
|
||||
- **500 Internal Server Error**: Serverfehler beim Abrufen der Mitglieder
|
||||
|
||||
### 2. Mitglied nach ID abrufen
|
||||
|
||||
```http
|
||||
GET /api/members/{id}
|
||||
```
|
||||
|
||||
Ruft ein spezifisches Mitglied anhand seiner eindeutigen ID ab.
|
||||
|
||||
#### Pfad-Parameter
|
||||
|
||||
| Parameter | Typ | Beschreibung |
|
||||
|-----------|-----|--------------|
|
||||
| `id` | UUID | Eindeutige Mitglieder-ID |
|
||||
|
||||
#### Beispiel-Anfrage
|
||||
|
||||
```http
|
||||
GET /api/members/123e4567-e89b-12d3-a456-426614174000
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
|
||||
#### Erfolgreiche Antwort (200 OK)
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"memberId": "123e4567-e89b-12d3-a456-426614174000",
|
||||
"firstName": "Max",
|
||||
"lastName": "Schmidt",
|
||||
"email": "max.schmidt@example.com",
|
||||
"phone": "+43 1 234 5678",
|
||||
"dateOfBirth": "1985-03-15",
|
||||
"membershipNumber": "M2024001",
|
||||
"membershipStartDate": "2024-01-01",
|
||||
"membershipEndDate": "2024-12-31",
|
||||
"isActive": true,
|
||||
"address": "Musterstraße 123, 1010 Wien",
|
||||
"emergencyContact": "Anna Schmidt, +43 1 234 5679",
|
||||
"createdAt": "2024-01-01T10:00:00Z",
|
||||
"updatedAt": "2024-07-25T12:37:00Z"
|
||||
},
|
||||
"success": true,
|
||||
"message": null,
|
||||
"errors": [],
|
||||
"timestamp": "2025-07-25T12:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### Fehler-Antworten
|
||||
|
||||
- **400 Bad Request**: Ungültiges UUID-Format
|
||||
- **404 Not Found**: Mitglied nicht gefunden
|
||||
- **500 Internal Server Error**: Serverfehler
|
||||
|
||||
### 3. Mitglied nach Mitgliedsnummer abrufen
|
||||
|
||||
```http
|
||||
GET /api/members/by-membership-number/{membershipNumber}
|
||||
```
|
||||
|
||||
#### Pfad-Parameter
|
||||
|
||||
| Parameter | Typ | Beschreibung |
|
||||
|-----------|-----|--------------|
|
||||
| `membershipNumber` | string | Mitgliedsnummer |
|
||||
|
||||
#### Beispiel-Anfrage
|
||||
|
||||
```http
|
||||
GET /api/members/by-membership-number/M2024001
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
|
||||
### 4. Mitglied nach E-Mail abrufen
|
||||
|
||||
```http
|
||||
GET /api/members/by-email/{email}
|
||||
```
|
||||
|
||||
#### Pfad-Parameter
|
||||
|
||||
| Parameter | Typ | Beschreibung |
|
||||
|-----------|-----|--------------|
|
||||
| `email` | string | E-Mail-Adresse |
|
||||
|
||||
#### Beispiel-Anfrage
|
||||
|
||||
```http
|
||||
GET /api/members/by-email/max.schmidt@example.com
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
|
||||
### 5. Mitgliederstatistiken abrufen
|
||||
|
||||
```http
|
||||
GET /api/members/stats
|
||||
```
|
||||
|
||||
Ruft Statistiken über die Mitgliederdatenbank ab.
|
||||
|
||||
#### Erfolgreiche Antwort (200 OK)
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"totalActive": 1250,
|
||||
"totalMembers": 1380
|
||||
},
|
||||
"success": true,
|
||||
"message": null,
|
||||
"errors": [],
|
||||
"timestamp": "2025-07-25T12:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Neues Mitglied erstellen
|
||||
|
||||
```http
|
||||
POST /api/members
|
||||
```
|
||||
|
||||
Erstellt ein neues Mitglied mit den bereitgestellten Daten.
|
||||
|
||||
#### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"firstName": "Max",
|
||||
"lastName": "Mustermann",
|
||||
"email": "max.mustermann@example.com",
|
||||
"phone": "+43 1 234 5678",
|
||||
"dateOfBirth": "1985-03-15",
|
||||
"membershipNumber": "M2024002",
|
||||
"membershipStartDate": "2024-08-01",
|
||||
"membershipEndDate": "2024-12-31",
|
||||
"isActive": true,
|
||||
"address": "Beispielstraße 456, 1020 Wien",
|
||||
"emergencyContact": "Anna Mustermann, +43 1 234 5679"
|
||||
}
|
||||
```
|
||||
|
||||
#### Erfolgreiche Antwort (201 Created)
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"memberId": "456e7890-e89b-12d3-a456-426614174001",
|
||||
"firstName": "Max",
|
||||
"lastName": "Mustermann",
|
||||
"email": "max.mustermann@example.com",
|
||||
"phone": "+43 1 234 5678",
|
||||
"dateOfBirth": "1985-03-15",
|
||||
"membershipNumber": "M2024002",
|
||||
"membershipStartDate": "2024-08-01",
|
||||
"membershipEndDate": "2024-12-31",
|
||||
"isActive": true,
|
||||
"address": "Beispielstraße 456, 1020 Wien",
|
||||
"emergencyContact": "Anna Mustermann, +43 1 234 5679",
|
||||
"createdAt": "2025-07-25T12:37:00Z",
|
||||
"updatedAt": "2025-07-25T12:37:00Z"
|
||||
},
|
||||
"success": true,
|
||||
"message": null,
|
||||
"errors": [],
|
||||
"timestamp": "2025-07-25T12:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### Fehler-Antworten
|
||||
|
||||
- **400 Bad Request**: Ungültige Anfragedaten
|
||||
- **409 Conflict**: E-Mail oder Mitgliedsnummer bereits vorhanden
|
||||
- **422 Unprocessable Entity**: Validierungsfehler
|
||||
|
||||
### 7. Mitglied aktualisieren
|
||||
|
||||
```http
|
||||
PUT /api/members/{id}
|
||||
```
|
||||
|
||||
Aktualisiert ein bestehendes Mitglied.
|
||||
|
||||
#### Pfad-Parameter
|
||||
|
||||
| Parameter | Typ | Beschreibung |
|
||||
|-----------|-----|--------------|
|
||||
| `id` | UUID | Eindeutige Mitglieder-ID |
|
||||
|
||||
#### Request Body
|
||||
|
||||
```json
|
||||
{
|
||||
"firstName": "Max",
|
||||
"lastName": "Mustermann",
|
||||
"email": "max.mustermann.updated@example.com",
|
||||
"phone": "+43 1 234 5678",
|
||||
"dateOfBirth": "1985-03-15",
|
||||
"membershipNumber": "M2024002",
|
||||
"membershipStartDate": "2024-08-01",
|
||||
"membershipEndDate": "2025-07-31",
|
||||
"isActive": true,
|
||||
"address": "Neue Straße 789, 1030 Wien",
|
||||
"emergencyContact": "Anna Mustermann, +43 1 234 5679"
|
||||
}
|
||||
```
|
||||
|
||||
#### Erfolgreiche Antwort (200 OK)
|
||||
|
||||
Gleiche Struktur wie bei der Erstellung, aber mit aktualisierten Daten und `updatedAt` Zeitstempel.
|
||||
|
||||
#### Fehler-Antworten
|
||||
|
||||
- **400 Bad Request**: Ungültige Anfragedaten oder UUID-Format
|
||||
- **404 Not Found**: Mitglied nicht gefunden
|
||||
- **409 Conflict**: E-Mail oder Mitgliedsnummer bereits vorhanden
|
||||
- **500 Internal Server Error**: Serverfehler
|
||||
|
||||
### 8. Mitglied löschen
|
||||
|
||||
```http
|
||||
DELETE /api/members/{id}
|
||||
```
|
||||
|
||||
Löscht ein Mitglied aus dem System.
|
||||
|
||||
#### Pfad-Parameter
|
||||
|
||||
| Parameter | Typ | Beschreibung |
|
||||
|-----------|-----|--------------|
|
||||
| `id` | UUID | Eindeutige Mitglieder-ID |
|
||||
|
||||
#### Beispiel-Anfrage
|
||||
|
||||
```http
|
||||
DELETE /api/members/123e4567-e89b-12d3-a456-426614174000
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
|
||||
#### Erfolgreiche Antwort (200 OK)
|
||||
|
||||
```json
|
||||
{
|
||||
"data": "Member deleted successfully",
|
||||
"success": true,
|
||||
"message": null,
|
||||
"errors": [],
|
||||
"timestamp": "2025-07-25T12:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
#### Fehler-Antworten
|
||||
|
||||
- **400 Bad Request**: Ungültiges UUID-Format
|
||||
- **404 Not Found**: Mitglied nicht gefunden
|
||||
- **500 Internal Server Error**: Serverfehler
|
||||
|
||||
### 9. Ablaufende Mitgliedschaften abrufen
|
||||
|
||||
```http
|
||||
GET /api/members/expiring-memberships
|
||||
```
|
||||
|
||||
Ruft Mitglieder ab, deren Mitgliedschaft in den nächsten Tagen abläuft.
|
||||
|
||||
#### Query-Parameter
|
||||
|
||||
| Parameter | Typ | Standard | Beschreibung |
|
||||
|-----------|-----|----------|--------------|
|
||||
| `daysAhead` | integer | `30` | Anzahl Tage im Voraus |
|
||||
|
||||
#### Beispiel-Anfrage
|
||||
|
||||
```http
|
||||
GET /api/members/expiring-memberships?daysAhead=14
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
|
||||
#### Erfolgreiche Antwort (200 OK)
|
||||
|
||||
```json
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"memberId": "123e4567-e89b-12d3-a456-426614174000",
|
||||
"firstName": "Max",
|
||||
"lastName": "Schmidt",
|
||||
"email": "max.schmidt@example.com",
|
||||
"membershipNumber": "M2024001",
|
||||
"membershipEndDate": "2025-08-10",
|
||||
"daysUntilExpiry": 14
|
||||
}
|
||||
],
|
||||
"success": true,
|
||||
"message": null,
|
||||
"errors": [],
|
||||
"timestamp": "2025-07-25T12:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 10. Mitglieder nach Datumsbereich abrufen
|
||||
|
||||
```http
|
||||
GET /api/members/by-date-range
|
||||
```
|
||||
|
||||
Ruft Mitglieder basierend auf einem Datumsbereich ab.
|
||||
|
||||
#### Query-Parameter
|
||||
|
||||
| Parameter | Typ | Erforderlich | Beschreibung |
|
||||
|-----------|-----|--------------|--------------|
|
||||
| `startDate` | string (YYYY-MM-DD) | Ja | Startdatum |
|
||||
| `endDate` | string (YYYY-MM-DD) | Ja | Enddatum |
|
||||
| `dateType` | string | Nein | `MEMBERSHIP_START_DATE` oder `MEMBERSHIP_END_DATE` |
|
||||
|
||||
#### Beispiel-Anfrage
|
||||
|
||||
```http
|
||||
GET /api/members/by-date-range?startDate=2024-01-01&endDate=2024-12-31&dateType=MEMBERSHIP_START_DATE
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
|
||||
#### Fehler-Antworten
|
||||
|
||||
- **400 Bad Request**: Ungültiges Datumsformat oder Datumstyp
|
||||
|
||||
### 11. E-Mail-Eindeutigkeit validieren
|
||||
|
||||
```http
|
||||
GET /api/members/validate/email/{email}
|
||||
```
|
||||
|
||||
Prüft, ob eine E-Mail-Adresse bereits verwendet wird.
|
||||
|
||||
#### Pfad-Parameter
|
||||
|
||||
| Parameter | Typ | Beschreibung |
|
||||
|-----------|-----|--------------|
|
||||
| `email` | string | Zu prüfende E-Mail-Adresse |
|
||||
|
||||
#### Query-Parameter
|
||||
|
||||
| Parameter | Typ | Beschreibung |
|
||||
|-----------|-----|--------------|
|
||||
| `excludeMemberId` | UUID | Mitglieder-ID zum Ausschließen (für Updates) |
|
||||
|
||||
#### Beispiel-Anfrage
|
||||
|
||||
```http
|
||||
GET /api/members/validate/email/test@example.com?excludeMemberId=123e4567-e89b-12d3-a456-426614174000
|
||||
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
|
||||
```
|
||||
|
||||
#### Erfolgreiche Antwort (200 OK)
|
||||
|
||||
```json
|
||||
{
|
||||
"data": {
|
||||
"isValid": true,
|
||||
"isUnique": false,
|
||||
"message": "Email address is already in use"
|
||||
},
|
||||
"success": true,
|
||||
"message": null,
|
||||
"errors": [],
|
||||
"timestamp": "2025-07-25T12:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### 12. Mitgliedsnummer-Eindeutigkeit validieren
|
||||
|
||||
```http
|
||||
GET /api/members/validate/membership-number/{membershipNumber}
|
||||
```
|
||||
|
||||
Prüft, ob eine Mitgliedsnummer bereits verwendet wird.
|
||||
|
||||
#### Pfad-Parameter
|
||||
|
||||
| Parameter | Typ | Beschreibung |
|
||||
|-----------|-----|--------------|
|
||||
| `membershipNumber` | string | Zu prüfende Mitgliedsnummer |
|
||||
|
||||
#### Query-Parameter
|
||||
|
||||
| Parameter | Typ | Beschreibung |
|
||||
|-----------|-----|--------------|
|
||||
| `excludeMemberId` | UUID | Mitglieder-ID zum Ausschließen (für Updates) |
|
||||
|
||||
## Datenmodelle
|
||||
|
||||
### Member (Mitglied)
|
||||
|
||||
```json
|
||||
{
|
||||
"memberId": "UUID",
|
||||
"firstName": "string",
|
||||
"lastName": "string",
|
||||
"email": "string",
|
||||
"phone": "string (optional)",
|
||||
"dateOfBirth": "string (YYYY-MM-DD, optional)",
|
||||
"membershipNumber": "string",
|
||||
"membershipStartDate": "string (YYYY-MM-DD)",
|
||||
"membershipEndDate": "string (YYYY-MM-DD, optional)",
|
||||
"isActive": "boolean",
|
||||
"address": "string (optional)",
|
||||
"emergencyContact": "string (optional)",
|
||||
"createdAt": "string (ISO 8601)",
|
||||
"updatedAt": "string (ISO 8601)"
|
||||
}
|
||||
```
|
||||
|
||||
### CreateMemberRequest
|
||||
|
||||
```json
|
||||
{
|
||||
"firstName": "string (required)",
|
||||
"lastName": "string (required)",
|
||||
"email": "string (required)",
|
||||
"phone": "string (optional)",
|
||||
"dateOfBirth": "string (YYYY-MM-DD, optional)",
|
||||
"membershipNumber": "string (required)",
|
||||
"membershipStartDate": "string (YYYY-MM-DD, required)",
|
||||
"membershipEndDate": "string (YYYY-MM-DD, optional)",
|
||||
"isActive": "boolean (default: true)",
|
||||
"address": "string (optional)",
|
||||
"emergencyContact": "string (optional)"
|
||||
}
|
||||
```
|
||||
|
||||
### UpdateMemberRequest
|
||||
|
||||
Identisch mit `CreateMemberRequest`.
|
||||
|
||||
### MemberStats
|
||||
|
||||
```json
|
||||
{
|
||||
"totalActive": "number",
|
||||
"totalMembers": "number"
|
||||
}
|
||||
```
|
||||
|
||||
## Validierungsregeln
|
||||
|
||||
### Pflichtfelder
|
||||
|
||||
- `firstName`: Nicht leer
|
||||
- `lastName`: Nicht leer
|
||||
- `email`: Gültige E-Mail-Adresse, eindeutig
|
||||
- `membershipNumber`: Nicht leer, eindeutig
|
||||
- `membershipStartDate`: Gültiges Datum
|
||||
|
||||
### Geschäftsregeln
|
||||
|
||||
- E-Mail-Adresse muss eindeutig sein
|
||||
- Mitgliedsnummer muss eindeutig sein
|
||||
- `membershipEndDate` muss nach `membershipStartDate` liegen (falls angegeben)
|
||||
- Telefonnummer muss gültiges Format haben (falls angegeben)
|
||||
|
||||
## Fehlerbehandlung
|
||||
|
||||
### Validierungsfehler (422 Unprocessable Entity)
|
||||
|
||||
```json
|
||||
{
|
||||
"data": null,
|
||||
"success": false,
|
||||
"message": "Validation failed",
|
||||
"errors": [
|
||||
{
|
||||
"field": "email",
|
||||
"message": "Email address is invalid",
|
||||
"code": "INVALID_EMAIL"
|
||||
},
|
||||
{
|
||||
"field": "membershipNumber",
|
||||
"message": "Membership number already exists",
|
||||
"code": "DUPLICATE_MEMBERSHIP_NUMBER"
|
||||
}
|
||||
],
|
||||
"timestamp": "2025-07-25T12:37:00Z"
|
||||
}
|
||||
```
|
||||
|
||||
### Häufige Fehlercodes
|
||||
|
||||
| Code | Beschreibung |
|
||||
|------|--------------|
|
||||
| `MEMBER_NOT_FOUND` | Mitglied nicht gefunden |
|
||||
| `INVALID_EMAIL` | Ungültige E-Mail-Adresse |
|
||||
| `DUPLICATE_EMAIL` | E-Mail bereits vorhanden |
|
||||
| `DUPLICATE_MEMBERSHIP_NUMBER` | Mitgliedsnummer bereits vorhanden |
|
||||
| `INVALID_DATE_FORMAT` | Ungültiges Datumsformat |
|
||||
| `INVALID_UUID_FORMAT` | Ungültiges UUID-Format |
|
||||
| `MEMBERSHIP_DATE_CONFLICT` | Enddatum vor Startdatum |
|
||||
|
||||
## Beispiel-Workflows
|
||||
|
||||
### Neues Mitglied registrieren
|
||||
|
||||
1. **E-Mail validieren**: `GET /api/members/validate/email/{email}`
|
||||
2. **Mitgliedsnummer validieren**: `GET /api/members/validate/membership-number/{membershipNumber}`
|
||||
3. **Mitglied erstellen**: `POST /api/members`
|
||||
|
||||
### Mitglied aktualisieren
|
||||
|
||||
1. **Aktuelles Mitglied abrufen**: `GET /api/members/{id}`
|
||||
2. **E-Mail validieren** (falls geändert): `GET /api/members/validate/email/{email}?excludeMemberId={id}`
|
||||
3. **Mitglied aktualisieren**: `PUT /api/members/{id}`
|
||||
|
||||
### Ablaufende Mitgliedschaften verwalten
|
||||
|
||||
1. **Ablaufende Mitgliedschaften abrufen**: `GET /api/members/expiring-memberships?daysAhead=30`
|
||||
2. **Für jedes Mitglied**: Benachrichtigung senden oder Verlängerung anbieten
|
||||
|
||||
## Rate Limiting
|
||||
|
||||
- **Authentifizierte Anfragen**: 1000 Anfragen/Stunde
|
||||
- **Validierungs-Endpunkte**: 100 Anfragen/Minute (zusätzliches Limit)
|
||||
|
||||
## Caching
|
||||
|
||||
- **GET-Anfragen**: 5 Minuten Cache (außer Validierungs-Endpunkte)
|
||||
- **Statistiken**: 15 Minuten Cache
|
||||
- **Cache-Invalidierung**: Bei POST/PUT/DELETE-Operationen
|
||||
|
||||
---
|
||||
|
||||
**Letzte Aktualisierung**: 25. Juli 2025
|
||||
**API-Version**: v1.0
|
||||
**Controller-Version**: MemberController v1.0
|
||||
@@ -1,14 +1,15 @@
|
||||
# ADR-0000: Vorlage für Architekturentscheidungsaufzeichnung
|
||||
# ADR-0000: Vorlage für Architekturentscheidungsaufzeichnungen
|
||||
|
||||
## Status
|
||||
|
||||
[Vorgeschlagen | Akzeptiert | Veraltet | Ersetzt]
|
||||
|
||||
Falls ersetzt, fügen Sie einen Verweis auf die neue ADR ein: [ADR-XXXX](XXXX-filename.md)
|
||||
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.
|
||||
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
|
||||
|
||||
@@ -16,7 +17,9 @@ 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.
|
||||
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
|
||||
|
||||
|
||||
@@ -6,18 +6,21 @@ 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:
|
||||
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 eng koordinieren, was die Entwicklung verlangsamte
|
||||
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 modulareren Architektur migrieren sollte.
|
||||
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:
|
||||
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
|
||||
@@ -27,7 +30,8 @@ Wir haben uns entschieden, von einer monolithischen Struktur zu einer modularen
|
||||
- **infrastructure**: Gemeinsame Infrastrukturkomponenten
|
||||
- **client**: Client-Anwendungen
|
||||
|
||||
Jedes Domänenmodul (masterdata, members, horses, events) folgt einem Clean-Architecture-Ansatz mit separaten API-, Anwendungs-, Domänen-, Infrastruktur- und Service-Schichten.
|
||||
Jedes Domänenmodul (masterdata, members, horses, events) folgt einem Clean-Architecture-Ansatz mit separaten API-,
|
||||
Anwendung-, Domänen-, Infrastruktur- und Service-Schichten.
|
||||
|
||||
## Konsequenzen
|
||||
|
||||
@@ -55,14 +59,17 @@ Jedes Domänenmodul (masterdata, members, horses, events) folgt einem Clean-Arch
|
||||
|
||||
### 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.
|
||||
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 feingranulareren 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.
|
||||
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
|
||||
|
||||
- [Migrationshinweise in README.md](../../../../README.md#aktuelle-migrationshinweise)
|
||||
- [Modular Monoliths von Simon Brown](https://simonbrown.je/blog/modularity-and-microservices/)
|
||||
- [Clean Architecture von Robert C. Martin](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
|
||||
- [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)
|
||||
|
||||
@@ -6,26 +6,31 @@ 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:
|
||||
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.
|
||||
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:
|
||||
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
|
||||
@@ -55,14 +60,19 @@ Wir haben uns entschieden, Domain-Driven Design (DDD)-Prinzipien für die Organi
|
||||
|
||||
### 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.
|
||||
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.
|
||||
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://domainlanguage.com/ddd/)
|
||||
- [Implementing Domain-Driven Design von Vaughn Vernon](https://vaughnvernon.co/?page_id=168)
|
||||
- [Clean Architecture von Robert C. Martin](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
|
||||
- [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)
|
||||
|
||||
@@ -6,17 +6,21 @@ 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:
|
||||
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
|
||||
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 Teamverantwortlichkeiten übereinstimmen
|
||||
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:
|
||||
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
|
||||
@@ -24,34 +28,39 @@ Wir haben uns entschieden, eine Microservices-Architektur zu implementieren, bei
|
||||
- **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**: Authentifizierungs- und Autorisierungsdienst (Keycloak)
|
||||
- **auth**: Authentifizierung- und Autorisierungsdienst (Keycloak)
|
||||
- **cache**: Caching-Dienst (Redis)
|
||||
- **messaging**: Message Broker für die Kommunikation zwischen Diensten (Kafka)
|
||||
- **monitoring**: Überwachungs- und Beobachtbarkeitsdienste
|
||||
- **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
|
||||
- **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 Teamverantwortlichkeiten übereinstimmen
|
||||
- **Kleinere Codebasen**: Jeder Dienst hat eine kleinere, fokussiertere Codebasis
|
||||
- **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
|
||||
- **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
|
||||
|
||||
@@ -64,14 +73,19 @@ Wir haben auch unterstützende Infrastrukturdienste implementiert:
|
||||
|
||||
### Modularer Monolith
|
||||
|
||||
Wir haben die Implementierung eines modularen Monolithen in Betracht gezogen, bei dem alle Module als eine einzige Anwendung bereitgestellt würden, 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.
|
||||
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 dienstbasierte Architektur mit weniger, 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.
|
||||
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://martinfowler.com/articles/microservices.html)
|
||||
- [Building Microservices von Sam Newman](https://samnewman.io/books/building_microservices/)
|
||||
- [Microservices Patterns von Chris Richardson](https://microservices.io/book)
|
||||
- [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)
|
||||
|
||||
@@ -6,7 +6,8 @@ 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:
|
||||
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
|
||||
@@ -16,15 +17,17 @@ Mit der Einführung einer Microservices-Architektur ([ADR-0003](0003-microservic
|
||||
|
||||
## Entscheidung
|
||||
|
||||
Wir haben uns entschieden, ein ereignisgesteuertes Kommunikationsmuster mit Apache Kafka als Message Broker zu implementieren. Die wichtigsten Aspekte dieses Ansatzes umfassen:
|
||||
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, um Kompatibilität zu gewährleisten
|
||||
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
|
||||
@@ -57,19 +60,25 @@ Die Implementierung umfasst:
|
||||
|
||||
### 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.
|
||||
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.
|
||||
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.
|
||||
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://www.enterpriseintegrationpatterns.com/)
|
||||
- [Event-Driven Architecture von Martin Fowler](https://martinfowler.com/articles/201701-event-driven.html)
|
||||
- [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://docs.microsoft.com/de-de/azure/architecture/patterns/event-sourcing)
|
||||
- [Event Sourcing Pattern](https://meldestelle-pro.youtrack.cloud/api/files/526-26?sign=MTc2MjU2MDAwMDAwMHwyLTF8NTI2LTI2fEZURXo4SVVIbmtwcUExVFlab3BLZkVyRFlZS3B1bTFNX1ROMFR4aElBMW8NCg&updated=1762343212733)
|
||||
|
||||
@@ -6,52 +6,64 @@ 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:
|
||||
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.
|
||||
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:
|
||||
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
|
||||
|
||||
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
|
||||
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.
|
||||
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
|
||||
- **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
|
||||
- **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
|
||||
- **Komplexität bei Backup und Wiederherstellung**: Verschiedene Speichertechnologien haben unterschiedliche Backup- und
|
||||
Wiederherstellungsverfahren
|
||||
|
||||
### Neutral
|
||||
|
||||
@@ -62,20 +74,27 @@ Jeder Dienst ist für die Verwaltung seiner eigenen Datenspeicherung verantwortl
|
||||
|
||||
### 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.
|
||||
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.
|
||||
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.
|
||||
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://martinfowler.com/bliki/PolyglotPersistence.html)
|
||||
- [PostgreSQL Dokumentation](https://www.postgresql.org/docs/)
|
||||
- [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/guide/index.html)
|
||||
- [Elasticsearch Dokumentation](https://www.elastic.co/docs/solutions/search)
|
||||
|
||||
@@ -6,7 +6,8 @@ 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:
|
||||
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)
|
||||
@@ -14,13 +15,15 @@ Als Teil unserer Microservices-Architektur ([ADR-0003](0003-microservices-archit
|
||||
4. Benutzerverwaltungsfunktionen einschließlich Selbstregistrierung und Profilmanagement
|
||||
5. Integration mit externen Identitätsanbietern
|
||||
6. Sicherheits-Best-Practices einschließlich Passwortrichtlinien und Kontosperrung
|
||||
7. Token-basierte Authentifizierung für die Kommunikation zwischen Diensten
|
||||
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.
|
||||
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 23.0) als unsere Identitäts- und Zugriffsverwaltungslösung zu verwenden. Keycloak ist eine Open-Source-Identitäts- und Zugriffsverwaltungslösung, die Folgendes bietet:
|
||||
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
|
||||
@@ -28,10 +31,11 @@ Wir haben uns entschieden, Keycloak (Version 23.0) als unsere Identitäts- und Z
|
||||
4. **Single Sign-On**: Über alle Anwendungen und Dienste hinweg
|
||||
5. **Feingranulare Autorisierung**: Rollen- und attributbasierte Zugriffssteuerung
|
||||
6. **Benutzerverwaltung**: Selbstregistrierung, Profilmanagement, Passwortrichtlinien
|
||||
7. **Token-basierte Authentifizierung**: JWT-Tokens für die Kommunikation zwischen Diensten
|
||||
7. **Tokenbasierte Authentifizierung**: JWT-Tokens für die Kommunikation zwischen Diensten
|
||||
|
||||
Unsere Implementierung umfasst:
|
||||
- Keycloak-Server, der als containerisierter Dienst bereitgestellt wird
|
||||
|
||||
- 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
|
||||
@@ -56,26 +60,31 @@ Unsere Implementierung umfasst:
|
||||
|
||||
### Neutral
|
||||
|
||||
- **Konfigurationsbedarf**: Keycloak erfordert sorgfältige Konfiguration, um mit unseren Sicherheitsanforderungen übereinzustimmen
|
||||
- **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.
|
||||
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.
|
||||
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.
|
||||
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/)
|
||||
- [Absicherung von Microservices mit Keycloak](https://www.keycloak.org/docs/latest/securing_apps/)
|
||||
|
||||
@@ -6,7 +6,8 @@ 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:
|
||||
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
|
||||
@@ -15,14 +16,18 @@ Mit unserer Microservices-Architektur ([ADR-0003](0003-microservices-architectur
|
||||
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.
|
||||
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:
|
||||
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
|
||||
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
|
||||
@@ -31,7 +36,8 @@ Wir haben uns entschieden, das API-Gateway-Muster mit Spring Cloud Gateway (Spri
|
||||
8. **Service-Discovery**: Integration mit Consul/Eureka
|
||||
|
||||
Unsere Implementierung umfasst:
|
||||
- Eine Spring-Cloud-Gateway-Applikation (Spring Boot), containerisiert
|
||||
|
||||
- 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
|
||||
@@ -50,9 +56,9 @@ Unsere Implementierung umfasst:
|
||||
### Negative
|
||||
|
||||
- **Single Point of Failure**: Das Gateway wird zu einer kritischen Komponente, die hochverfügbar sein muss
|
||||
- **Leistungs-Overhead**: Anfragen durchlaufen einen zusätzlichen Netzwerk-Hop
|
||||
- **Leistung-Overhead**: Anfragen durchlaufen einen zusätzlichen Netzwerk-Hop
|
||||
- **Komplexität**: Das Gateway muss eine breite Palette von Funktionalitäten handhaben
|
||||
- **Entwicklungs-Engpass**: Änderungen am Gateway können Koordination über Teams hinweg erfordern
|
||||
- **Entwicklung-Engpass**: Änderungen am Gateway können Koordination über Teams hinweg erfordern
|
||||
|
||||
### Neutral
|
||||
|
||||
@@ -63,18 +69,24 @@ Unsere Implementierung umfasst:
|
||||
|
||||
### 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.
|
||||
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 clientspezifische Optimierungen ermöglicht, hätte aber den Entwicklungs- und Betriebsaufwand erhöht.
|
||||
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.
|
||||
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
|
||||
|
||||
- <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>
|
||||
|
||||
@@ -13,68 +13,83 @@ Unser System benötigt Client-Anwendungen für verschiedene Benutzerrollen und P
|
||||
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.
|
||||
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
|
||||
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.
|
||||
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
|
||||
|
||||
- **Code-Sharing**: Wesentliche Teile des Codes werden über Plattformen hinweg geteilt, was Duplizierung reduziert
|
||||
- **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
|
||||
- **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 plattformnativen Lösungen zu Leistungs-Overhead kommen
|
||||
- **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 Überlegung
|
||||
- **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.
|
||||
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 Code-Sharing zwischen Mobile und Web ermöglicht, hätte aber immer noch eine separate Desktop-Lösung erfordert und hätte JavaScript-Expertise erfordert.
|
||||
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.
|
||||
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
|
||||
|
||||
|
||||
@@ -5,14 +5,16 @@ last_reviewed: 2025-10-22
|
||||
review_cycle: 180d
|
||||
summary: Empfehlungen für Branchschutz, PR-Ablauf und Naming-Konventionen.
|
||||
yt_epic: MP-1
|
||||
yt_issues: []
|
||||
yt_issues: [ ]
|
||||
---
|
||||
|
||||
# Branchschutz & Pull-Request Workflow
|
||||
|
||||
Diese Anleitung beschreibt einen einfachen, robusten Flow für `main` mit kurzen Feature-Branches und klaren Qualitätschecks.
|
||||
Diese Anleitung beschreibt einen einfachen, robusten Flow für `main` mit kurzen Feature-Branches und klaren
|
||||
Qualitätschecks.
|
||||
|
||||
## 1) Branch-Naming
|
||||
|
||||
- Feature: `feature/<kurz-beschreibung>`
|
||||
- Bugfix: `fix/<kurz-beschreibung>`
|
||||
- Docs: `docs/<kurz-beschreibung>`
|
||||
@@ -20,11 +22,13 @@ Diese Anleitung beschreibt einen einfachen, robusten Flow für `main` mit kurzen
|
||||
Optional: Issue-Key voranstellen, z. B. `feature/MP-7-doku-konsolidieren`.
|
||||
|
||||
## 2) Pull Request (PR)
|
||||
|
||||
- PR-Titel nach Conventional Commits (kurz): `docs(api): Front‑Matter vereinheitlicht (MP-7)`
|
||||
- Beschreibung kurz mit Bulletpoints; DoD-Checkliste abhaken (Template vorhanden)
|
||||
- CI muss grün sein (Backend + Docs)
|
||||
|
||||
## 3) Branchschutz (GitHub Einstellungen → Branches → main)
|
||||
|
||||
- Require a pull request before merging
|
||||
- Require status checks to pass before merging
|
||||
- aktivieren: `CI Docs`, `CI` (Backend falls vorhanden)
|
||||
@@ -34,16 +38,20 @@ Optional: Issue-Key voranstellen, z. B. `feature/MP-7-doku-konsolidieren`.
|
||||
- Disallow force pushes, Disallow deletions
|
||||
|
||||
## 4) Commits & YouTrack
|
||||
|
||||
- Commit-Message enthält Issue-Key (z. B. `MP-7`) → erleichtert Nachverfolgung
|
||||
- In Doku-Front‑Matter `yt_epic`/`yt_issues` pflegen
|
||||
- Optional: GitHub Secrets `YT_URL`, `YT_TOKEN` setzen → CI validiert verlinkte Issues, und `youtrack-sync.yml` kommentiert beim Merge automatisch ins Issue
|
||||
- Optional: GitHub Secrets `YT_URL`, `YT_TOKEN` setzen → CI validiert verlinkte Issues, und `youtrack-sync.yml`
|
||||
kommentiert beim Merge automatisch ins Issue
|
||||
|
||||
## 5) Definition of Done (Auszug)
|
||||
|
||||
- Doku aktuell (README/ADR/C4/API)
|
||||
- Front‑Matter valide (`modul`, `status`, `summary`, optional `last_reviewed`, `review_cycle`, `yt_*`)
|
||||
- Links funktionieren (CI link-check grün)
|
||||
- Tests grün
|
||||
|
||||
## 6) Lokale Tipps
|
||||
|
||||
- Vor dem Push: `markdownlint`, `vale` lokal laufen lassen (optional via pre-commit hooks)
|
||||
- kleine, häufige PRs statt großer Monster-PRs
|
||||
|
||||
@@ -1,53 +0,0 @@
|
||||
---
|
||||
owner: ops-team
|
||||
status: active
|
||||
review_cycle: 180d
|
||||
last_reviewed: 2025-10-15
|
||||
summary: Anleitung zur Installation und Konfiguration des Nginx Reverse Proxys auf dem Proxmox-Host für die Meldestelle-Services.
|
||||
---
|
||||
|
||||
# How-To: Proxmox/Nginx Reverse Proxy deployen
|
||||
|
||||
Diese Anleitung beschreibt die Einrichtung des Nginx Reverse Proxys auf dem Proxmox-Host. Die Beispielkonfiguration liegt im Repository und wird unverändert übernommen.
|
||||
|
||||
- Beispielkonfiguration: proxmox-nginx/meldestelle.conf
|
||||
|
||||
## Voraussetzungen
|
||||
- Proxmox-Host mit root-/sudo-Zugang
|
||||
- Installiertes Nginx (`apt install nginx`)
|
||||
- Lokale Container-Services laufen auf dem Host und sind über `localhost` erreichbar (Web 4000, Gateway 8081, VNC 6080)
|
||||
|
||||
## Schritte
|
||||
1) Konfigurationsdatei auf den Host kopieren
|
||||
```bash
|
||||
sudo cp docs/proxmox-nginx/meldestelle.conf /etc/nginx/sites-available/
|
||||
```
|
||||
|
||||
2) Site aktivieren (Symlink anlegen)
|
||||
```bash
|
||||
sudo ln -s /etc/nginx/sites-available/meldestelle.conf /etc/nginx/sites-enabled/
|
||||
```
|
||||
|
||||
3) Nginx Konfiguration testen und neu laden
|
||||
```bash
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
4) DNS konfigurieren (Beispiele)
|
||||
- meldestelle.yourdomain.com → öffentliche IP deines Proxmox-Hosts
|
||||
- api.meldestelle.yourdomain.com → öffentliche IP deines Proxmox-Hosts
|
||||
- vnc.meldestelle.yourdomain.com → öffentliche IP deines Proxmox-Hosts
|
||||
|
||||
5) Health-Checks
|
||||
```bash
|
||||
curl -i http://api.meldestelle.yourdomain.com/actuator/health
|
||||
curl -i http://meldestelle.yourdomain.com/health
|
||||
```
|
||||
|
||||
## HTTPS (optional)
|
||||
In der Beispielkonfiguration sind HTTPS-Serverblöcke und HTTP→HTTPS Redirects als Kommentar enthalten. Aktiviere diese Blöcke, wenn du Zertifikate (Let's Encrypt/Cloudflare) eingerichtet hast. Datei: proxmox-nginx/meldestelle.conf
|
||||
|
||||
## Fehlerbehebung
|
||||
- 502 Bad Gateway: Zielcontainer läuft nicht oder Port falsch → Dienste starten (`make full-up`) und Ports prüfen.
|
||||
- CORS-Fehler: API ausschließlich über die `api.*`-Domain aufrufen; Web-App über `meldestelle.*`.
|
||||
- Änderungen ohne Effekt: `nginx -t` ausführen und `systemctl reload nginx`.
|
||||
@@ -0,0 +1,66 @@
|
||||
---
|
||||
owner: project-maintainers
|
||||
status: active
|
||||
review_cycle: 365d
|
||||
last_reviewed: 2025-10-28
|
||||
summary: KDoc-Styleguide für die Meldestelle. Mindeststandards für KDoc, damit Dokka lesbare API-Doku generiert.
|
||||
bc: infrastructure
|
||||
doc_type: how-to
|
||||
---
|
||||
|
||||
# KDoc-Styleguide (Kurzfassung)
|
||||
|
||||
Dieser Styleguide definiert die wichtigsten Regeln für KDoc-Kommentare in Kotlin-Projekten der Meldestelle. Ziel:
|
||||
Verständliche, konsistente API-Dokumentation via Dokka (GFM/HTML).
|
||||
|
||||
## Grundregeln
|
||||
|
||||
- Sprache: Deutsch für Fließtexte; Code/Bezeichner bleiben Englisch.
|
||||
- Jeder public class, interface, object, enum, public function und public property erhält einen KDoc-Block.
|
||||
- KDoc beginnt mit einem vollständigen, aussagekräftigen Satz in der dritten Person.
|
||||
- Beispiele und wichtige Hinweise als kurze Absätze oder Listen, keine Romane.
|
||||
|
||||
## Struktur eines KDoc-Blocks
|
||||
|
||||
```kotlin
|
||||
/**
|
||||
* Beschreibt prägnant, was das Element macht und warum es existiert.
|
||||
*
|
||||
* Details: Optionale Erläuterung von Parametern, Nebenwirkungen, Fehlerfällen.
|
||||
*
|
||||
* @param id Eindeutige Kennung des Members
|
||||
* @return Das gefundene Objekt oder null, wenn nicht vorhanden
|
||||
* @throws IllegalArgumentException Falls Parameter ungültig sind
|
||||
*/
|
||||
fun findMember(id: MemberId): Member?
|
||||
```
|
||||
|
||||
## Tags
|
||||
|
||||
- @param: Für jeden Parameter bei public Funktionen
|
||||
- @return: Wenn Rückgabewert semantisch relevant ist
|
||||
- @throws: Relevante Exceptions dokumentieren
|
||||
- @since, @see: Sparsam verwenden, wenn es wirklichen Mehrwert bringt
|
||||
|
||||
## Stil & Sprache
|
||||
|
||||
- Klar, knapp, aktiv. Keine Redundanz.
|
||||
- Domänenbegriffe verwenden (BCs: members, horses, events, masterdata, infrastructure).
|
||||
- Keine Interna oder Secrets dokumentieren.
|
||||
|
||||
## Beispielschnipsel
|
||||
|
||||
```kotlin
|
||||
/** Erstellt einen neuen Event und persistiert ihn transaktional. */
|
||||
fun createEvent(cmd: CreateEventCommand): EventId
|
||||
```
|
||||
|
||||
## Dokka-Hinweise
|
||||
|
||||
- Dokka erzeugt GFM (Markdown) unter build/dokka/gfm und HTML unter build/dokka/html.
|
||||
- Source-Link führt auf GitHub (main-Branch). Prüfe Links in der CI.
|
||||
|
||||
## Review
|
||||
|
||||
- PR-Checklist: "KDoc vollständig?" anhaken, wenn neue public APIs hinzugekommen sind.
|
||||
- Vale/markdownlint gelten nur für .md; KDoc wird redaktionell in Code-Reviews geprüft.
|
||||
+25
-10
@@ -4,6 +4,8 @@ status: active
|
||||
review_cycle: 90d
|
||||
last_reviewed: 2025-10-15
|
||||
summary: Kürzeste Anleitung, um das komplette System lokal zu starten und zu prüfen, ob alles läuft.
|
||||
bc: infrastructure
|
||||
doc_type: how-to
|
||||
---
|
||||
|
||||
# How-To: Lokale Umgebung starten (Quickstart)
|
||||
@@ -11,35 +13,42 @@ summary: Kürzeste Anleitung, um das komplette System lokal zu starten und zu pr
|
||||
Diese Kurz-Anleitung bringt deine lokale Umgebung in wenigen Minuten zum Laufen.
|
||||
|
||||
## Starten
|
||||
|
||||
- Komplettes System (Infra + Services + Clients)
|
||||
|
||||
```bash
|
||||
make full-up
|
||||
```
|
||||
|
||||
- Nur Backend (Infra + Gateway + Microservices)
|
||||
|
||||
```bash
|
||||
make services-up
|
||||
```
|
||||
|
||||
- Nur Clients (Infra + Web-App)
|
||||
|
||||
```bash
|
||||
make clients-up
|
||||
```
|
||||
|
||||
Logs ansehen (z. B. Backend):
|
||||
|
||||
```bash
|
||||
make services-logs
|
||||
```
|
||||
|
||||
## Wichtige URLs
|
||||
- Web App: http://localhost:4000
|
||||
- API Gateway: http://localhost:8081 (Health: /actuator/health)
|
||||
- Keycloak (Auth): http://localhost:8180
|
||||
- Consul (Service Discovery): http://localhost:8500
|
||||
|
||||
Weitere Ports findest du unter: reference/ports-and-urls.md
|
||||
- Web App: <http://localhost:4000>
|
||||
- API Gateway: <http://localhost:8081> (Health: /actuator/health)
|
||||
- Keycloak (Auth): <http://localhost:8180>
|
||||
- Consul (Service Discovery): <http://localhost:8500>
|
||||
|
||||
Weitere Ports findest du unter: [reference/ports-and-urls.md](../reference/ports-and-urls.md)
|
||||
|
||||
## Health-Checks
|
||||
|
||||
```bash
|
||||
# Gateway
|
||||
curl -i http://localhost:8081/actuator/health
|
||||
@@ -49,19 +58,25 @@ curl -i http://localhost:4000/health || true
|
||||
```
|
||||
|
||||
## Auth (Keycloak)
|
||||
- Admin-Login (default): http://localhost:8180
|
||||
|
||||
- Admin-Login (default): <http://localhost:8180>
|
||||
- Username: KC_BOOTSTRAP_ADMIN_USERNAME (default: admin)
|
||||
- Password: KC_BOOTSTRAP_ADMIN_PASSWORD (default: admin)
|
||||
- Beim ersten Start wird der Realm aus docker/services/keycloak/meldestelle-realm.json importiert.
|
||||
|
||||
## Häufige Probleme
|
||||
- Dienste nicht erreichbar → Containers laufen? `make full-logs` bzw. `make services-logs` prüfen.
|
||||
|
||||
- Dienste sind nicht erreichbar → Container laufen? `make full-logs` bzw. `make services-logs` prüfen.
|
||||
- 401/403 beim API-Aufruf → Prüfen, ob ein gültiges Bearer-Token gesendet wird und Keycloak erreichbar ist.
|
||||
- CORS im Browser → API über das Gateway (http://localhost:8081) aufrufen und nicht direkt die Services (8082–8086).
|
||||
- CORS im Browser → API über das Gateway (<http://localhost:8081>) aufrufen und nicht direkt die Services (8082–8086).
|
||||
- Port-Kollisionen → Belegte Ports mit `lsof -i :PORT` prüfen oder Ports anpassen.
|
||||
|
||||
## Stoppen
|
||||
|
||||
```bash
|
||||
make full-down
|
||||
# oder spezifisch: make services-down / make clients-down / make infrastructure-down
|
||||
make full-down
|
||||
# oder spezifisch:
|
||||
make services-down
|
||||
make clients-down
|
||||
make infrastructure-down
|
||||
```
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
---
|
||||
owner: project-maintainers
|
||||
status: active
|
||||
review_cycle: 90d
|
||||
last_reviewed: 2025-10-15
|
||||
summary: Schlanker Einstiegspunkt in die Dokumentation der Meldestelle. Nur die wichtigsten Links für Start, Überblick, API, Produktion und aktuelles Vorhaben.
|
||||
---
|
||||
|
||||
# Meldestelle – Dokumentation (Startseite)
|
||||
|
||||
Willkommen! Das ist der zentrale Einstieg in die Projektdokumentation. Starte hier.
|
||||
|
||||
## Start
|
||||
- Schnellstart lokal: how-to/start-local.md
|
||||
- Gesamtüberblick: overview/system-overview.md
|
||||
|
||||
## API
|
||||
- API-Übersicht: api/README.md
|
||||
|
||||
## Betrieb
|
||||
- Produktion (Proxmox/Nginx): how-to/deploy-proxmox-nginx.md
|
||||
|
||||
## Aktuelles Vorhaben
|
||||
- Now-Page: now/current.md
|
||||
|
||||
Hinweis: Diese Seite ist der einzige offizielle Einstiegspunkt. Ältere Indizes (z. B. INDEX.md oder bilingualer Index) sind historisch bzw. entfernt.
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
owner: project-maintainers
|
||||
status: active
|
||||
last_reviewed: 2025-10-15
|
||||
review_cycle: 90d
|
||||
summary: Anleitung zur Nutzung der Now-Page (Initiativen-One‑Pager) als zentraler Steuerungs- und Übersichtspunkt.
|
||||
---
|
||||
|
||||
# Now-Page – Nutzung & Workflow
|
||||
|
||||
Die Now-Page ist ein schlanker One‑Pager für dein aktuelles Vorhaben. Sie beantwortet stets fünf Fragen: Was, Warum, Wie, Was ist zu tun, und Was ist als Nächstes dran.
|
||||
|
||||
## Struktur
|
||||
- Aktive Seite: `docs/now/current.md`
|
||||
- Vorlage: `docs/now/TEMPLATE.md`
|
||||
- Archiv (optional): `docs/now/archive/` (einfach Dateien hinein verschieben)
|
||||
|
||||
## So verwendest du die Now-Page
|
||||
1. Neue Initiative starten: Kopiere `TEMPLATE.md` nach `current.md` und fülle sie aus.
|
||||
2. Kurz halten: 1 Seite, maximal 5–10 Tasks. Große Aufgaben in kleinere Schneiden.
|
||||
3. Pflege-Ritual: Bei Änderung von Fokus/Status/Plan kurz aktualisieren, `last_reviewed` anpassen.
|
||||
4. Abschluss: `status: done` setzen, 3 Bulletpoints „Lessons Learned“ ergänzen und Datei nach `now/archive/` verschieben.
|
||||
5. Dauerhafte Entscheidungen: Als ADR in `docs/architecture/adr/` festhalten und aus der Now‑Page verlinken.
|
||||
|
||||
## Tipps
|
||||
- Verlinke nur, was du beim Arbeiten wirklich brauchst (PRs, Issues, wichtige How‑Tos).
|
||||
- Nutze die Now‑Page als Daily/Nächstes‑To‑Do‑Quelle statt vieler verstreuter Notizen.
|
||||
- Optional in CI: Einen „Stale‑Check“ einführen, der warnt, wenn `current.md` länger als `review_cycle` nicht aktualisiert wurde.
|
||||
|
||||
## Navigation
|
||||
- Die Startseite (docs/index.md) verlinkt direkt auf `now/current.md`, damit du jederzeit mit einem Klick am aktuellen Fokus bist.
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
owner: <dein-name-oder-team>
|
||||
status: active # active | blocked | done
|
||||
timeframe: YYYY-MM-DD → YYYY-MM-DD
|
||||
last_reviewed: YYYY-MM-DD
|
||||
review_cycle: 7d # erinnert dich wöchentlich ans Aktualisieren
|
||||
summary: One-Pager-Template für das aktuell wichtigste Vorhaben (Now-Page).
|
||||
---
|
||||
|
||||
# Aktuelle Initiative: <Titel>
|
||||
|
||||
## 1) Vision (Was?)
|
||||
Ein Satz Zielbild. Was soll am Ende anders/besser sein? Optional: In/Out of Scope.
|
||||
- In Scope: …
|
||||
- Out of Scope: …
|
||||
|
||||
## 2) Why (Warum so?)
|
||||
Problem, Zielmetriken/Erfolgskriterien, Alternativen/Trade-offs.
|
||||
- Erfolg messbar an: <Metriken/Kriterien>
|
||||
- Falls dauerhaft relevant: verweise auf ADR (`docs/adr/...`).
|
||||
|
||||
## 3) How (Wie umsetzen?)
|
||||
Kurzarchitektur, Ansatz, Risiken/Abhängigkeiten. 5–10 Zeilen genügen.
|
||||
- Ansatz: …
|
||||
- Risiken: …
|
||||
- Abhängigkeiten: …
|
||||
|
||||
## 4) Plan (Was ist jetzt zu tun?)
|
||||
Milestones + nächste konkrete Schritte. Max. 5–10 Tasks, sonst zu groß schneiden.
|
||||
- [ ] Schritt 1 (heute)
|
||||
- [ ] Schritt 2 (diese Woche)
|
||||
- [ ] Schritt 3 (nächste Woche)
|
||||
|
||||
## 5) Status & Nächster Fokus
|
||||
- Status: active | blocked | done
|
||||
- Nächster Fokus (heute): <1–2 Sätze>
|
||||
|
||||
## 6) Referenzen
|
||||
Links zu PRs, Issues, Diagrammen, Konfigs (nur die, die man wirklich braucht).
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
owner: stefan
|
||||
status: active
|
||||
timeframe: 2025-10-15 → 2025-10-29
|
||||
last_reviewed: 2025-10-15
|
||||
review_cycle: 7d
|
||||
summary: Git-Strategie (Trunk-based) + GitHub Actions CI/CD etablieren; Branchschutz, Releases per Tags; optional Images & Deploy zu Proxmox.
|
||||
---
|
||||
|
||||
# Aktuelle Initiative: Git-Flow & GitHub Actions Strategy
|
||||
|
||||
## 1) Vision (Was?)
|
||||
Ein schlanker, verlässlicher Dev-Flow: kurze Feature-Branches → PR → main, automatisierte CI, Releases per Tag; optional Build & Deploy.
|
||||
- In Scope: Branchschutz `main`, CI aktualisieren, Release-Tags, (optional) Image-Build & Deploy-Workflow
|
||||
- Out of Scope: Mehrstufige Environments/Canary, komplexe Monorepo-Pipelines
|
||||
|
||||
## 2) Why (Warum so?)
|
||||
Weniger Overhead als GitFlow, klare Qualitätstore via CI, reproduzierbare Releases mit Tags. Ziel: schneller und sicherer liefern.
|
||||
- Erfolg messbar an: CI grün auf PRs, geschützter `main`, erster Release-Tag `v0.1.0`, optional erfolgreicher Deploy-Run
|
||||
|
||||
## 3) How (Wie umsetzen?)
|
||||
- Trunk-based: `main` geschützt; kurzlebige Branches `feature/*`, `fix/*`, `docs/*`, Squash-Merge only; PR-Titel nach Conventional Commits
|
||||
- CI (CI.yml): Trigger auf PR/push zu `main`; Schritte: Gradle Build, Docs-Validation, optional Testreports-Artefakte; Concurrency aktiv
|
||||
- Releases: zunächst manuell taggen (`vX.Y.Z`); später optional `release-please`
|
||||
- Images: optional GHCR Build & Push bei Tags `v*` (Matrix für gateway, members, horses, events, masterdata, web)
|
||||
- Deploy: optional via SSH zu Proxmox (`docker compose pull && up -d`); Secrets im Repo setzen
|
||||
|
||||
## 4) Plan (Was ist jetzt zu tun?)
|
||||
- [ ] Branch umbenennen: `structur-umbau` → `feature/structur-umbau`; pushen und PR nach `main` eröffnen
|
||||
- [ ] Branchschutz für `main` setzen: PR erforderlich, Required Checks (`CI`), „Squash & Merge only“, lineare History
|
||||
- [ ] CI-Workflow anpassen: vorhandenes `.github/workflows/build.yml` auf PR/push nur `main`, Concurrency, Testreports-Upload
|
||||
- [ ] (Optional) Deploy-Workflow anlegen: `.github/workflows/deploy.yml` (SSH); Secrets setzen: `PROD_SSH_HOST`, `PROD_SSH_USER`, `PROD_SSH_KEY`
|
||||
- [ ] (Optional) Image-Build & Push bei Tags (`v*`) zu GHCR einführen
|
||||
- [ ] (Optional) Release-Strategie entscheiden: manuelle Tags vs. `release-please`; ggf. Workflow hinzufügen
|
||||
- [ ] Cloudflare/Nginx prüfen: DNS (Proxy ON), SSL/TLS „Full (strict)“, Origin-Zertifikat, HTTPS-Serverblöcke aktivieren
|
||||
- [ ] Smoke-Tests: Health über Domains prüfen (`/actuator/health`, `/health`)
|
||||
|
||||
## 5) Status & Nächster Fokus
|
||||
- Status: active
|
||||
- Nächster Fokus (heute): Branch umbenennen → PR; Branchschutz setzen; CI-Workflow auf `main` fokussieren
|
||||
|
||||
## 6) Referenzen
|
||||
- CI-Workflow aktuell: `.github/workflows/build.yml`
|
||||
- Docs-Validator: `scripts/validation/validate-docs.sh`
|
||||
- Nginx Beispiel: `docs/proxmox-nginx/meldestelle.conf`
|
||||
- Überblick/Start: `docs/overview/system-overview.md`, `docs/how-to/start-local.md`
|
||||
@@ -1,79 +0,0 @@
|
||||
---
|
||||
owner: project-owner
|
||||
status: active
|
||||
last_reviewed: 2025-10-15
|
||||
review_cycle: 90d
|
||||
summary: Gesamtüberblick – Was ist vorhanden, wie funktioniert es, wie starte/deploye ich es.
|
||||
---
|
||||
|
||||
# Meldestelle – System Overview (Kurz & vollständig)
|
||||
|
||||
## Was ist vorhanden (Bausteine)
|
||||
- Clients
|
||||
- Web App (Port 4000)
|
||||
- optional Desktop/noVNC (Port 6080)
|
||||
- Gateway & Services
|
||||
- API Gateway (Spring Cloud Gateway, Port 8081)
|
||||
- Microservices: Members (8083), Horses (8084), Events (8085), Masterdata (8086), Ping (8082)
|
||||
- Infrastruktur
|
||||
- Postgres (5432), Redis (6379), Keycloak (8180), Consul (8500)
|
||||
- Reverse Proxy (Produktion)
|
||||
- Nginx auf Proxmox-Host
|
||||
- vHosts: `meldestelle.yourdomain.com` (Web), `api.meldestelle.yourdomain.com` (API), `vnc.meldestelle.yourdomain.com` (VNC)
|
||||
|
||||
## Wie funktioniert es (Ablauf & Verantwortungen)
|
||||
- Einstieg nur über das API-Gateway (Security, CORS, Rate-Limits, Observability, Routing)
|
||||
- Authentifizierung via Keycloak (OIDC/JWT)
|
||||
- Web holt Token bei Keycloak → sendet Requests mit `Authorization: Bearer <JWT>`
|
||||
- Gateway validiert JWT (JWKs), injiziert Kontext, routet an Services
|
||||
- Service Discovery über Consul (Gateway ↔ Services)
|
||||
- Persistenz: Services schreiben/lesen in Postgres; Redis optional für Cache
|
||||
- Produktion: Öffentliche Zugriffe laufen über Nginx-vHosts → Gateway/Web/noVNC in Docker
|
||||
|
||||
## Starten & Stoppen (lokal)
|
||||
- Komplettes System: `make full-up`
|
||||
- Nur Infrastruktur: `make infrastructure-up`
|
||||
- Nur Backend (inkl. Gateway): `make services-up`
|
||||
- Nur Clients (inkl. Web): `make clients-up`
|
||||
- Stoppen: `make full-down` (bzw. `*-down`)
|
||||
- Logs: `make full-logs` (bzw. `services-logs`, `infrastructure-logs`)
|
||||
|
||||
## Health, URLs & Ports
|
||||
- Web: `http://localhost:4000` → Health: `/health`
|
||||
- Gateway: `http://localhost:8081` → Health: `/actuator/health`
|
||||
- Services (dev): Ping 8082, Members 8083, Horses 8084, Events 8085, Masterdata 8086
|
||||
- Keycloak: `http://localhost:8180`
|
||||
- Consul UI: `http://localhost:8500`
|
||||
- Postgres: `localhost:5432`
|
||||
- Redis: `localhost:6379`
|
||||
- noVNC: `http://localhost:6080`
|
||||
|
||||
## Auth-Flow (kurz)
|
||||
1. Web ruft geschützte Seite → Redirect zu Keycloak `/authorize`
|
||||
2. Login → Code → Token-Tausch (ID/Access Token)
|
||||
3. Web ruft Gateway mit `Bearer <JWT>` auf → Gateway prüft Token → leitet an Service
|
||||
|
||||
## Produktion (Proxmox/Nginx)
|
||||
- Datei: `docs/proxmox-nginx/meldestelle.conf`
|
||||
- vHosts:
|
||||
- `meldestelle.yourdomain.com` → Web (`localhost:4000`)
|
||||
- `api.meldestelle.yourdomain.com` → Gateway (`localhost:8081`)
|
||||
- `vnc.meldestelle.yourdomain.com` → noVNC (`localhost:6080`)
|
||||
- Health-Checks:
|
||||
- `curl -i http://api.meldestelle.yourdomain.com/actuator/health`
|
||||
- `curl -i http://meldestelle.yourdomain.com/health`
|
||||
|
||||
## Konfiguration auf einen Blick (Defaults)
|
||||
- Postgres: `POSTGRES_USER=meldestelle`, `POSTGRES_PASSWORD=meldestelle`, `POSTGRES_DB=meldestelle`
|
||||
- Keycloak Admin: `KC_BOOTSTRAP_ADMIN_USERNAME=admin`, `KC_BOOTSTRAP_ADMIN_PASSWORD=admin`
|
||||
- Gateway: Port 8081, Profil `dev` (per `SPRING_PROFILES_ACTIVE`)
|
||||
|
||||
## Troubleshooting (Top 5)
|
||||
- 401/403 am Gateway: Token fehlt/abgelaufen? Keycloak auf `http://localhost:8180` erreichbar?
|
||||
- 502/Bad Gateway: Zielservice down? Logs prüfen (`make services-logs`).
|
||||
- CORS im Browser: API über `api.meldestelle.*` bzw. `localhost:8081` aufrufen.
|
||||
- Consul leer: Services nicht registriert → Services neu starten.
|
||||
- Port-Konflikt: Belegte Ports mit `lsof -i :<port>` prüfen, Prozesse beenden.
|
||||
|
||||
## Diagramme (PlantUML)
|
||||
Siehe `docs/architecture/c4/` – Context & Container sowie Login‑Sequenz. In CI zu SVG rendern.
|
||||
@@ -1,181 +0,0 @@
|
||||
# ===================================================================
|
||||
# Nginx Host-Level Konfiguration für Proxmox-Server
|
||||
# Meldestelle Project - Reverse Proxy Setup
|
||||
# ===================================================================
|
||||
# Installation auf Proxmox:
|
||||
# sudo cp meldestelle.conf /etc/nginx/sites-available/
|
||||
# sudo ln -s /etc/nginx/sites-available/meldestelle.conf /etc/nginx/sites-enabled/
|
||||
# sudo nginx -t && sudo systemctl reload nginx
|
||||
# ===================================================================
|
||||
|
||||
# Upstream-Definitionen für Container-Services
|
||||
upstream meldestelle-web-app {
|
||||
server localhost:4000;
|
||||
}
|
||||
|
||||
upstream meldestelle-desktop-vnc {
|
||||
server localhost:6080;
|
||||
}
|
||||
|
||||
upstream meldestelle-api-gateway {
|
||||
server localhost:8081;
|
||||
}
|
||||
|
||||
# ===================================================================
|
||||
# Web-App (Hauptanwendung)
|
||||
# ===================================================================
|
||||
server {
|
||||
listen 80;
|
||||
server_name meldestelle.yourdomain.com;
|
||||
|
||||
# Security Headers
|
||||
add_header X-Frame-Options "SAMEORIGIN" always;
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header X-XSS-Protection "1; mode=block" always;
|
||||
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
|
||||
|
||||
# Logging
|
||||
access_log /var/log/nginx/meldestelle-web.access.log;
|
||||
error_log /var/log/nginx/meldestelle-web.error.log;
|
||||
|
||||
# Reverse Proxy zur Web-App
|
||||
location / {
|
||||
proxy_pass http://meldestelle-web-app;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_set_header X-Forwarded-Host $server_name;
|
||||
|
||||
# Timeouts
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
|
||||
# Buffering
|
||||
proxy_buffering on;
|
||||
proxy_buffer_size 4k;
|
||||
proxy_buffers 8 4k;
|
||||
}
|
||||
|
||||
# Health-Check Endpoint
|
||||
location /health {
|
||||
proxy_pass http://meldestelle-web-app/health;
|
||||
access_log off;
|
||||
}
|
||||
}
|
||||
|
||||
# ===================================================================
|
||||
# Desktop-VNC (noVNC Web-Interface)
|
||||
# ===================================================================
|
||||
server {
|
||||
listen 80;
|
||||
server_name vnc.meldestelle.yourdomain.com;
|
||||
|
||||
# Logging
|
||||
access_log /var/log/nginx/meldestelle-vnc.access.log;
|
||||
error_log /var/log/nginx/meldestelle-vnc.error.log;
|
||||
|
||||
# Reverse Proxy zum VNC-Container
|
||||
location / {
|
||||
proxy_pass http://meldestelle-desktop-vnc;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# WebSocket Support für noVNC
|
||||
proxy_http_version 1.1;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Origin "";
|
||||
|
||||
# VNC-spezifische Timeouts
|
||||
proxy_connect_timeout 60s;
|
||||
proxy_send_timeout 3600s;
|
||||
proxy_read_timeout 3600s;
|
||||
|
||||
# Buffering deaktivieren für Real-time
|
||||
proxy_buffering off;
|
||||
}
|
||||
}
|
||||
|
||||
# ===================================================================
|
||||
# API-Gateway (Direkter Zugriff)
|
||||
# ===================================================================
|
||||
server {
|
||||
listen 80;
|
||||
server_name api.meldestelle.yourdomain.com;
|
||||
|
||||
# Logging
|
||||
access_log /var/log/nginx/meldestelle-api.access.log;
|
||||
error_log /var/log/nginx/meldestelle-api.error.log;
|
||||
|
||||
# CORS Headers für API-Zugriff
|
||||
add_header Access-Control-Allow-Origin "*" always;
|
||||
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS" always;
|
||||
add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With" always;
|
||||
|
||||
# Reverse Proxy zum API-Gateway
|
||||
location / {
|
||||
# Handle preflight requests
|
||||
if ($request_method = 'OPTIONS') {
|
||||
add_header Access-Control-Allow-Origin "*";
|
||||
add_header Access-Control-Allow-Methods "GET, POST, PUT, DELETE, OPTIONS";
|
||||
add_header Access-Control-Allow-Headers "Content-Type, Authorization, X-Requested-With";
|
||||
add_header Access-Control-Max-Age 86400;
|
||||
add_header Content-Length 0;
|
||||
add_header Content-Type text/plain;
|
||||
return 204;
|
||||
}
|
||||
|
||||
proxy_pass http://meldestelle-api-gateway;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
|
||||
# API-spezifische Timeouts
|
||||
proxy_connect_timeout 30s;
|
||||
proxy_send_timeout 60s;
|
||||
proxy_read_timeout 60s;
|
||||
}
|
||||
|
||||
# Health-Check Endpoint
|
||||
location /actuator/health {
|
||||
proxy_pass http://meldestelle-api-gateway/actuator/health;
|
||||
access_log off;
|
||||
}
|
||||
}
|
||||
|
||||
# ===================================================================
|
||||
# SSL/HTTPS Konfiguration (Optional - für Cloudflare)
|
||||
# ===================================================================
|
||||
# Uncomment für HTTPS mit Let's Encrypt oder Cloudflare:
|
||||
#
|
||||
# server {
|
||||
# listen 443 ssl http2;
|
||||
# server_name meldestelle.yourdomain.com;
|
||||
#
|
||||
# ssl_certificate /etc/ssl/certs/meldestelle.crt;
|
||||
# ssl_certificate_key /etc/ssl/private/meldestelle.key;
|
||||
#
|
||||
# # SSL Configuration
|
||||
# ssl_protocols TLSv1.2 TLSv1.3;
|
||||
# ssl_ciphers ECDHE-RSA-AES256-GCM-SHA512:DHE-RSA-AES256-GCM-SHA512;
|
||||
# ssl_prefer_server_ciphers off;
|
||||
# ssl_session_cache shared:SSL:10m;
|
||||
#
|
||||
# # Rest der Web-App Konfiguration hier...
|
||||
# }
|
||||
|
||||
# ===================================================================
|
||||
# HTTP -> HTTPS Redirect (Optional)
|
||||
# ===================================================================
|
||||
# Uncomment für automatische HTTPS-Weiterleitung:
|
||||
#
|
||||
# server {
|
||||
# listen 80;
|
||||
# server_name meldestelle.yourdomain.com vnc.meldestelle.yourdomain.com api.meldestelle.yourdomain.com;
|
||||
# return 301 https://$server_name$request_uri;
|
||||
# }
|
||||
@@ -2,34 +2,44 @@
|
||||
owner: project-maintainers
|
||||
status: active
|
||||
review_cycle: 180d
|
||||
last_reviewed: 2025-10-15
|
||||
summary: Konsolidierte Übersicht aller relevanten lokalen Ports/URLs sowie der produktiven Domains (hinter Nginx).
|
||||
last_reviewed: 2025-10-31
|
||||
summary: "Übersicht der wichtigsten lokalen URLs und Ports. Quelle: docker/versions.toml"
|
||||
---
|
||||
|
||||
# Referenz: Ports & URLs
|
||||
# Referenz: Wichtige URLs und Ports (lokal)
|
||||
|
||||
Quelle der Wahrheit für Ports: [docker/versions.toml](../../docker/versions.toml) → [service-ports]
|
||||
|
||||
## Infrastruktur
|
||||
|
||||
## Lokal (Standard-Setup)
|
||||
- Web App: http://localhost:4000
|
||||
- API Gateway: http://localhost:8081
|
||||
- Health: http://localhost:8081/actuator/health
|
||||
- Services (nur lokal):
|
||||
- Ping Service: http://localhost:8082
|
||||
- Members Service: http://localhost:8083
|
||||
- Horses Service: http://localhost:8084
|
||||
- Events Service: http://localhost:8085
|
||||
- Masterdata Service: http://localhost:8086
|
||||
- Keycloak (Auth): http://localhost:8180
|
||||
- Consul (Service Discovery): http://localhost:8500
|
||||
- Postgres: localhost:5432
|
||||
- PostgreSQL: localhost:5432
|
||||
- Redis: localhost:6379
|
||||
- noVNC (Desktop): http://localhost:6080
|
||||
|
||||
Hinweis: In Produktion sind die einzelnen Services (8082–8086) nicht öffentlich erreichbar. Alle API-Aufrufe laufen über das Gateway.
|
||||
## Services
|
||||
|
||||
## Produktion (hinter Nginx)
|
||||
- Web App: http://meldestelle.yourdomain.com
|
||||
- API Gateway: http://api.meldestelle.yourdomain.com
|
||||
- Health: http://api.meldestelle.yourdomain.com/actuator/health
|
||||
- VNC (optional): http://vnc.meldestelle.yourdomain.com
|
||||
- Ping Service: http://localhost:8082
|
||||
- Members Service: http://localhost:8083
|
||||
- Horses Service: http://localhost:8084
|
||||
- Events Service: http://localhost:8085
|
||||
- Masterdata Service: http://localhost:8086
|
||||
|
||||
Optional HTTPS: gleiche Hosts mit https://, sobald Zertifikate aktiv sind.
|
||||
## Monitoring
|
||||
|
||||
- Prometheus: http://localhost:9090
|
||||
- Grafana: http://localhost:3000
|
||||
|
||||
## Clients
|
||||
|
||||
- Web App: http://localhost:4000
|
||||
- Desktop App (VNC): localhost:5901
|
||||
- Desktop App (noVNC): http://localhost:6080
|
||||
|
||||
## Hinweise
|
||||
|
||||
- Die oben genannten Ports sind in `docker/versions.toml` unter `[service-ports]` zentral gepflegt und werden für Docker
|
||||
Compose-Generierung und Validierung verwendet.
|
||||
- Bei Port-Konflikten können die Werte in `docker/versions.toml` angepasst und anschließend die Compose-Dateien mit
|
||||
`bash scripts/generate-compose-files.sh all development` neu generiert werden.
|
||||
|
||||
Reference in New Issue
Block a user