Some checks failed
Build and Publish Docker Images / build-and-push (., backend/infrastructure/gateway/Dockerfile, api-gateway, api-gateway) (push) Failing after 2m56s
Build and Publish Docker Images / build-and-push (., backend/services/ping/Dockerfile, ping-service, ping-service) (push) Failing after 3m3s
Build and Publish Docker Images / build-and-push (., config/docker/caddy/web-app/Dockerfile, web-app, web-app) (push) Failing after 2m49s
Build and Publish Docker Images / build-and-push (., config/docker/keycloak/Dockerfile, keycloak, keycloak) (push) Successful in 2m13s
- Deleted unused screens including `AdminUebersichtScreen`, `AktorScreens`, `StammdatenImportScreen`, `TurnierDetailScreen`, and supporting components such as `PlaceholderContent`. - Cleaned up references and placeholders to streamline module structure. Signed-off-by: Stefan Mogeritsch <stefan.mo.co@gmail.com>
164 lines
5.9 KiB
Markdown
164 lines
5.9 KiB
Markdown
# Frontend-Architektur-Richtlinien
|
|
|
|
> **Status:** Verbindlich ab 26.03.2026
|
|
> **Zuständig:** 🏗️ Lead Architect
|
|
> **Zweck:** Verhindert Architektur-Drift und inkonsistente Schichtentrennung.
|
|
|
|
---
|
|
|
|
## Die 3 Schichten
|
|
|
|
```
|
|
frontend/
|
|
├── core/ ← Infrastruktur (plattformübergreifend, kein Business-Code)
|
|
├── features/ ← Fachliche Bausteine (je ein Bounded Context)
|
|
└── shells/ ← Ausführbare Apps (nur Verdrahtung, kein Fach-UI)
|
|
```
|
|
|
|
---
|
|
|
|
## Schicht 1: `core/`
|
|
|
|
### Aufgabe
|
|
|
|
Gemeinsame Infrastruktur, die von **allen** Features und Shells genutzt wird.
|
|
|
|
### Module
|
|
|
|
| Modul | Inhalt |
|
|
|-----------------|-----------------------------------------------------------------|
|
|
| `auth` | Login, Token-Management, OIDC/PKCE, `LoginScreen` |
|
|
| `design-system` | Farben, Typografie, gemeinsame UI-Komponenten, `SharedUiModels` |
|
|
| `domain` | Gemeinsame Domain-Modelle (plattformübergreifend) |
|
|
| `navigation` | `AppScreen`-Sealed-Class (einzige Wahrheit über alle Routen) |
|
|
| `network` | Ktor-Client, `NetworkConfig` |
|
|
| `local-db` | SQLDelight/Room-Setup, `DatabaseProvider` |
|
|
| `sync` | Offline-Sync-Infrastruktur |
|
|
|
|
### Regeln
|
|
|
|
- ✅ Darf importieren: externe Libraries, andere `core`-Module (keine Zyklen)
|
|
- ❌ Darf NICHT importieren: `features/*`, `shells/*`
|
|
- ❌ Kein Business-Code, keine fachlichen Screens
|
|
|
|
---
|
|
|
|
## Schicht 2: `features/`
|
|
|
|
### Aufgabe
|
|
|
|
Jedes Feature kapselt **einen Bounded Context** vollständig: Daten, Logik und UI.
|
|
|
|
### Pflicht-Struktur eines Feature-Moduls
|
|
|
|
```
|
|
features/<name>-feature/
|
|
└── src/
|
|
└── jvmMain/kotlin/at/mocode/<name>/feature/
|
|
├── data/ ← Repository, API-Client
|
|
├── domain/ ← Modelle, Use Cases
|
|
├── presentation/ ← ViewModel + Screen-Composables ← PFLICHT
|
|
└── di/ ← Koin-Module
|
|
```
|
|
|
|
### Vorhandene Features
|
|
|
|
| Feature | Bounded Context |
|
|
|-------------------------|-----------------------------------------------|
|
|
| `ping-feature` | Verbindungstest / Sync-Status |
|
|
| `nennung-feature` | Nennungs-Erfassung am Turnier |
|
|
| `zns-import-feature` | ZNS-Stammdaten-Import |
|
|
| `veranstalter-feature` | Veranstalter-Auswahl, -Detail, -Neuanlage |
|
|
| `veranstaltung-feature` | Veranstaltungs-Übersicht, -Detail, -Neuanlage |
|
|
| `turnier-feature` | Turnier-Detail, alle Tabs, Akteure |
|
|
|
|
### Regeln
|
|
|
|
- ✅ Darf importieren: `core/*`
|
|
- ❌ Darf NICHT importieren: andere `features/*`, `shells/*`
|
|
- ✅ **Jedes Feature MUSS seinen eigenen Screen in `presentation/` haben**
|
|
- ❌ Screen-Composables gehören NICHT in den Shell
|
|
|
|
---
|
|
|
|
## Schicht 3: `shells/`
|
|
|
|
### Aufgabe
|
|
|
|
Einstiegspunkt einer konkreten App. Verdrahtet Features und Core zu einer lauffähigen Anwendung.
|
|
|
|
### Erlaubter Inhalt im Shell
|
|
|
|
```
|
|
shells/<name>/
|
|
└── src/jvmMain/kotlin/at/mocode/desktop/
|
|
├── main.kt ← App-Einstiegspunkt, Koin-Init
|
|
├── DesktopApp.kt ← Root-Composable, Login-Gate
|
|
├── di/DesktopModule.kt ← Shell-spezifische DI
|
|
├── navigation/ ← Navigation-Port (optional)
|
|
└── screens/
|
|
├── layout/DesktopMainLayout.kt ← Navigation + Layout-Gerüst
|
|
└── preview/ScreenPreviews.kt ← @Preview-Funktionen (IDE-only)
|
|
```
|
|
|
|
### Regeln
|
|
|
|
- ✅ Darf importieren: `core/*`, `features/*`
|
|
- ✅ Darf enthalten: `main.kt`, `DesktopApp.kt`, DI-Verdrahtung, Layout, Previews
|
|
- ❌ Darf NICHT enthalten: fachliche Screen-Composables (gehören in Features)
|
|
- ❌ Darf NICHT enthalten: ViewModels, Repositories, Business-Logik
|
|
|
|
---
|
|
|
|
## Abhängigkeits-Diagramm
|
|
|
|
```
|
|
shells/meldestelle-desktop
|
|
├── core/auth
|
|
├── core/design-system
|
|
├── core/domain
|
|
├── core/navigation
|
|
├── core/network
|
|
├── core/local-db
|
|
├── core/sync
|
|
├── features/ping-feature
|
|
├── features/nennung-feature
|
|
├── features/zns-import-feature
|
|
├── features/veranstalter-feature
|
|
├── features/veranstaltung-feature
|
|
└── features/turnier-feature
|
|
|
|
features/* → core/* (nur)
|
|
core/* → (keine internen Abhängigkeiten außer erlaubte core-zu-core)
|
|
```
|
|
|
|
---
|
|
|
|
## Checkliste: Neues Feature anlegen
|
|
|
|
1. `frontend/features/<name>-feature/` Verzeichnis anlegen
|
|
2. `build.gradle.kts` nach Vorlage `nennung-feature` erstellen
|
|
3. Eintrag in `settings.gradle.kts` unter `// --- FEATURES ---` hinzufügen
|
|
4. Eintrag in `shells/meldestelle-desktop/build.gradle.kts` unter `// Feature-Module` hinzufügen
|
|
5. Screen in `presentation/` implementieren
|
|
6. DI-Modul in `di/` implementieren
|
|
7. DI-Modul in `shells/.../main.kt` registrieren
|
|
8. Route in `core/navigation/AppScreen.kt` eintragen
|
|
9. Navigation-Case in `shells/.../screens/layout/DesktopMainLayout.kt` eintragen
|
|
|
|
---
|
|
|
|
## Anti-Patterns (verboten)
|
|
|
|
| Anti-Pattern | Warum verboten |
|
|
|------------------------------------|------------------------------------------------------|
|
|
| Screen-Composable direkt im Shell | Verletzt Schichttrennung, nicht wiederverwendbar |
|
|
| Feature importiert anderes Feature | Erzeugt Kopplung, verhindert unabhängige Entwicklung |
|
|
| `core` importiert `features` | Zirkuläre Abhängigkeit |
|
|
| Shared-Modelle im Shell definieren | Gehören in `core/design-system` oder `core/domain` |
|
|
| ViewModel im Shell | Gehört ins Feature |
|
|
|
|
---
|
|
|
|
*Letzte Aktualisierung: 26.03.2026 — nach Architektur-Refactor (Screens aus Shell in Features verschoben)*
|