### feat: optimiere Architektur und verbessere E-Mail-Handling

- **ArchTests:** Passe Slices-Matching für `FrontendArchitectureTest` an Package-Struktur an.
- **Mail-Service:** Füge Plan-B-Benachrichtigung für Nennungen an Meldestelle hinzu; entferne Plus-Addressing (Fallback).
- **Build:** Deaktiviere Desktop-Build standardmäßig (`enableDesktop=false`) und mache Module-Registrierung optional.
This commit is contained in:
Stefan Mogeritsch 2026-04-22 16:01:49 +02:00
parent 5baa971b46
commit 255343145d
5 changed files with 44 additions and 22 deletions

View File

@ -71,19 +71,43 @@ class MailController(
nennungRepository.save(entity) nennungRepository.save(entity)
logger.info("Nennung ${entity.id} in Datenbank persistiert.") logger.info("Nennung ${entity.id} in Datenbank persistiert.")
// Bestätigung an Reiter senden // --- PLAN B: Benachrichtigung an die Meldestelle (online-nennen@mo-code.at) senden ---
try {
val notification = SimpleMailMessage()
notification.from = baseMailAddress // Mailserver erfordert oft, dass From == Username ist
notification.setTo(baseMailAddress) // Wir senden es an uns selbst
// WICHTIG: Die Turniernummer im Betreff für das einfache Mail-Filtering!
notification.subject = "[NENNUNG] Turnier ${request.turnierNr} - ${request.vorname} ${request.nachname}"
val textBody = buildString {
appendLine("Neue Online-Nennung eingegangen!")
appendLine("----------------------------------")
appendLine("Turnier: ${request.turnierNr}")
appendLine("Reiter: ${request.vorname} ${request.nachname}")
appendLine("Lizenz: ${request.lizenz}")
appendLine("Pferd: ${request.pferdName} (Alter: ${request.pferdAlter})")
appendLine("E-Mail: ${request.email}")
appendLine("Telefon: ${request.telefon ?: "-"}")
appendLine("Bewerbe: ${request.bewerbe}")
appendLine("Bemerkungen: ${request.bemerkungen ?: "-"}")
appendLine("----------------------------------")
appendLine("System-ID: ${entity.id}")
}
notification.text = textBody
mailSender.send(notification)
logger.info("Plan-B Nennungs-Mail an die Meldestelle gesendet. Betreff: ${notification.subject}")
} catch (e: Exception) {
logger.error("Fehler beim Senden der Plan-B Nennungs-Mail an die Meldestelle: ${e.message}")
}
// --- Ursprüngliche Bestätigung an den Reiter (optional, bleibt vorerst erhalten) ---
try { try {
val message = SimpleMailMessage() val message = SimpleMailMessage()
// Dynamische Absenderadresse mit Plus-Addressing (z.B. online-nennen+26128@mo-code.at) // PLAN B Fallback: Kein Plus-Addressing, da World4You es nicht unterstützt
val dynamicFrom = try { // Wir verwenden als Absender einfach die Basis-Adresse
val (user, domain) = baseMailAddress.split("@") message.from = baseMailAddress
"$user+${request.turnierNr}@$domain"
} catch (_: Exception) {
baseMailAddress
}
message.from = dynamicFrom
message.setTo(request.email) message.setTo(request.email)
message.subject = "Bestätigung: Ihre Online-Nennung für Turnier ${request.turnierNr}" message.subject = "Bestätigung: Ihre Online-Nennung für Turnier ${request.turnierNr}"
message.text = """ message.text = """
@ -133,14 +157,8 @@ class MailController(
@RequestParam nachname: String @RequestParam nachname: String
) { ) {
val message = SimpleMailMessage() val message = SimpleMailMessage()
val dynamicFrom = try { // PLAN B Fallback: Kein Plus-Addressing
val (user, domain) = baseMailAddress.split("@") message.from = baseMailAddress
"$user+$turnierNr@$domain"
} catch (_: Exception) {
baseMailAddress
}
message.from = dynamicFrom
message.setTo(email) message.setTo(email)
message.subject = "Bestätigung: Nennung für Turnier $turnierNr manuell übernommen" message.subject = "Bestätigung: Nennung für Turnier $turnierNr manuell übernommen"
message.text = """ message.text = """

View File

@ -74,6 +74,7 @@ dev.port.offset=0
# Setze enableWasm=true, um die Web-App zu bauen oder Web-spezifische # Setze enableWasm=true, um die Web-App zu bauen oder Web-spezifische
# Module zu testen. Default=false spart massiv Zeit beim Desktop-Build. # Module zu testen. Default=false spart massiv Zeit beim Desktop-Build.
enableWasm=true enableWasm=true
enableDesktop=false
# Dokka Gradle plugin V2 mode (with helpers for V1 compatibility) # Dokka Gradle plugin V2 mode (with helpers for V1 compatibility)
# See https://kotl.in/dokka-gradle-migration # See https://kotl.in/dokka-gradle-migration

View File

@ -38,6 +38,6 @@ dependencies {
implementation(projects.frontend.core.localDb) implementation(projects.frontend.core.localDb)
implementation(projects.frontend.core.sync) implementation(projects.frontend.core.sync)
implementation(projects.frontend.shells.meldestelleDesktop) // implementation(projects.frontend.shells.meldestelleDesktop) // Temporarily disabled while desktop build is disabled
// implementation(projects.frontend.shells.meldestelleWeb) // WASM-only modules cannot be tested with ArchUnit (JVM-only) // implementation(projects.frontend.shells.meldestelleWeb) // WASM-only modules cannot be tested with ArchUnit (JVM-only)
} }

View File

@ -11,9 +11,9 @@ class FrontendArchitectureTest {
@ArchTest @ArchTest
fun `feature modules should not depend on each other`(importedClasses: JavaClasses) { fun `feature modules should not depend on each other`(importedClasses: JavaClasses) {
// The pattern must match the actual package structure, e.g., 'at.mocode.ping.feature' // The pattern must match the actual package structure, e.g., 'at.mocode.frontend.features.(*)..'
slices() slices()
.matching("at.mocode.(*).feature..") .matching("at.mocode.frontend.features.(*)..")
.should().notDependOnEachOther() .should().notDependOnEachOther()
.check(importedClasses) .check(importedClasses)
} }

View File

@ -160,7 +160,10 @@ include(":frontend:features:billing-feature")
include(":frontend:features:device-initialization") include(":frontend:features:device-initialization")
// --- SHELLS --- // --- SHELLS ---
include(":frontend:shells:meldestelle-desktop") val enableDesktop = providers.gradleProperty("enableDesktop").getOrElse("true").toBoolean()
if (enableDesktop) {
include(":frontend:shells:meldestelle-desktop")
}
include(":frontend:shells:meldestelle-web") include(":frontend:shells:meldestelle-web")
// ========================================================================== // ==========================================================================