diff --git a/android/PLAN.md b/android/PLAN.md index c7537d8..6a37123 100644 --- a/android/PLAN.md +++ b/android/PLAN.md @@ -995,6 +995,29 @@ repos use), on a bare `ubuntu:latest` container. signing identity stable from the first release (Play later requires consistency). - Semantic `versionName` + monotonic `versionCode`; tag releases. +### 12.1 Code quality — SonarQube (`Runic-Gateway-Android-app`) + +Analysis runs post-merge and non-blocking (`.gitea/workflows/sonarqube.yml`); the gate is +informational. The project is clean (0 bugs / 0 vulns / 0 hotspots, Maintainability **A**); the only +gate failure is **coverage = 0% on new code**, which is a *reporting* gap, not a testing gap — the +25-file JVM unit suite exists, but the source-only Sonar scan never received a JaCoCo report. + +**Coverage wiring (the fix):** +- Apply the `jacoco` plugin in `app/build.gradle.kts` + a `jacocoTestReport` task fed by + `testDebugUnitTest`, emitting XML. Exclude generated/DI/Compose scaffolding + (`**/*_Hilt*`, `**/*_Factory*`, `**/di/**`, `**/*ComposableSingletons*`, `R`/`BuildConfig`). +- `sonar-project.properties`: set `sonar.coverage.jacoco.xmlReportPaths` to the report, and + `sonar.coverage.exclusions` for pure-`@Composable` UI (JVM unit tests can't execute composable + bodies without Robolectric, so counting those lines would unfairly sink new-code coverage). +- `sonarqube.yml` must now run a real Gradle build before the scan (JDK 17 + Android SDK, mirroring + `pr-checks.yml`): `./gradlew testDebugUnitTest jacocoTestReport` → then the scan step. + +**Issue triage (2026-07-22):** of 15 code smells, **3 fixed in code** — remove an unused import +(`AdminContentScreen.kt`), remove an unused `page` param (`AdminSupportScreen.RespondDialog`), and +decompose `LoginViewModel` (cognitive complexity 20). The remaining **12 marked *Won't Fix*** via the +Sonar API with rationale: 5 snake_case DTO fields (intentionally mirror the JSON wire contract) and 7 +Compose/nav cognitive-complexity + hoisted-callback param-count smells (idiomatic for Jetpack Compose). + ## 13. Open questions (revisit as we go) **Decided (recorded here for context):** single shard per install (§3); native auth is