diff --git a/.github/workflows/auto_request_review.yml b/.github/workflows/auto_request_review.yml index 64883a53aa7..2b9e53f9705 100644 --- a/.github/workflows/auto_request_review.yml +++ b/.github/workflows/auto_request_review.yml @@ -15,7 +15,7 @@ jobs: runs-on: [ ubuntu-latest ] steps: - name: Request Android Devs for review - uses: necojackarc/auto-request-review@v0.13.0 + uses: necojackarc/auto-request-review@v0.14.0 with: token: ${{ secrets.SERVICES_ACCESS_TOKEN }} config: .github/reviewers.yml diff --git a/CHANGELOG.md b/CHANGELOG.md index e35bfc88924..86ef0a8d53d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,22 @@ ### Internal +- Bump Sentry to v8.57.0 +- Bump Sentry Android to v6.22.0 +- Bump AndroidX Room to v2.8.5 +- Bump KSP to v2.3.12 +- Bump Kotlin to v2.4.20 +- Bump AndroidX Benchmark to v1.5.0 +- Bump Compose BOM to v2026.09.00 +- Bump sqlCipher to v4.19.0 +- Bump necojackarc auto request review to v0.14.0 +- Enabled R8 obfuscation for production builds to improve application code protection. +- Preserved generated Room DAO class names to maintain SQL performance monitoring functionality. + +## 2026.09.18 + +### Internal + - Bump AGP to v9.4.0 - Bump Lint to v32.4.0 diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index 4eaaa5c6416..7ee71d1f5c7 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -1,8 +1,8 @@ -# No obfuscation because open source -# We depend on the convention of generated DAO names by Room in order to support performance profiling. -# If you decide to obfuscate the final APK, please verify the performance profiling tool continues to function. +# We obfuscate the final APK while keeping generated Room DAO names unchanged. +# We depend on the convention of generated DAO names by Room to support performance profiling. +# If you modify this rule, please verify that the performance profiling tool continues to function. # See: https://github.com/simpledotorg/simple-android/issues/2470 --dontobfuscate +-keepnames class **_RoomDao_Impl # We process generated Room DAO metadata and use a runtime exception for performance profiling. # If you remove this, please ensure that the profiling does not break. @@ -46,6 +46,12 @@ ; } +# SyncProgress is serialized by Moshi's reflective EnumJsonAdapter. +# Keep enum field names unchanged so Moshi can resolve them by reflection. +-keepclassmembers enum org.simple.clinic.sync.SyncProgress { + ; +} + # The name of @JsonClass types is used to look up the generated adapter. -keepnames @com.squareup.moshi.JsonClass class * diff --git a/app/src/main/java/org/simple/clinic/scheduleappointment/ScheduleAppointmentEffectHandler.kt b/app/src/main/java/org/simple/clinic/scheduleappointment/ScheduleAppointmentEffectHandler.kt index 64bcc107dcc..38957d096f8 100644 --- a/app/src/main/java/org/simple/clinic/scheduleappointment/ScheduleAppointmentEffectHandler.kt +++ b/app/src/main/java/org/simple/clinic/scheduleappointment/ScheduleAppointmentEffectHandler.kt @@ -125,10 +125,17 @@ class ScheduleAppointmentEffectHandler @AssistedInject constructor( return ObservableTransformer { effects -> effects .observeOn(schedulers.io()) - .map { patientRepository.patientImmediate(it.patientUuid) } - .map { - val assignedFacility = getAssignedFacility(it).toNullable() - AppointmentFacilitiesLoaded(assignedFacility, currentFacility.get()) + .map { effect -> + val patient = patientRepository.patientImmediate(effect.patientUuid) + + val assignedFacility = patient + ?.let(::getAssignedFacility) + ?.toNullable() + + AppointmentFacilitiesLoaded( + assignedFacility = assignedFacility, + currentFacility = currentFacility.get() + ) } } } diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2cbd5af4fcf..a84c70548b4 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -4,7 +4,7 @@ agp = "9.4.0" androidx-cameraView = "1.6.2" androidx-camera = "1.6.2" androidx-paging = "3.5.1" -androidx-room = "2.8.4" +androidx-room = "2.8.5" androidx-work = "2.11.2" androidx-security-crypto = "1.1.0" androidx-viewmodel = "2.11.0" @@ -14,10 +14,10 @@ androidx-activity = "1.13.0" chucker = "4.3.0" dagger = "2.60.1" -kotlin = "2.4.10" +kotlin = "2.4.20" kotlinx-serialization = "1.11.0" -ksp = "2.3.11" +ksp = "2.3.12" ktlint = "0.36.0" @@ -39,11 +39,11 @@ coroutines = "1.11.0" compose-compiler = "1.5.13" -androidx-compose-bom = "2026.08.00" +androidx-compose-bom = "2026.09.00" composeThemeAdapter = "0.36.0" -sqlCipher = "4.18.0" +sqlCipher = "4.19.0" [libraries] android-desugaring = "com.android.tools:desugar_jdk_libs:2.1.5" @@ -180,7 +180,7 @@ rx-java = "io.reactivex.rxjava2:rxjava:2.2.21" rx-kotlin = "io.reactivex.rxjava2:rxkotlin:2.4.0" rx-preferences = "com.f2prateek.rx.preferences2:rx-preferences:2.0.1" -sentry-android = "io.sentry:sentry-android:8.54.0" +sentry-android = "io.sentry:sentry-android:8.57.0" signaturepad = "com.github.gcacace:signature-pad:1.4.0" @@ -224,13 +224,13 @@ sqlCipher = { module = "net.zetetic:sqlcipher-android", version.ref = "sqlCipher android-application = { id = "com.android.application", version.ref = "agp" } android-library = { id = "com.android.library", version.ref = "agp" } android-lint = { id = "com.android.lint", version.ref = "agp" } -androidx-benchmark = { id = "androidx.benchmark", version = "1.5.0-rc02" } +androidx-benchmark = { id = "androidx.benchmark", version = "1.5.0" } kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlin" } kotlin-compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } ksp = { id = "com.google.devtools.ksp", version.ref = "ksp" } google-services = { id = "com.google.gms.google-services", version = "4.5.0" } -sentry = { id = "io.sentry.android.gradle", version = "6.20.0" } +sentry = { id = "io.sentry.android.gradle", version = "6.22.0" } [bundles] androidx-camera = ["androidx-camera-core", "androidx-camera-camera2", "androidx-camera-view", "androidx-camera-lifecycle"]