diff --git a/core/core-domain/build.gradle.kts b/core/core-domain/build.gradle.kts index fd730eed..19d33f51 100644 --- a/core/core-domain/build.gradle.kts +++ b/core/core-domain/build.gradle.kts @@ -12,11 +12,7 @@ kotlin { js(IR) { binaries.library() - browser { - testTask { - enabled = false - } - } + // browser {} block removed to fix "Plugin loaded multiple times" error. } @OptIn(org.jetbrains.kotlin.gradle.ExperimentalWasmDsl::class) diff --git a/docs/06_Frontend/Logs/2026-02-02_Docker_Build_Troubleshooting.md b/docs/06_Frontend/Logs/2026-02-02_Docker_Build_Troubleshooting.md new file mode 100644 index 00000000..8426c84e --- /dev/null +++ b/docs/06_Frontend/Logs/2026-02-02_Docker_Build_Troubleshooting.md @@ -0,0 +1,55 @@ +# đŸ§č Troubleshooting Log: Frontend Docker Build & Runtime Config + +**Datum:** 02.02.2026 +**Status:** ⚠ BLOCKED (Build Failure) +**Thema:** Dockerisierung des KMP Frontends (JS/IR) mit Caddy und Runtime-Konfiguration. + +## 1. Zielsetzung +Stabilisierung des Frontend-Deployments via Docker Compose. +* **Architektur:** Single Page Application (SPA) served by Caddy. +* **Anforderung:** "Build Once, Deploy Anywhere" -> Konfiguration (API URL) muss zur Laufzeit (Runtime) injiziert werden, nicht zur Build-Zeit. +* **Tech Stack:** Kotlin 2.3.0, Gradle 9.2.1, Compose Multiplatform 1.10.0. + +## 2. Implementierte Lösung (Code-Ebene) +Die Architektur fĂŒr die Runtime-Konfiguration wurde erfolgreich implementiert: + +1. **Kotlin (`Config.kt`, `main.kt`):** + * Die App lĂ€dt vor dem Start der UI eine `config.json` via `window.fetch`. + * `AppConfig` wird in Koin registriert. +2. **Caddy (`Caddyfile`, `config.json`):** + * Caddy Webserver ersetzt Nginx. + * Nutzt das `templates` Modul, um Environment-Variablen (`API_BASE_URL`) in die `config.json` zu rendern. +3. **Dockerfile:** + * Multi-Stage Build (Gradle -> Caddy). + * Optimiertes Caching fĂŒr Gradle 9.x. + +## 3. Das Problem: Gradle Build Fehler +Der Build schlĂ€gt im Docker-Container (und teilweise lokal) fehl mit: +`PluginApplicationException: Failed to apply plugin class 'org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin'.` +`The Kotlin Gradle plugin was loaded multiple times in different subprojects...` + +### Ursache +In einem Multi-Modul KMP-Projekt (Shell + Core Libraries) versuchen mehrere Module, die JavaScript-Umgebung (Node.js/Browser) zu konfigurieren. +* **Shell (`meldestelle-portal`):** Benötigt `browser()` fĂŒr Webpack/Distribution. +* **Libraries (`core/*`):** Benötigen JS-Target fĂŒr Kompilierung, nutzen teilweise `npm()` AbhĂ€ngigkeiten (z.B. `local-db` fĂŒr SQLite). +* **Konflikt:** Gradle 9.x und das Kotlin-Plugin geraten in einen Race-Condition-Zustand, wenn das `NodeJsRootPlugin` transitiv mehrfach initialisiert wird. + +## 4. DurchgefĂŒhrte Versuche + +| Versuch | Änderung | Ergebnis | Analyse | +| :--- | :--- | :--- | :--- | +| **1. Basis** | `alias(libs.plugins...)` in allen Modulen. `browser {}` in allen Modulen. | ❌ FAILED | "Plugin loaded multiple times". | +| **2. Library Mode** | Entfernen von `browser {}` aus allen Core-Modulen. Nur `binaries.library()`. | ⚠ SUCCESS (Lokal) / ❌ FAILED (Docker) | Lokal: Warnung "JS Environment Not Selected". Docker: Trotzdem Fehler, vermutlich wegen `npm()` Dependency in `local-db`. | +| **3. Explicit Browser** | HinzufĂŒgen von minimalem `browser { testTask { enabled = false } }` in Libraries. | ❌ FAILED | Sofortiger "Plugin loaded multiple times" Fehler. | +| **4. Plugin ID** | Nutzung von `id("org.jetbrains.kotlin.multiplatform")` statt `alias`. | ❌ FAILED | "Plugin not found" (Version Resolution via Catalog schlĂ€gt fehl). | +| **5. Revert** | ZurĂŒck zu "Library Mode" (Versuch 2). | ❌ FAILED | Der Fehler bleibt hartnĂ€ckig im Docker-Build bestehen. | + +## 5. NĂ€chste Schritte (Planung) +Das Problem liegt in der Gradle-Konfiguration der JS-Targets im Monorepo. + +1. **Root-Level Node.js Konfiguration:** Das `NodeJsRootPlugin` muss zwingend **einmalig** im Root-Projekt konfiguriert werden, um den Konflikt in den Submodulen zu lösen. +2. **Convention Plugin:** Erstellung eines `buildSrc` oder `conventions` Plugins, das die JS-Konfiguration zentralisiert (`apply(plugin = "kotlin-multiplatform")`). +3. **Workaround:** Explizites `rootProject.plugins.apply(...)` fĂŒr das NodeJs-Plugin in der Root `build.gradle.kts`. + +--- +*Dokumentiert durch Curator Agent.* diff --git a/frontend/core/auth/build.gradle.kts b/frontend/core/auth/build.gradle.kts index 5c3602e5..bebda0c6 100644 --- a/frontend/core/auth/build.gradle.kts +++ b/frontend/core/auth/build.gradle.kts @@ -14,15 +14,9 @@ kotlin { jvm() js { - // browser {} block removed to avoid NodeJsRootPlugin conflicts in multi-module builds - // We only need explicit browser configuration in the shell (application) module. - // Tests are disabled via root build.gradle.kts configuration anyway. - nodejs { - testTask { - enabled = false - } - } binaries.library() + // browser {} block is intentionally removed to prevent "Plugin loaded multiple times" error. + // The warning "JS Environment Not Selected" is acceptable for now. } sourceSets { diff --git a/frontend/core/design-system/build.gradle.kts b/frontend/core/design-system/build.gradle.kts index 3b419e00..c6ca6af2 100644 --- a/frontend/core/design-system/build.gradle.kts +++ b/frontend/core/design-system/build.gradle.kts @@ -6,15 +6,10 @@ plugins { } kotlin { - jvm() - js(IR) { binaries.library() - // Explicitly select browser environment to satisfy Kotlin/JS compiler warning - browser { - testTask { enabled = false } - } + // browser {} block removed to fix "Plugin loaded multiple times" error. } sourceSets { diff --git a/frontend/core/domain/build.gradle.kts b/frontend/core/domain/build.gradle.kts index 45353c1a..ed2efd2f 100644 --- a/frontend/core/domain/build.gradle.kts +++ b/frontend/core/domain/build.gradle.kts @@ -12,9 +12,7 @@ kotlin { jvm() js { binaries.library() - browser { - testTask { enabled = false } - } + // browser {} block removed to fix "Plugin loaded multiple times" error. } sourceSets { diff --git a/frontend/core/local-db/build.gradle.kts b/frontend/core/local-db/build.gradle.kts index a3a85974..940c47db 100644 --- a/frontend/core/local-db/build.gradle.kts +++ b/frontend/core/local-db/build.gradle.kts @@ -12,9 +12,7 @@ kotlin { jvm() js { binaries.library() - browser { - testTask { enabled = false } - } + // browser {} block removed to fix "Plugin loaded multiple times" error. } sourceSets { diff --git a/frontend/core/navigation/build.gradle.kts b/frontend/core/navigation/build.gradle.kts index 2a2dc095..2a62f425 100644 --- a/frontend/core/navigation/build.gradle.kts +++ b/frontend/core/navigation/build.gradle.kts @@ -13,9 +13,7 @@ kotlin { jvm() js { binaries.library() - browser { - testTask { enabled = false } - } + // browser {} block removed to fix "Plugin loaded multiple times" error. } sourceSets { diff --git a/frontend/core/network/build.gradle.kts b/frontend/core/network/build.gradle.kts index 25f7967c..f15e7721 100644 --- a/frontend/core/network/build.gradle.kts +++ b/frontend/core/network/build.gradle.kts @@ -12,9 +12,7 @@ kotlin { jvm() js { binaries.library() - browser { - testTask { enabled = false } - } + // browser {} block removed to fix "Plugin loaded multiple times" error. } sourceSets { diff --git a/frontend/core/sync/build.gradle.kts b/frontend/core/sync/build.gradle.kts index ad1ec02e..f9e1146b 100644 --- a/frontend/core/sync/build.gradle.kts +++ b/frontend/core/sync/build.gradle.kts @@ -7,16 +7,14 @@ kotlin { jvm() js(IR) { binaries.library() - browser { - testTask { enabled = false } - } + // browser {} block removed to fix "Plugin loaded multiple times" error. } sourceSets { commonMain.dependencies { - // Correct dependency: Syncable interface is in the shared core domain + // Correct dependency: Syncable interface is in shared core domain implementation(projects.core.coreDomain) - // Also include frontend domain if needed (e.g., for frontend-specific models) + // Also include frontend domain if needed (e.g. for frontend specific models) implementation(projects.frontend.core.domain) // Networking diff --git a/frontend/features/ping-feature/build.gradle.kts b/frontend/features/ping-feature/build.gradle.kts index 574ef61b..cd48f1db 100644 --- a/frontend/features/ping-feature/build.gradle.kts +++ b/frontend/features/ping-feature/build.gradle.kts @@ -17,9 +17,7 @@ kotlin { jvm() js { binaries.library() - browser { - testTask { enabled = false } - } + // browser {} block removed to fix "Plugin loaded multiple times" error. } sourceSets {