meldestelle/docs/06_Frontend/ARCHITECTURE_RULES.md
Stefan Mogeritsch c2b3b5889f
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
chore: remove obsolete screens from meldestelle-desktop module
- 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>
2026-03-26 15:09:44 +01:00

5.9 KiB

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)