Skip to content

chore: Update Project Dependencies to Latest Version#102

Draft
TheKalpeshPawar wants to merge 14 commits intoopenMF:devfrom
TheKalpeshPawar:version_update
Draft

chore: Update Project Dependencies to Latest Version#102
TheKalpeshPawar wants to merge 14 commits intoopenMF:devfrom
TheKalpeshPawar:version_update

Conversation

@TheKalpeshPawar
Copy link

@TheKalpeshPawar TheKalpeshPawar commented Jan 8, 2026

This pull request introduces significant updates to the project's build logic and multiplatform configuration, with a focus on improving consistency, modernizing plugin usage, and streamlining dependency management across platforms. The most important changes are the migration to the androidLibrary DSL for Android configuration in multiplatform modules, updates to plugin application conventions, and enhanced dependency handling for platform-specific source sets.

Multiplatform and Build Logic Modernization:

  • Migrated Android configuration in multiplatform modules to use the androidLibrary DSL block instead of the legacy android block, improving consistency and future-proofing build scripts in files like cmp-navigation/build.gradle.kts, cmp-shared/build.gradle.kts, core-base/common/build.gradle.kts, core-base/database/build.gradle.kts, and core-base/designsystem/build.gradle.kts. [1] [2] [3] [4] [5] [6] [7] [8] [9] [10]
  • Updated plugin application in convention plugins: replaced com.android.library with com.android.kotlin.multiplatform.library and adjusted lint configuration logic to match, ensuring correct plugin usage for multiplatform projects. [1] [2]
  • Refactored the multiplatform configuration logic to use androidLibrary within the configureKotlinMultiplatform function, explicitly setting compileSdk, minSdk, resource handling, and desugaring dependencies.

Dependency and Source Set Improvements:

  • Improved Room database dependencies for multiplatform: added platform-specific dependencies for androidMain, desktopMain, nativeMain, and nonJsCommonMain source sets, ensuring correct runtime and SQLite support across platforms.
  • Enhanced Firebase and analytics dependency management: switched from api to implementation, added BOM support, and clarified dependency requirements for different source sets in core-base/analytics/build.gradle.kts.

Build Configuration and Toolchain Updates:

  • Standardized build toolchain configuration by using the Gradle toolchain API for Java 17 and updating Kotlin JVM target configuration, replacing legacy compatibility settings. [1] [2]
  • Added BuildKonfig plugin and configuration to enable build-time constants for flavors and demo mode in analytics, supporting better environment-based logic in multiplatform code. [1] [2] [3]

Gradle Settings and Plugin Management:

  • Updated settings.gradle.kts to include explicit plugin management repositories and the latest Kotlin JVM plugin version, ensuring reliable plugin resolution and compatibility.

These changes collectively modernize the project structure, improve multiplatform support, and lay the groundwork for easier maintenance and future upgrades.

Summary by CodeRabbit

  • New Features

    • Contextual month navigation in the tasks calendar (hides prev/next arrows at year boundaries).
    • Improved connectivity provider for more reliable online/offline behavior.
  • Bug Fixes & Improvements

    • Broad dependency upgrades across UI, networking, and platform libraries for stability and performance.
    • Modernized build and multiplatform configuration to streamline releases.
    • Update/review checks now honor debug/demo configuration, reducing spurious prompts during testing.

✏️ Tip: You can customize this high-level summary in your review settings.

…ibrary` plugin

This commit refactors the build logic to adopt the `com.android.kotlin.multiplatform.library` plugin, replacing the deprecated `com.android.library` and `kotlin-android` plugins for Kotlin Multiplatform modules.

Key changes include:
*   Updating the Android Gradle Plugin to version `8.13.0` and Kotlin to `2.3.0`.
*   Replacing `android {}` blocks with the `androidLibrary {}` configuration within the `kotlin {}` block across all multiplatform modules.
*   Centralizing Android configuration (like `compileSdk`, `minSdk`, and desugaring) into the `KotlinMultiplatform.kt` convention.
*   Removing explicit `androidTarget()` calls, as this is now handled by the new plugin.
*   Adjusting lint plugin configuration to recognize the new library plugin type.
*   Cleaning up `settings.gradle.kts` and `build.gradle.kts` by simplifying repository declarations.
…ibrary` plugin

This commit refactors the build logic to adopt the `com.android.kotlin.multiplatform.library` plugin, replacing the deprecated `com.android.library` and `kotlin-android` plugins for Kotlin Multiplatform modules.

Key changes include:
*   Updating the Android Gradle Plugin to version `8.13.0` and Kotlin to `2.3.0`.
*   Replacing `android {}` blocks with the `androidLibrary {}` configuration within the `kotlin {}` block across all multiplatform modules.
*   Centralizing Android configuration (like `compileSdk`, `minSdk`, and desugaring) into the `KotlinMultiplatform.kt` convention.
*   Removing explicit `androidTarget()` calls, as this is now handled by the new plugin.
*   Adjusting lint plugin configuration to recognize the new library plugin type.
*   Cleaning up `settings.gradle.kts` and `build.gradle.kts` by simplifying repository declarations.
Integrates the BuildKonfig plugin to manage build-time configurations, replacing the Android `BuildConfig`. This allows for compile-time variations such as `FLAVOR` and `IS_DEMO_MODE`.

Key changes:
- Adds and configures `buildkonfig` in `analytics` and `platform` modules.
- Creates `KMPRoomConventionPlugin` to centralize Room dependency management for KMP.
- Updates dependencies including `firebase-bom`, `gitLive`, and `buildKonfig`.
- Replaces `BuildConfig.DEBUG` with `BuildKonfig.DEBUG` in `AppReviewManager` and `AppUpdateManager`.
- Adds `cmp-navigation` dependency to the `cmp-android` module.
…d enable Android resources

This commit addresses two distinct issues:

1.  It corrects a bug in `TasksUiState.kt` where the `defaultMonthIndex` was incorrectly calculated as 1-indexed minus one, leading to an off-by-one error. The calculation is now correctly set to use the month's number directly.
2.  It enables the `androidResources` feature in the Kotlin Multiplatform configuration to allow the use of Android-specific resources.
Fixes the month selection logic in the Tasks feature. The month index is now correctly handled as 1-based (1 for January, 12 for December) instead of 0-based.

This change also conditionally hides the "previous month" arrow when January is selected and the "next month" arrow when December is selected, preventing navigation beyond the 12-month range.
Fixes the month selection logic in the Tasks feature. The month index is now correctly handled as 1-based (1 for January, 12 for December) instead of 0-based.

This change also conditionally hides the "previous month" arrow when January is selected and the "next month" arrow when December is selected, preventing navigation beyond the 12-month range.
- Updated numerous project dependencies including Android Gradle Plugin (8.13.2), Compose (2025.12.01), Ktor (3.3.3), and various AndroidX, Kotlin, and CMP libraries.
- Added `pluginManagement` block to `build-logic/settings.gradle.kts`.
- Refactored `build-logic/convention` to use Java toolchains for JDK 17 configuration.
Updated several AndroidX, Compose, and third-party libraries across the project:
- Bumped `androidx.activity` to 1.12.2 and `androidx.core` to 1.17.0.
- Updated `androidx.compose` BOM to 2025.12.01 and associated libraries to 1.10.0.
- Upgraded `io.ktor` to 3.3.3 and `io.insert-koin` to 4.1.1.
- Updated testing infrastructure: `robolectric` to 4.16, `roborazzi` to 1.54.0, and `junit-jupiter` to 6.0.1.
- Bumped other dependencies including `coil` (3.3.0), `ktorfit` (2.7.1), `kermit` (2.0.8), and `kotlinx-serialization` (1.9.0).
- Bumped `okhttp` version to 5.3.2 in `libs.versions.toml`.
- Switched `Clock` and `Instant` references from `kotlinx.datetime` to `kotlin.time` across `TasksUiState.kt`, `EditTaskScreen.kt`, and `DateTimeFormatter.kt`.
- Cleaned up unused `kotlinx.datetime` imports.
@coderabbitai
Copy link

coderabbitai bot commented Jan 8, 2026

📝 Walkthrough

Walkthrough

Switches many modules from the legacy Android DSL to Kotlin Multiplatform's androidLibrary DSL, adopts Java toolchains for Java 17, updates the version catalog and plugin aliases, restructures Room/platform dependencies, integrates BuildKonfig, and applies several code fixes (month-indexing, datetime qualification, connectivity and analytics wiring).

Changes

Cohort / File(s) Summary
Root build & plugin management
build.gradle.kts, settings.gradle.kts, build-logic/settings.gradle.kts
Simplify repositories to google(), mavenCentral(), gradlePluginPortal(); add pluginManagement repos; register Kotlin JVM Gradle plugin; add many plugin aliases (most apply false).
Java toolchains
build-logic/convention/build.gradle.kts
Replace direct Java source/target 17 settings with Gradle Java toolchains (languageVersion = 17).
Kotlin Multiplatform convention changes
build-logic/convention/src/main/kotlin/* (KMPLibraryConventionPlugin.kt, KMPRoomConventionPlugin.kt, KotlinAndroid.kt, KotlinMultiplatform.kt)
Switch plugin identifiers toward Kotlin MPP library plugin, make configureKotlin() public, add androidLibrary target config (compileSdk/minSdk/desugaring), restructure Room dependencies to platform-specific adds, and adjust lint plugin detection.
Module Android → androidLibrary migrations
multiple build files under cmp-*/, core-*/**/build.gradle.kts, feature/*/build.gradle.kts (e.g., cmp-navigation/build.gradle.kts, core-base/*, core/*, feature/*)
Replace android { namespace = ... } with kotlin { androidLibrary { namespace = ... } } across many modules; add/adjust DSL imports; enable device/host test configs where present; move consumer proguard rules into optimization blocks.
Version catalog & dependency bumps
gradle/libs.versions.toml, cmp-android/dependencies/prodReleaseRuntimeClasspath.txt
Large-scale version upgrades across Kotlin, Compose/CMP, AndroidX, Firebase, Ktor, Koin, Coil, tooling; add buildKonfig and android-kotlin-multiplatform plugin entries and new library mappings (e.g., firebase-common-ktx).
BuildKonfig integration & usage
core-base/platform/build.gradle.kts, core-base/analytics/build.gradle.kts, core-base/platform/src/.../AppReviewManagerImpl.kt, .../AppUpdateManagerImpl.kt
Add buildkonfig plugin/blocks and fields (FLAVOR, IS_DEMO_MODE, DEBUG toggles); switch debug checks from BuildConfig.DEBUG to BuildKonfig.DEBUG.
Room dependency restructuring
build-logic/convention/src/main/kotlin/KMPRoomConventionPlugin.kt
Replace single androidx.room.ktx dependency with multiple platform-specific add("<sourceSet>Implementation", ...) entries (room runtime + sqlite bundled) for Android, desktop, native, and non-JS common.
New/modified Kotlin sources
core-base/analytics/src/androidMain/.../AnalyticsModule.kt, core/data/src/androidMain/.../ConnectivityProvider.android.kt
Add Koin analytics module wiring (AnalyticsHelper → StubAnalyticsHelper) and Android connectivity provider (actual val connectivityProvider) with autoStart(true).
Home feature: datetime & month-index fixes
feature/home/src/commonMain/.../EditTaskScreen.kt, TasksScreen.kt, TasksUiState.kt, TasksViewModel.kt, DateTimeFormatter.kt
Fully qualify datetime calls, rename/shift month field from selectedMonthIndex → selectedMonthNumber (1-based semantics), update month navigation/boundary and rendering logic.
Miscellaneous & formatting
cmp-shared/cmp_shared.podspec, assorted build files
Whitespace/formatting adjustments, some api→implementation dependency scope changes, minor import refinements.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~70 minutes

Possibly related PRs

Poem

🐰
I hopped through Gradle, nibbling old DSL thread,
Swapped namespaces, toolchains, and versions ahead.
BuildKonfig tucked flavors into pockets so neat,
Months now count proper — no off-by-one defeat!
Dependency carrots and repo clover to eat.

🚥 Pre-merge checks | ✅ 1 | ❌ 2
❌ Failed checks (1 warning, 1 inconclusive)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 61.54% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'chore: Update Project Dependencies to Latest Version' is partially related to the changeset but overly broad, as the PR encompasses extensive build logic refactoring, multiplatform configuration migration, and toolchain updates beyond just dependency version bumping. Consider a more specific title that reflects the primary modernization effort, such as 'chore: Migrate to androidLibrary DSL and add BuildKonfig for Kotlin Multiplatform' or 'refactor: Modernize build configuration with androidLibrary and multiplatform support'.
✅ Passed checks (1 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 15

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (18)
feature/home/build.gradle.kts (1)

1-20: Remove duplicate copyright headers.

The file contains two copyright headers—one dated 2026 (lines 1-9) and another dated 2025 (lines 12-20). This duplication likely occurred during a merge or rebase. Keep only one copyright header at the top of the file.

🧹 Proposed fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
-import com.android.build.api.dsl.androidLibrary
-
 /*
  * Copyright 2025 Mifos Initiative
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
+import com.android.build.api.dsl.androidLibrary
+
 plugins {
core/domain/build.gradle.kts (1)

1-20: Remove duplicate copyright headers.

The file contains two copyright headers—one dated 2026 (lines 1-9) and another dated 2025 (lines 12-20). Keep only one copyright header at the top of the file.

🧹 Proposed fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
-import com.android.build.api.dsl.androidLibrary
-
 /*
  * Copyright 2025 Mifos Initiative
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
+import com.android.build.api.dsl.androidLibrary
+
 plugins {
core/model/build.gradle.kts (1)

1-20: Remove duplicate copyright headers.

The file contains two copyright headers—one dated 2026 (lines 1-9) and another dated 2025 (lines 12-20). Keep only one copyright header at the top of the file.

🧹 Proposed fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
-import com.android.build.api.dsl.androidLibrary
-
 /*
  * Copyright 2025 Mifos Initiative
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
+import com.android.build.api.dsl.androidLibrary
+
 plugins {
feature/profile/build.gradle.kts (1)

1-20: Remove duplicate copyright headers.

The file contains two copyright headers—one dated 2026 (lines 1-9) and another dated 2025 (lines 12-20). Keep only one copyright header at the top of the file.

🧹 Proposed fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
-import com.android.build.api.dsl.androidLibrary
-
 /*
  * Copyright 2025 Mifos Initiative
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
+import com.android.build.api.dsl.androidLibrary
+
 plugins {
core-base/common/build.gradle.kts (1)

1-20: Remove duplicate copyright header.

The file contains two copyright headers—one at lines 1-9 (2026) and another at lines 12-20 (2025). Remove one of them to clean up the file.

🧹 Suggested fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
-import com.android.build.api.dsl.androidLibrary
-
 /*
  * Copyright 2025 Mifos Initiative
  *
@@ -18,6 +8,8 @@
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
+import com.android.build.api.dsl.androidLibrary
+
 plugins {
core/datastore/build.gradle.kts (1)

1-20: Remove duplicate copyright header.

Duplicate copyright headers exist (2026 at lines 1-9 and 2024 at lines 12-20). Keep only one.

🧹 Suggested fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
-import com.android.build.api.dsl.androidLibrary
-
 /*
  * Copyright 2024 Mifos Initiative
  *
@@ -18,6 +8,8 @@
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
+import com.android.build.api.dsl.androidLibrary
+
 plugins {
core-base/designsystem/build.gradle.kts (1)

1-20: Remove duplicate copyright header.

The file has two copyright headers (2026 at lines 1-9, 2025 at lines 12-20). Clean up by removing one.

🧹 Suggested fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
-import com.android.build.api.dsl.androidLibrary
-
 /*
  * Copyright 2025 Mifos Initiative
  *
@@ -18,6 +8,8 @@
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
+import com.android.build.api.dsl.androidLibrary
+
 plugins {
core/analytics/build.gradle.kts (1)

1-20: Remove duplicate copyright header.

Duplicate copyright headers present (2026 at lines 1-9, 2025 at lines 12-20). Remove one for consistency.

🧹 Suggested fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
-import com.android.build.api.dsl.androidLibrary
-
 /*
  * Copyright 2025 Mifos Initiative
  *
@@ -18,6 +8,8 @@
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
+import com.android.build.api.dsl.androidLibrary
+
 plugins {
core/common/build.gradle.kts (1)

1-22: Remove duplicate copyright headers.

Two copyright headers are present (2026 at lines 1-9 and 2025 at lines 14-22). This appears to be a merge artifact that should be cleaned up.

🧹 Proposed fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
-import com.android.build.api.dsl.androidLibrary
-import org.gradle.kotlin.dsl.commonMain
-import org.gradle.kotlin.dsl.dependencies
-
 /*
  * Copyright 2025 Mifos Initiative
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
+import com.android.build.api.dsl.androidLibrary
+import org.gradle.kotlin.dsl.commonMain
+import org.gradle.kotlin.dsl.dependencies
+
 plugins {
cmp-navigation/build.gradle.kts (1)

29-55: Remove duplicate datastore dependency.

Line 37 duplicates the dependency declaration from line 35: implementation(projects.core.datastore) appears twice in the commonMain.dependencies block.

🧹 Proposed fix
             implementation(projects.core.data)
             implementation(projects.core.model)
             implementation(projects.core.common)
             implementation(projects.core.datastore)
 
-            implementation(projects.core.datastore)
             implementation(projects.coreBase.common)
             implementation(projects.coreBase.platform)
core-base/ui/build.gradle.kts (1)

1-21: Remove duplicate license header.

The file contains two identical copyright headers. Remove the duplicate to improve file cleanliness.

🧹 Proposed fix
-/*
- * Copyright 2025 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
 import com.android.build.api.dsl.androidLibrary
 import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
 
 /*
  * Copyright 2025 Mifos Initiative
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
core-base/network/build.gradle.kts (1)

1-20: Remove duplicate license header and verify copyright year.

The file contains duplicate license headers with inconsistent copyright years (2026 vs 2025). Since this appears to be a 2025 project, the 2026 copyright is likely premature. Remove the duplicate and verify the correct year.

🧹 Proposed fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
 import com.android.build.api.dsl.androidLibrary
 
 /*
  * Copyright 2025 Mifos Initiative
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
feature/settings/build.gradle.kts (1)

1-20: Remove duplicate license header and verify copyright year.

The file contains duplicate license headers with inconsistent copyright years (2026 vs 2025). Since this appears to be a 2025 project, the 2026 copyright is likely premature. Remove the duplicate and verify the correct year.

🧹 Proposed fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
 import com.android.build.api.dsl.androidLibrary
 
 /*
  * Copyright 2025 Mifos Initiative
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
core/database/build.gradle.kts (1)

1-20: Remove duplicate license header and verify copyright year.

The file contains duplicate license headers with inconsistent copyright years (2026 vs 2025). Since this appears to be a 2025 project, the 2026 copyright is likely premature. Remove the duplicate and verify the correct year.

🧹 Proposed fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
 import com.android.build.api.dsl.androidLibrary
 
 /*
  * Copyright 2025 Mifos Initiative
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
core/network/build.gradle.kts (1)

1-20: Remove duplicate license headers.

The file contains two copyright headers—one dated 2026 (lines 1-9) and another dated 2025 (lines 12-20). Retain only one header at the top of the file.

🧹 Proposed fix to remove the duplicate
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
-import com.android.build.api.dsl.androidLibrary
-
 /*
  * Copyright 2025 Mifos Initiative
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
+import com.android.build.api.dsl.androidLibrary
+
 plugins {
core/data/build.gradle.kts (1)

1-20: Remove duplicate license headers.

Similar to other files, this contains two copyright headers (2026 and 2025). Retain only one at the top.

🧹 Proposed fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
-import com.android.build.api.dsl.androidLibrary
-
 /*
  * Copyright 2025 Mifos Initiative
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
+import com.android.build.api.dsl.androidLibrary
+
 plugins {
core/designsystem/build.gradle.kts (1)

1-20: Remove duplicate license headers.

This file also contains duplicate copyright headers (2026 and 2025). Keep only one.

🧹 Proposed fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
-import com.android.build.api.dsl.androidLibrary
-
 /*
  * Copyright 2025 Mifos Initiative
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
+import com.android.build.api.dsl.androidLibrary
+
 plugins {
core/ui/build.gradle.kts (1)

1-20: Duplicate copyright headers detected.

The file contains two copyright headers - one dated 2026 (lines 1-9) and another dated 2025 (lines 12-20). This appears to be an accidental duplication. Remove one of them.

Suggested fix
 /*
- * Copyright 2026 Mifos Initiative
+ * Copyright 2025 Mifos Initiative
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at https://mozilla.org/MPL/2.0/.
  *
  * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
  */
 import com.android.build.api.dsl.androidLibrary

-/*
- * Copyright 2025 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
 plugins {
🤖 Fix all issues with AI agents
In @build-logic/convention/build.gradle.kts:
- Line 11: Update the outdated comment that reads "Configure the build-logic
plugins to target JDK 19" so it matches the actual configuration (JDK 17);
locate the comment in build.gradle.kts (the line containing that phrase) and
change the text to reference JDK 17 instead of JDK 19.

In
@build-logic/convention/src/main/kotlin/org/convention/KotlinMultiplatform.kt:
- Around line 3-4: The file imports an internal AGP symbol
com.android.build.gradle.internal.ide.kmp.KotlinAndroidSourceSetMarker.Companion.android
which is unsafe and (per review) unused; remove that import and any references
to KotlinAndroidSourceSetMarker.android from KotlinMultiplatform.kt, and if you
need Android source-set wiring use the public DSL/API (e.g., androidLibrary or
the official Kotlin Multiplatform sourceSet accessors) instead of the internal
class; ensure the remaining imports (like androidLibrary) are kept only if
actually used.

In @build.gradle.kts:
- Around line 15-16: Remove the redundant buildscript classpath entry: delete
the classpath(libs.buildkonfig.gradle.plugin) line (and the surrounding
buildscript { ... } block if it becomes empty) because BuildKonfig is already
declared via the plugins block as alias(libs.plugins.codingfeline.buildKonfig)
apply false; ensure no other buildscript-only usages remain and that subprojects
rely on the plugins block instead.

In @core-base/analytics/build.gradle.kts:
- Line 12: Remove the incorrect and unused import
org.gradle.declarative.dsl.schema.FqName.Empty.packageName at the top of the
file; the buildkonfig block's packageName comes from the BuildKonfig DSL, so
delete that import and ensure no other references rely on it (inspect the
buildkonfig block and related BuildKonfig usages to confirm).
- Around line 87-103: Update the BuildKonfig default flavor string to match your
product flavors: in the buildkonfig block (symbol: buildkonfig) inside
defaultConfigs, change the buildConfigField call that sets FLAVOR from "dev" to
"demo" so it aligns with AppFlavor.kt; leave IS_DEMO_MODE as "true" and keep the
prod targetConfig unchanged.

In @core-base/platform/build.gradle.kts:
- Around line 74-84: The DEBUG buildConfigField is hardcoded to "true" for all
builds; change it to be build-type or variant-specific so release builds get
"false" — e.g., use buildkonfig.defaultConfigs("debug") {
buildConfigField(FieldSpec.Type.BOOLEAN, "DEBUG", "true", const = true) } and
defaultConfigs("release") { buildConfigField(FieldSpec.Type.BOOLEAN, "DEBUG",
"false", const = true) } or derive the value from the Gradle buildType (use
buildTypes.getByName("release") / "debug" to set the field) instead of the
current single defaultConfigs block that always sets DEBUG true; update the
buildkonfig block (reference: buildkonfig, defaultConfigs, buildConfigField,
FieldSpec.Type.BOOLEAN, "DEBUG") accordingly.

In @core/data/build.gradle.kts:
- Around line 53-55: The analytics Gradle sourceSet still uses mobileMain;
update the sourceSet block in core-base/analytics build script to use iosMain
instead of mobileMain so it matches other modules (replace the
mobileMain.dependencies reference with iosMain.dependencies and ensure the same
dependency entries are present); verify the iosMain block mirrors the pattern
used in core/data and core-base/common where
implementation(libs.connectivity.device) (or equivalent analytics dependencies)
are declared.

In
@core/data/src/androidMain/kotlin/org/mifos/core/data/util/ConnectivityProvider.android.kt:
- Line 12: Remove the incorrect import of android.R.attr.autoStart and change
the DSL call site that currently invokes autoStart(true) to use property
assignment autoStart = true (i.e., replace the function-style call with the
property assignment in the connectivity DSL/builder where autoStart is
configured).

In @core/database/build.gradle.kts:
- Line 25: Uncomment the Room convention plugin alias (mifos.kmp.room) and
restore the Room/KSP dependencies so the Room annotation processors run for this
module; specifically re-enable the plugin alias and re-add the Room runtime,
room-ktx, room-compiler/ksp and any KSP configuration referenced in this build
script so annotations on SampleEntity, SampleDao and AppDatabase are processed
locally by KSP rather than relying on transitive modules.

In @core/ui/build.gradle.kts:
- Around line 64-66: In the dependencies block replace the non-standard
configuration usage "androidRuntimeClasspath"(compose.uiTooling) with a
debug-only dependency by using debugImplementation(compose.uiTooling); locate
the dependencies { ... } block containing
"androidRuntimeClasspath"(compose.uiTooling) and change that single entry to
debugImplementation(compose.uiTooling) to ensure Compose UI tooling is only
included in debug builds.

In
@feature/home/src/commonMain/kotlin/org/mifos/feature/home/task/EditTaskScreen.kt:
- Line 304: The currentTime assignment uses kotlin.time.Clock.System.now(),
producing a kotlin.time.Instant incompatible with the toLocalDateTime extension
from kotlinx.datetime; replace the call with kotlinx.datetime.Clock.System.now()
(or remove the kotlin.time import and use kotlinx.datetime.Clock.System.now())
so that currentTime is a kotlinx.datetime.Instant compatible with
toLocalDateTime in EditTaskScreen (reference: currentTime variable and
toLocalDateTime usage).

In
@feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksScreen.kt:
- Around line 407-415: The UI currently does fragile string-based month checks
using selectedMonth.lowercase() != "january"; replace this with a numeric month
index in state (e.g., selectedMonthIndex: Int with range 1..12) and change
visibility checks to bounds checks (if selectedMonthIndex > 1 for previous arrow
and if selectedMonthIndex < 12 for next arrow). Update handlers
(onPreviousMonth/onNextMonth) to increment/decrement selectedMonthIndex with
proper clamping, and render the displayed month name by formatting the index
into a localized month string rather than relying on stored names; apply the
same changes to the other occurrence referenced (lines ~424-432) so all
month-bound logic uses selectedMonthIndex.

In
@feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksUiState.kt:
- Line 65: The selectedMonth getter accesses months[selectedMonthIndex - 1]
without bounds checking; add validation to prevent IndexOutOfBoundsException by
ensuring selectedMonthIndex is in 1..12. Fix options: add a
require(selectedMonthIndex in 1..12) check in the TasksUiState init block to
fail fast, or change the selectedMonth getter to safely clamp/return a default
when selectedMonthIndex is out of range (e.g., use safe index computation or a
guard that returns months.first()/months.last() or a null/placeholder). Update
references in TasksUiState (selectedMonth getter, selectedMonthIndex, months)
accordingly.
- Line 41: Replace the erroneous kotlin.time.Clock.System.now() call with
kotlinx.datetime.Clock.System.now() where currentMoment is defined (e.g., in
TasksUiState.kt and EditTaskScreen.kt usages) so the returned Instant matches
kotlinx.datetime extensions, and update the import to kotlinx.datetime.Clock;
also remove the unnecessary +1 adjustments wherever selectedMonthIndex is
consumed in TasksViewModel (stop adding 1 to selectedMonthIndex in the code
paths that currently do selectedMonthIndex + 1) so selectedMonthIndex remains
1..12 instead of becoming 2..13.
🧹 Nitpick comments (13)
core-base/analytics/src/androidMain/kotlin/template/core/base/analytics/di/AnalyticsModule.kt (2)

12-12: Consider removing unused import.

This Firebase import is only referenced in commented code. Unless Firebase integration is planned imminently, consider removing it to keep imports clean.

🧹 Cleanup suggestion
-import com.google.firebase.analytics.analytics
 import org.koin.core.module.Module
 import org.koin.dsl.module
 import template.core.base.analytics.AnalyticsHelper
 import template.core.base.analytics.StubAnalyticsHelper

18-30: Current stub implementation is correct; Firebase integration scaffolding incomplete.

The active code correctly binds AnalyticsHelper to StubAnalyticsHelper. The commented Firebase integration plan (lines 21-26, 29) is missing several imports that would be needed when uncommented:

  • BuildKonfig (for IS_DEMO_MODE check)
  • FirebaseAnalyticsHelper (the prod implementation)
  • Firebase (for Firebase.analytics)

Would you like me to generate the complete Firebase integration code with all necessary imports, or should this scaffolding be removed until Firebase integration is ready?

settings.gradle.kts (1)

4-11: Remove commented-out code.

The file contains multiple blocks of commented-out code (google() content filters at lines 4-10 and 20-26, and repositoriesMode at line 18). Commented code creates maintenance debt and can cause confusion about the intended configuration.

♻️ Proposed cleanup
 pluginManagement {
     includeBuild("build-logic")
     repositories {
-//        google {
-//            content {
-//                includeGroupByRegex("com\\.android.*")
-//                includeGroupByRegex("com\\.google.*")
-//                includeGroupByRegex("androidx.*")
-//            }
-//        }
         google()
         mavenCentral()
         gradlePluginPortal()
     }
 }

 dependencyResolutionManagement {
-//    repositoriesMode = RepositoriesMode.PREFER_PROJECT
     repositories {
-//        google {
-//            content {
-//                includeGroupByRegex("com\\.android.*")
-//                includeGroupByRegex("com\\.google.*")
-//                includeGroupByRegex("androidx.*")
-//            }
-//        }
         google()
         mavenCentral()
         gradlePluginPortal()
     }
 }

Also applies to: 18-18, 20-27

core-base/database/build.gradle.kts (1)

32-48: Remove commented-out code.

The entire sourceSets block is commented out because the new mifos.kmp.room plugin handles Room dependencies centrally. Remove the commented code to improve maintainability.

🧹 Proposed cleanup
     androidLibrary {
         namespace = "template.core.base.database"
     }
-
-//    sourceSets {
-//        androidMain.dependencies {
-//            implementation(libs.androidx.room.runtime)
-//        }
-//
-//        desktopMain.dependencies {
-//            implementation(libs.androidx.room.runtime)
-//        }
-//
-//        nativeMain.dependencies {
-//            implementation(libs.androidx.room.runtime)
-//        }
-//
-//        nonJsCommonMain.dependencies {
-//            implementation(libs.androidx.room.runtime)
-//        }
-//    }
 }
core/designsystem/build.gradle.kts (2)

29-46: Remove commented-out android {} block.

The old android {} configuration (lines 29-35) has been replaced by the new androidLibrary {} block. Remove the commented code.

🧹 Proposed cleanup
 kotlin {
-//    android {
-//        defaultConfig {
-//            testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
-//        }
-//        namespace = "org.mifos.core.designsystem"
-//
-//    }
-
     androidLibrary {
         namespace = "org.mifos.core.designsystem"
         withDeviceTest {

61-67: Remove commented-out test sourceSets.

The old androidInstrumentedTest and androidUnitTest configurations are now handled by androidDeviceTest and androidHostTest. Remove the commented code.

🧹 Proposed cleanup
         val androidDeviceTest by getting {
             dependencies {
                 implementation(libs.androidx.compose.ui.test)
             }
         }
-//
-//        androidInstrumentedTest.dependencies {
-//            implementation(libs.androidx.compose.ui.test)
-//        }
-//        androidUnitTest.dependencies {
-//            implementation(libs.androidx.compose.ui.test)
-//        }
         commonMain.dependencies {
core-base/analytics/build.gradle.kts (1)

34-38: Clarify or remove the empty KotlinMetadataTarget block.

The comment "force BuildKonfig to attach" doesn't explain why an empty compilation configuration is necessary. If BuildKonfig requires this block, add a more detailed comment explaining the rationale and link to relevant documentation. If it's not needed, remove it.

📝 Suggested improvement
 targets.withType<KotlinMetadataTarget> {
     compilations.all {
-        // force BuildKonfig to attach
+        // Empty block required to ensure BuildKonfig processes metadata target
+        // See: https://github.com/yshrsmz/BuildKonfig/issues/XXX
     }
 }
build-logic/convention/build.gradle.kts (1)

13-28: Remove commented-out code or document the transition plan.

Large blocks of commented code reduce readability. If this code is preserved for reference during migration, add a comment explaining when it can be removed. Otherwise, delete it.

🧹 Cleanup suggestion

If the migration is complete:

-//java {
-//    sourceCompatibility = JavaVersion.VERSION_17
-//    targetCompatibility = JavaVersion.VERSION_17
-//}
-
 java {
     toolchain {
         languageVersion.set(JavaLanguageVersion.of(17))
     }
 }
-
-//kotlin {
-//    compilerOptions {
-//        jvmTarget = JvmTarget.JVM_17
-//    }
-//}

If preserving for transition, add context:

+// TODO: Remove after verifying all modules work with toolchain API (target: <date>)
 //java {
 //    sourceCompatibility = JavaVersion.VERSION_17
build-logic/convention/src/main/kotlin/org/convention/KotlinMultiplatform.kt (1)

10-10: Unused import.

kotlinExtension is imported but not used anywhere in this file.

Suggested fix
-import org.jetbrains.kotlin.gradle.dsl.kotlinExtension
core-base/platform/build.gradle.kts (1)

34-38: Document the BuildKonfig workaround.

This empty block is a workaround to force BuildKonfig plugin attachment. Consider adding a link to the relevant issue for future maintainers.

Suggested improvement
     targets.withType<KotlinMetadataTarget> {
         compilations.all {
-            // force BuildKonfig to attach
+            // Workaround to force BuildKonfig plugin to attach to metadata target
+            // See: https://github.com/nicholasbishop/buildkonfig/issues/XXX
         }
     }
build.gradle.kts (2)

4-11: Remove commented-out code.

The commented-out repository filter configuration should be removed rather than left in the codebase. If needed in the future, it can be retrieved from version control history.

Suggested cleanup
 buildscript {
     repositories {
-//        google {
-//            content {
-//                includeGroupByRegex("com\\.android.*")
-//                includeGroupByRegex("com\\.google.*")
-//                includeGroupByRegex("androidx.*")
-//            }
-//        }
         google()
         mavenCentral()

55-56: Minor: Extra blank lines.

There are consecutive blank lines that could be reduced to a single blank line for consistency.

build-logic/convention/src/main/kotlin/KMPRoomConventionPlugin.kt (1)

26-35: Consider consolidating dependencies to nonJsCommonMain only.

Based on the KMP hierarchy defined in HierarchyTemplate.kt, nonJsCommonMain is indeed a parent source set that transitively includes androidMain, desktopMain, and nativeMain. Dependencies declared on nonJsCommonMain automatically propagate to these child source sets, making the explicit platform-specific declarations redundant.

You can safely consolidate to:

Suggested simplification
             dependencies {
-                add("androidMainImplementation", libs.findLibrary("androidx.room.runtime").get())
-                add("androidMainImplementation", libs.findLibrary("androidx.sqlite.bundled").get())
-                add("desktopMainImplementation", libs.findLibrary("androidx.room.runtime").get())
-                add("desktopMainImplementation", libs.findLibrary("androidx.sqlite.bundled").get())
-                add("nativeMainImplementation", libs.findLibrary("androidx.room.runtime").get())
-                add("nativeMainImplementation", libs.findLibrary("androidx.sqlite.bundled").get())
                 add("nonJsCommonMainImplementation", libs.findLibrary("androidx.room.runtime").get())
                 add("nonJsCommonMainImplementation", libs.findLibrary("androidx.sqlite.bundled").get())
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1105deb and 2a7f678.

📒 Files selected for processing (44)
  • build-logic/convention/build.gradle.kts
  • build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt
  • build-logic/convention/src/main/kotlin/KMPLibraryConventionPlugin.kt
  • build-logic/convention/src/main/kotlin/KMPRoomConventionPlugin.kt
  • build-logic/convention/src/main/kotlin/org/convention/KotlinAndroid.kt
  • build-logic/convention/src/main/kotlin/org/convention/KotlinMultiplatform.kt
  • build-logic/settings.gradle.kts
  • build.gradle.kts
  • cmp-android/dependencies/prodReleaseRuntimeClasspath.tree.txt
  • cmp-android/dependencies/prodReleaseRuntimeClasspath.txt
  • cmp-navigation/build.gradle.kts
  • cmp-shared/build.gradle.kts
  • cmp-shared/cmp_shared.podspec
  • core-base/analytics/build.gradle.kts
  • core-base/analytics/src/androidMain/kotlin/template/core/base/analytics/di/AnalyticsModule.kt
  • core-base/common/build.gradle.kts
  • core-base/database/build.gradle.kts
  • core-base/designsystem/build.gradle.kts
  • core-base/network/build.gradle.kts
  • core-base/platform/build.gradle.kts
  • core-base/platform/src/androidMain/kotlin/template/core/base/platform/review/AppReviewManagerImpl.kt
  • core-base/platform/src/androidMain/kotlin/template/core/base/platform/update/AppUpdateManagerImpl.kt
  • core-base/ui/build.gradle.kts
  • core/analytics/build.gradle.kts
  • core/common/build.gradle.kts
  • core/data/build.gradle.kts
  • core/data/src/androidMain/kotlin/org/mifos/core/data/util/ConnectivityProvider.android.kt
  • core/database/build.gradle.kts
  • core/datastore/build.gradle.kts
  • core/designsystem/build.gradle.kts
  • core/domain/build.gradle.kts
  • core/model/build.gradle.kts
  • core/network/build.gradle.kts
  • core/ui/build.gradle.kts
  • feature/home/build.gradle.kts
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/task/EditTaskScreen.kt
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksScreen.kt
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksUiState.kt
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksViewModel.kt
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/utils/DateTimeFormatter.kt
  • feature/profile/build.gradle.kts
  • feature/settings/build.gradle.kts
  • gradle/libs.versions.toml
  • settings.gradle.kts
🔇 Additional comments (39)
cmp-shared/cmp_shared.podspec (2)

33-34: LGTM: Cosmetic changes only.

These lines contain only whitespace or indentation adjustments with no functional impact.


46-46: LGTM: Formatting adjustment.

This is a trailing newline adjustment with no functional impact on the podspec.

core-base/platform/src/androidMain/kotlin/template/core/base/platform/update/AppUpdateManagerImpl.kt (1)

19-19: Migration to BuildKonfig looks correct.

The change from BuildConfig.DEBUG to BuildKonfig.DEBUG aligns with the broader migration to BuildKonfig for multiplatform build constants.

Also applies to: 72-72

core-base/platform/src/androidMain/kotlin/template/core/base/platform/review/AppReviewManagerImpl.kt (1)

15-15: Migration to BuildKonfig is correctly implemented.

The change from BuildConfig.DEBUG to BuildKonfig.DEBUG is consistent with the PR's objective to introduce BuildKonfig for build-time constants across multiplatform code. The BuildKonfig plugin is properly configured in core-base/platform/build.gradle.kts with the DEBUG constant defined as a BOOLEAN field in the defaultConfigs block, and the import statement and usage on lines 15 and 59 are both correct.

feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksViewModel.kt (1)

115-115: The boundary check is correct; the original concern misunderstands the indexing system.

selectedMonthIndex is 1-based (1-12 for Jan-Dec), not 0-based as assumed in the review. This is confirmed by:

  • Line 48: defaultMonthIndex = datetimeInSystemZone.month.number returns 1-12
  • Line 25: Documentation explicitly states "(1 for January, 2 for February, etc.)"
  • Line 65: months[selectedMonthIndex - 1] converts from 1-based to array indexing

With this 1-based system, the boundary check selectedMonthIndex < 12 is correct:

  • Allows increment from 1 to 11 → 2 to 12 (January through December)
  • Prevents increment when at 12 (December) to avoid wrapping to 13

The concern that it "would cause invalid date construction and potential crashes" does not apply. The original < 11 would have been the actual bug, preventing December navigation.

Note: There is a minor documentation inconsistency at line 62 which incorrectly states "if [selectedMonthIndex] is 0" when it should be "1".

Likely an incorrect or invalid review comment.

feature/home/build.gradle.kts (1)

28-30: Namespace migration looks correct.

The Android namespace has been successfully migrated to the androidLibrary block within the kotlin DSL, aligning with the KMP modernization effort across the project.

core/domain/build.gradle.kts (1)

27-29: Namespace migration looks correct.

The Android namespace has been successfully migrated to the androidLibrary block within the kotlin DSL.

core/model/build.gradle.kts (1)

29-31: Namespace migration looks correct.

The Android namespace has been successfully migrated to the androidLibrary block within the kotlin DSL.

feature/profile/build.gradle.kts (1)

28-30: Namespace migration looks correct.

The Android namespace has been successfully migrated to the androidLibrary block within the kotlin DSL.

feature/home/src/commonMain/kotlin/org/mifos/feature/home/utils/DateTimeFormatter.kt (1)

40-42: The code is valid and will compile without issues. kotlin.time.Instant has a toLocalDateTime extension function that accepts kotlinx.datetime.TimeZone. This is confirmed by similar patterns in EditTaskScreen.kt and TasksUiState.kt, which successfully use kotlin.time.Clock.System.now().toLocalDateTime(TimeZone.currentSystemDefault()). There is no type mismatch between the types being used.

Likely an incorrect or invalid review comment.

core-base/common/build.gradle.kts (1)

27-30: LGTM! AndroidLibrary DSL migration is correct.

The namespace has been properly migrated from the legacy android {} block to the new kotlin { androidLibrary { ... } } DSL as part of the KMP modernization.

core-base/designsystem/build.gradle.kts (1)

29-31: LGTM! AndroidLibrary DSL migration is correct.

The namespace configuration has been properly migrated to the androidLibrary block.

core/analytics/build.gradle.kts (1)

30-32: LGTM! AndroidLibrary DSL migration is correct.

The namespace declaration has been properly moved to the androidLibrary block, consistent with the project-wide KMP modernization.

core/datastore/build.gradle.kts (1)

28-33: API migration to consumerKeepRules is correct for AGP 8.13.2.

The codebase uses AGP 8.13.2, and the optimization { consumerKeepRules.files.add(...) } API is the appropriate replacement for the deprecated consumerProguardFiles in this version. The migration pattern is consistently applied across all affected modules (core/datastore and core/network).

core/common/build.gradle.kts (1)

29-31: LGTM! Clean migration to androidLibrary DSL.

The migration from the legacy android {} block to the KMP-friendly androidLibrary {} DSL is correctly implemented.

cmp-navigation/build.gradle.kts (1)

56-58: LGTM! Clean migration to androidLibrary DSL.

The migration to the androidLibrary {} DSL is correctly implemented.

cmp-shared/build.gradle.kts (1)

72-74: LGTM! Clean migration to androidLibrary DSL.

The migration from the legacy android {} block to the KMP-friendly androidLibrary {} DSL is correctly implemented.

build-logic/settings.gradle.kts (1)

14-24: No action needed — Kotlin version is already aligned with the version catalog.

The hardcoded version 2.3.0 matches the version catalog definition (kotlin = "2.3.0" in gradle/libs.versions.toml), so there is no version conflict. The pluginManagement block in settings.gradle.kts using inline version declarations is a standard and acceptable practice. Kotlin 2.3.0 is a stable release (December 16, 2025).

Likely an incorrect or invalid review comment.

core-base/ui/build.gradle.kts (1)

10-10: LGTM! Clean migration to androidLibrary DSL.

The import and migration to the androidLibrary block correctly modernizes the Android library configuration for Kotlin Multiplatform. The withDeviceTest configuration properly sets up Android instrumentation testing.

Also applies to: 30-35

core-base/network/build.gradle.kts (1)

10-10: LGTM! Consistent androidLibrary DSL migration.

The namespace migration to the androidLibrary block is correctly implemented and consistent with the project-wide modernization.

Also applies to: 28-30

feature/settings/build.gradle.kts (1)

10-10: LGTM! Consistent androidLibrary DSL migration.

The namespace migration to the androidLibrary block is correctly implemented and consistent with the project-wide modernization.

Also applies to: 27-29

core/database/build.gradle.kts (1)

10-10: LGTM! Consistent androidLibrary DSL migration.

The namespace migration to the androidLibrary block is correctly implemented.

Also applies to: 30-32

core/network/build.gradle.kts (1)

30-38: LGTM—androidLibrary migration looks correct.

The migration from the legacy android {} block to kotlin { androidLibrary {} } is correctly structured, and the consumerKeepRules configuration is properly added.

core/data/build.gradle.kts (1)

27-30: LGTM—androidLibrary migration looks correct.

The namespace configuration has been successfully moved to the androidLibrary block.

core/designsystem/build.gradle.kts (1)

37-46: LGTM—Test configuration migration looks correct.

The migration to withDeviceTest and withHostTest configurations is properly structured, and the test runner and resource settings are correctly applied.

gradle/libs.versions.toml (4)

116-117: LGTM—New BuildKonfig and plugin entries added correctly.

The new entries for BuildKonfig plugin, firebase-common-ktx library, and the android-kotlin-multiplatform-library plugin are properly structured and align with the PR's migration goals.

Also applies to: 161-161, 337-337, 349-349, 353-353


59-59: Kotlin 2.3.0 is the latest stable version (released December 16, 2025).


113-114: Room version 2.8.4 already has full Kotlin Multiplatform support (KMP support was introduced in the 2.7.x line). No change needed.


4-5: No action required—both versions are valid and available.

AGP version 8.13.2 is an official release with documented fixes (AAPT2 compatibility, R8/kotlin-metadata updates). Android Build Tools 31.13.2 is the current stable 31.x release, available in Maven repositories.

core-base/database/build.gradle.kts (1)

23-23: Verify that the mifos.kmp.room convention plugin is properly configured.

Ensure the plugin is correctly defined in the build-logic convention plugins directory, registered in settings.gradle.kts, and that the KMPRoomConventionPlugin class exists. This plugin centralizes Room dependency handling and must be accessible for the alias to resolve correctly.

build-logic/convention/build.gradle.kts (1)

24-28: Kotlin JVM target configuration is properly configured elsewhere.

The commented-out Kotlin block in build.gradle.kts is redundant. The JVM 17 target is actively configured in build-logic/convention/src/main/kotlin/org/convention/KotlinAndroid.kt at line 66, within the configureKotlin() function. No action needed.

build-logic/convention/src/main/kotlin/org/convention/KotlinAndroid.kt (1)

61-61: LGTM: Function visibility change is necessary for cross-package usage.

Making configureKotlin() public is required for KMPLibraryConventionPlugin (which is in a different package) to import and call it. This centralizes Kotlin compilation configuration and enables code reuse across convention plugins.

core-base/analytics/build.gradle.kts (1)

54-61: Remove TODO and document the dual Firebase implementation pattern.

The androidMain configuration using direct Firebase SDK is intentional and aligns with the androidMain source code imports. The androidProd flavor uses the GitLive wrapper instead. This is a valid dual-implementation strategy for multiplatform projects. Replace the TODO with a brief comment documenting why androidMain differs from other platforms, then remove the commented-out gitlive line.

build-logic/convention/src/main/kotlin/AndroidLintConventionPlugin.kt (1)

32-33: Change correctly aligns with KMP migration.

The plugin identifier com.android.kotlin.multiplatform.library is valid, consistently applied in KMPLibraryConventionPlugin, and properly checked in AndroidLintConventionPlugin. Lint configuration is appropriately scoped to KMP library modules.

cmp-android/dependencies/prodReleaseRuntimeClasspath.txt (1)

1-416: This is an auto-generated dependency lock file; review version choices in gradle/libs.versions.toml instead.

The file prodReleaseRuntimeClasspath.txt is generated automatically by the dependencyGuard plugin and reflects resolved dependencies from the version catalog. Changes here are consequences of updates made to gradle/libs.versions.toml, not independent modifications. Review version safety and compatibility in the catalog itself (Kotlin 2.3.0, Ktor 3.3.3, Koin 4.1.1, Firebase BOM 34.7.0, etc.) rather than this generated output.

Likely an incorrect or invalid review comment.

core/ui/build.gradle.kts (1)

29-34: LGTM!

The migration to androidLibrary DSL with namespace and device test configuration is correctly structured.

build-logic/convention/src/main/kotlin/KMPLibraryConventionPlugin.kt (1)

11-27: LGTM!

The migration to com.android.kotlin.multiplatform.library plugin and the centralized configuration approach with configureKotlinMultiplatform() and configureKotlin() is well-structured. The test dependencies for common source sets are appropriate.

Minor: There's an extra blank line at line 24 that could be removed for consistency.

build.gradle.kts (1)

24-53: LGTM!

The plugin declarations are properly configured with apply false for plugins that should only be applied in submodules. The addition of android.kotlin.multiplatform.library and buildKonfig plugins aligns with the KMP migration.

build-logic/convention/src/main/kotlin/org/convention/KotlinMultiplatform.kt (1)

23-31: compileSdk = 36 is now the stable Android 16 SDK.

Android 16 (API level 36) was released to the stable channel in March 2025 and is the current standard. The androidLibrary configuration is well-structured with proper desugaring setup.


group = "org.convention.buildlogic"

// Configure the build-logic plugins to target JDK 19
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Update outdated comment.

The comment references JDK 19, but the code now configures Java 17. Update the comment to match the actual configuration.

📝 Proposed fix
-// Configure the build-logic plugins to target JDK 19
+// Configure the build-logic plugins to target JDK 17
 // This matches the JDK used to build the project, and is not related to what is running on device.
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// Configure the build-logic plugins to target JDK 19
// Configure the build-logic plugins to target JDK 17
// This matches the JDK used to build the project, and is not related to what is running on device.
🤖 Prompt for AI Agents
In @build-logic/convention/build.gradle.kts at line 11, Update the outdated
comment that reads "Configure the build-logic plugins to target JDK 19" so it
matches the actual configuration (JDK 17); locate the comment in
build.gradle.kts (the line containing that phrase) and change the text to
reference JDK 17 instead of JDK 19.

Comment on lines +3 to +4
import com.android.build.api.dsl.androidLibrary
import com.android.build.gradle.internal.ide.kmp.KotlinAndroidSourceSetMarker.Companion.android
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Avoid using internal Android Gradle Plugin APIs.

The import com.android.build.gradle.internal.ide.kmp.KotlinAndroidSourceSetMarker.Companion.android references an internal AGP class (internal package). Internal APIs are not part of the public contract and may change or be removed without notice in future AGP versions, causing build breakages.

Additionally, this import doesn't appear to be used in the current file.

Suggested fix
 import com.android.build.api.dsl.androidLibrary
-import com.android.build.gradle.internal.ide.kmp.KotlinAndroidSourceSetMarker.Companion.android
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
import com.android.build.api.dsl.androidLibrary
import com.android.build.gradle.internal.ide.kmp.KotlinAndroidSourceSetMarker.Companion.android
import com.android.build.api.dsl.androidLibrary
🤖 Prompt for AI Agents
In @build-logic/convention/src/main/kotlin/org/convention/KotlinMultiplatform.kt
around lines 3 - 4, The file imports an internal AGP symbol
com.android.build.gradle.internal.ide.kmp.KotlinAndroidSourceSetMarker.Companion.android
which is unsafe and (per review) unused; remove that import and any references
to KotlinAndroidSourceSetMarker.android from KotlinMultiplatform.kt, and if you
need Android source-set wiring use the public DSL/API (e.g., androidLibrary or
the official Kotlin Multiplatform sourceSet accessors) instead of the internal
class; ensure the remaining imports (like androidLibrary) are kept only if
actually used.

Comment on lines +407 to 415
if (selectedMonth.lowercase() != "january") {
IconButton(onClick = onPreviousMonth) {
Icon(
imageVector = Icons.AutoMirrored.Filled.ArrowLeft,
contentDescription = "Navigate to previous month",
tint = MaterialTheme.colorScheme.primary,
)
}
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

String-based month boundary checking is fragile and not i18n-friendly.

The current implementation uses case-insensitive string comparison (selectedMonth.lowercase() != "january") to determine month boundaries. This approach has several issues:

  • Breaks if month names are localized or displayed in a different format
  • Fragile to changes in month representation
  • Makes the code harder to maintain

Consider refactoring to use a numeric month index (1-12) in the UI state instead of month names, which would make boundary checking robust and format-agnostic:

// In ViewModel/State: selectedMonthIndex: Int (1-12)
if (selectedMonthIndex > 1) { /* show previous arrow */ }
if (selectedMonthIndex < 12) { /* show next arrow */ }

Also applies to: 424-432

🤖 Prompt for AI Agents
In
@feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksScreen.kt
around lines 407 - 415, The UI currently does fragile string-based month checks
using selectedMonth.lowercase() != "january"; replace this with a numeric month
index in state (e.g., selectedMonthIndex: Int with range 1..12) and change
visibility checks to bounds checks (if selectedMonthIndex > 1 for previous arrow
and if selectedMonthIndex < 12 for next arrow). Update handlers
(onPreviousMonth/onNextMonth) to increment/decrement selectedMonthIndex with
proper clamping, and render the displayed month name by formatting the index
into a localized month string rather than relying on stored names; apply the
same changes to the other occurrence referenced (lines ~424-432) so all
month-bound logic uses selectedMonthIndex.

companion object {
// Default values based on the current date
private val currentMoment = Clock.System.now()
private val currentMoment = kotlin.time.Clock.System.now()
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find all usages of selectedMonthIndex and TasksUiState to verify 1-based indexing handling

echo "=== Searching for selectedMonthIndex usages ==="
rg -n -C3 'selectedMonthIndex' --type=kt -g '!**/TasksUiState.kt'

echo -e "\n=== Searching for TasksUiState instantiation ==="
rg -n -C3 'TasksUiState\(' --type=kt -g '!**/TasksUiState.kt'

echo -e "\n=== Searching for month-related arithmetic that might assume 0-based indexing ==="
rg -nP --type=kt 'selectedMonthIndex\s*[\+\-]' -g '!**/TasksUiState.kt'

Repository: openMF/kmp-project-template

Length of output: 349


🏁 Script executed:

# Check the actual TasksUiState.kt file content, particularly lines 25-26, 41, 48
head -60 feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksUiState.kt | cat -n

Repository: openMF/kmp-project-template

Length of output: 2978


🏁 Script executed:

# Verify kotlin.time.Clock usage - check imports to see if this is the right API
head -20 feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksUiState.kt | cat -n

Repository: openMF/kmp-project-template

Length of output: 872


🏁 Script executed:

# Look for any month offset or adjustment logic in the codebase
rg -n -C2 'month.*[\+\-].*1|month\[|month\.minus\(1\)|month\.plus\(1\)' --type=kt | head -50

Repository: openMF/kmp-project-template

Length of output: 97


🏁 Script executed:

# Search for selectedMonthIndex usages without --type filter
grep -r "selectedMonthIndex" feature/home/src/commonMain --include="*.kt" --include="*.kts" -n -C3 | grep -v "TasksUiState.kt"

Repository: openMF/kmp-project-template

Length of output: 5987


🏁 Script executed:

# Search for TasksUiState instantiation
grep -r "TasksUiState(" feature/home/src/commonMain --include="*.kt" --include="*.kts" -n -C3

Repository: openMF/kmp-project-template

Length of output: 2637


🏁 Script executed:

# Check for any other imports related to Clock in the file and surrounding files
grep -r "kotlin\.time\|kotlinx\.datetime" feature/home/src/commonMain --include="*.kt" --include="*.kts" -n | grep -E "Clock|Import" | head -30

Repository: openMF/kmp-project-template

Length of output: 407


🏁 Script executed:

# Verify the actual implementation - does kotlin.time.Clock and kotlinx.datetime.Clock have compatible APIs?
python3 << 'EOF'
# Check if kotlin.time.Clock.System.now() can be converted to LocalDateTime with kotlinx.datetime
# kotlin.time.Clock.System.now() returns kotlin.time.Instant
# kotlinx.datetime has its own Instant and Clock
# These are different types and incompatible

print("=== API Compatibility Analysis ===")
print("kotlin.time.Clock.System.now() returns: kotlin.time.Instant")
print("toLocalDateTime(TimeZone) is an extension on: kotlinx.datetime.Instant")
print("Issue: These are different types - this code will NOT compile")
print()
print("Expected fix: Use kotlinx.datetime.Clock.System.now() instead")
EOF

Repository: openMF/kmp-project-template

Length of output: 157


Fix critical compilation error and off-by-one logic in consumers.

The code has two blocking issues:

  1. API incompatibility (compilation error): kotlin.time.Clock.System.now() returns kotlin.time.Instant, but the code calls .toLocalDateTime(TimeZone) which is an extension on kotlinx.datetime.Instant—these are incompatible types. Use kotlinx.datetime.Clock.System.now() instead (also appears in EditTaskScreen.kt:304).

  2. Consumer logic broken: TasksViewModel.kt still adds 1 to selectedMonthIndex in multiple places (lines 83, 163, 168) despite the change to 1-based indexing. This creates new off-by-one errors—selectedMonthIndex becomes 2-13 instead of the expected 1-12. Remove the + 1 offsets in all consumer code.

🤖 Prompt for AI Agents
In
@feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksUiState.kt
at line 41, Replace the erroneous kotlin.time.Clock.System.now() call with
kotlinx.datetime.Clock.System.now() where currentMoment is defined (e.g., in
TasksUiState.kt and EditTaskScreen.kt usages) so the returned Instant matches
kotlinx.datetime extensions, and update the import to kotlinx.datetime.Clock;
also remove the unnecessary +1 adjustments wherever selectedMonthIndex is
consumed in TasksViewModel (stop adding 1 to selectedMonthIndex in the code
paths that currently do selectedMonthIndex + 1) so selectedMonthIndex remains
1..12 instead of becoming 2..13.

*/
val selectedMonth: String
get() = months[selectedMonthIndex]
get() = months[selectedMonthIndex - 1]
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Add bounds validation for selectedMonthIndex.

The selectedMonth getter directly accesses months[selectedMonthIndex - 1] without validating that selectedMonthIndex is within the valid range [1, 12]. Invalid values could cause IndexOutOfBoundsException at runtime.

🛡️ Proposed defensive check
 val selectedMonth: String
-    get() = months[selectedMonthIndex - 1]
+    get() = months.getOrElse(selectedMonthIndex - 1) { 
+        months[defaultMonthIndex - 1] 
+    }

Or add validation in the data class using require:

data class TasksUiState(
    val selectedYear: Int = defaultYear,
    val selectedMonthIndex: Int = defaultMonthIndex,
    val selectedDayInMonth: String = defaultDayInMonth.toString(),
    val weekdaysAndDaysInMonth: List<Pair<String, String>> = emptyList(),
) {
    init {
        require(selectedMonthIndex in 1..12) { 
            "selectedMonthIndex must be between 1 and 12, got $selectedMonthIndex" 
        }
    }
    // ...
}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
get() = months[selectedMonthIndex - 1]
get() = months.getOrElse(selectedMonthIndex - 1) {
months[defaultMonthIndex - 1]
}
🤖 Prompt for AI Agents
In
@feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksUiState.kt
at line 65, The selectedMonth getter accesses months[selectedMonthIndex - 1]
without bounds checking; add validation to prevent IndexOutOfBoundsException by
ensuring selectedMonthIndex is in 1..12. Fix options: add a
require(selectedMonthIndex in 1..12) check in the TasksUiState init block to
fail fast, or change the selectedMonth getter to safely clamp/return a default
when selectedMonthIndex is out of range (e.g., use safe index computation or a
guard that returns months.first()/months.last() or a null/placeholder). Update
references in TasksUiState (selectedMonth getter, selectedMonthIndex, months)
accordingly.

Comment on lines +68 to +70
ktorVersion = "3.3.3"
ktorfit = "2.7.1"
ktorfitKsp = "2.7.1"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🌐 Web query:

Ktor 3.3.3 Kotlin 2.3.0 compatibility requirements

💡 Result:

Short answer: Ktor 3.3.3 was built against Kotlin 2.2.x (changelog shows update to Kotlin 2.2.20 and published artifacts list kotlin-stdlib 2.2.21). There is no official indication that 3.3.3 is compiled/tested with Kotlin 2.3.0, and Kotlin 2.3.0 contains compiler/Gradle/plugin compatibility changes you must account for. For production stability either use Kotlin 2.2.x with Ktor 3.3.3 or upgrade Ktor to a release that explicitly updates its Kotlin target to 2.3.x. [1][2][3]

References

  • Ktor 3.3.3 changelog (shows "Update Kotlin to 2.2.20"). [1]
  • Ktor docs / server dependencies (artifact examples using 3.3.3). [2]
  • Kotlin 2.3 compatibility guide (breaking/Gradle/plugin changes in 2.3.0). [3]

Would you like exact Gradle/KGP/AGP version requirements for Kotlin 2.3.0 in your project (I can look them up and give concrete settings)?


🌐 Web query:

Ktorfit 2.7.1 Kotlin version compatibility

💡 Result:

Ktorfit 2.7.1 requires Kotlin >= 2.2.0 (and KSP >= 2.0.2); it targets Ktor 3.3.3 and was released 2025-12-11. [1][2]

Sources:
[1] Ktorfit changelog (2.7.1).
[2] Ktorfit GitHub releases.


🏁 Script executed:

# Find gradle/libs.versions.toml and check Kotlin version
cat gradle/libs.versions.toml | grep -i kotlin

Repository: openMF/kmp-project-template

Length of output: 3706


Incompatible Kotlin version: Ktor 3.3.3 targets Kotlin 2.2.x, not 2.3.0.

Ktor 3.3.3 was built against Kotlin 2.2.20 and has no official support for Kotlin 2.3.0, which contains compiler and Gradle plugin breaking changes. While Ktorfit 2.7.1 technically requires only Kotlin ≥ 2.2.0, this combination lacks official testing and support. Either downgrade Kotlin to 2.2.x or upgrade Ktor to a release targeting Kotlin 2.3.x.

- Removed redundant buildscript classpath entry in build.gradle.kts.
- Updated BuildKonfig default flavor string from 'dev' to 'demo' in core-base/analytics/build.gradle.kts.
- Corrected currentTime assignment to use kotlinx.datetime.Clock.System.now() in EditTaskScreen.kt and TasksUiState.kt.
- Removed unnecessary +1 adjustments for selectedMonthIndex in TasksViewModel.kt.
- Updated kotlinx-datetime version to 0.6.0 in gradle/libs.versions.toml.
- Corrected Instant creation and import in DateTimeFormatter.kt to use kotlinx.datetime.Instant.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksViewModel.kt (1)

81-87: Critical bug: incorrect month offset in date string formatting.

Line 83 adds 1 to selectedMonthIndex, but with the new 1-based indexing (1-12), this produces months in the 2-13 range. This will cause incorrect date strings and break task retrieval for the selected date.

🐛 Proposed fix
 val tasks: StateFlow<List<TaskEntity>> =
     tasksUiState.map {
-        val selectedMonth = it.selectedMonthIndex.plus(1).toString().formatDay()
+        val selectedMonth = it.selectedMonthIndex.toString().formatDay()
         "$selectedMonth/${it.selectedDayInMonth}/${it.selectedYear}"
     }.flatMapLatest { dateString ->
         storageService.getSelectedDayTasks(dateString)
core-base/analytics/build.gradle.kts (1)

1-23: Remove duplicate copyright header.

The file contains two copyright headers—one for 2026 (lines 1-9) and one for 2025 (lines 15-23). This appears to be a copy-paste oversight.

🧹 Proposed fix
-/*
- * Copyright 2026 Mifos Initiative
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at https://mozilla.org/MPL/2.0/.
- *
- * See https://github.com/openMF/kmp-project-template/blob/main/LICENSE
- */
 import com.android.build.api.dsl.androidLibrary
 import com.codingfeline.buildkonfig.compiler.FieldSpec
-
 import org.jetbrains.kotlin.gradle.plugin.mpp.KotlinMetadataTarget
 
 /*
- * Copyright 2025 Mifos Initiative
+ * Copyright 2026 Mifos Initiative
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
🤖 Fix all issues with AI agents
In @core-base/analytics/build.gradle.kts:
- Around line 54-61: Remove the unused Firebase analytics dependency by deleting
the implementation(libs.firebase.analytics) entry (and its corresponding
import/alias from the build script if present) inside the
androidMain.dependencies block; confirm AnalyticsModule continues to use
StubAnalyticsHelper() and that no code references Firebase.analytics elsewhere,
and also remove any now-unnecessary firebase BOM import
(implementation(project.dependencies.platform(libs.firebase.bom))) if nothing
else in the module depends on it; do not assume cmp-android provides Firebase.

In
@feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksViewModel.kt:
- Around line 113-120: selectNextMonth() is currently a no-op because it copies
selectedMonthIndex to itself; change the assignment in the _tasksUiState.copy
call inside selectNextMonth() to increment the index (e.g., selectedMonthIndex +
1) and keep the existing upper-bound check (selectedMonthIndex < 12) so the
month advances by one before calling updateDaysInMonth(); ensure you reference
the selectNextMonth function and the _tasksUiState.value.copy(selectedMonthIndex
= ...) expression when making the change.
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2a7f678 and aaab477.

📒 Files selected for processing (9)
  • build.gradle.kts
  • cmp-android/dependencies/prodReleaseRuntimeClasspath.tree.txt
  • cmp-android/dependencies/prodReleaseRuntimeClasspath.txt
  • core-base/analytics/build.gradle.kts
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/task/EditTaskScreen.kt
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksUiState.kt
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksViewModel.kt
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/utils/DateTimeFormatter.kt
  • gradle/libs.versions.toml
🔇 Additional comments (15)
feature/home/src/commonMain/kotlin/org/mifos/feature/home/utils/DateTimeFormatter.kt (1)

15-15: LGTM!

The shift to fully-qualified kotlinx.datetime.Instant usage aligns with the broader datetime API standardization across the codebase.

Also applies to: 41-41

feature/home/src/commonMain/kotlin/org/mifos/feature/home/task/EditTaskScreen.kt (1)

51-51: LGTM!

The fully-qualified kotlinx.datetime.Clock.System.now() usage is consistent with the datetime API standardization applied throughout this PR.

Also applies to: 305-305

feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksUiState.kt (1)

42-42: LGTM! Month indexing shifted from 0-based to 1-based.

The changes correctly implement 1-based month indexing (1-12 instead of 0-11). The selectedMonth getter properly adjusts by subtracting 1 when indexing into the zero-based months list.

Ensure that all code consuming selectedMonthIndex in TasksViewModel has been updated to handle the new 1-based indexing semantics.

Also applies to: 49-49, 66-66

feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksViewModel.kt (1)

161-176: LGTM! Date calculation logic correctly updated for 1-based month indexing.

Lines 163 and 168 now use selectedMonthIndex directly (without adding 1), which is correct since LocalDate expects 1-based months (1-12) and selectedMonthIndex is now 1-based.

cmp-android/dependencies/prodReleaseRuntimeClasspath.txt (1)

1-416: LGTM - Generated dependency file.

This is an auto-generated dependency list that reflects the resolved runtime classpath. The actual version updates are controlled by the version catalog and build configuration files, which should be the focus of review.

core-base/analytics/build.gradle.kts (3)

63-77: LGTM - Improved dependency encapsulation.

Changing from api to implementation for Firebase dependencies across all source sets improves encapsulation and follows best practices by not exposing these dependencies to consumers of this module.


87-103: LGTM - BuildKonfig configuration is well-structured.

The BuildKonfig configuration correctly provides build-time constants for flavor and demo mode detection. The default configuration uses "demo" flavor with demo mode enabled, while the "prod" target configuration appropriately overrides these values.


34-38: Remove or verify the necessity of the KotlinMetadataTarget workaround.

This empty compilations.all block appears to be a workaround for a BuildKonfig metadata target issue that has been reported and supposedly fixed in version 0.17.1 (which the project currently uses). The workaround is duplicated identically in both core-base/platform/build.gradle.kts and core-base/analytics/build.gradle.kts. Since BuildKonfig 0.17.1 includes fixes for metadata-related compatibility issues, verify that this workaround is still necessary by attempting to remove it from one module and confirming the build and Gradle sync work correctly.

gradle/libs.versions.toml (5)

161-161: LGTM - BuildKonfig plugin library added correctly.

The BuildKonfig Gradle plugin library entry is properly configured with the version reference.


349-349: LGTM - Android Kotlin Multiplatform library plugin added.

The android-kotlin-multiplatform-library plugin is correctly declared to support the migration to the new KMP Android library DSL mentioned in the PR objectives.


353-353: LGTM - BuildKonfig plugin added correctly.

The BuildKonfig plugin is properly declared with the correct version reference, supporting the build-time constants feature introduced in this PR.


59-59: Kotlin 2.3.0 is a stable release and available.

Kotlin 2.3.0 was released on December 16, 2025, as a stable version. No issues with this update.


8-8: Firebase BOM version 34.7.0 is valid and has no known security vulnerabilities.

Firebase BOM 34.7.0 was released on December 11, 2025, and is published to Google's Maven repository. No public security advisories or CVEs are associated with this version. The version is current and safe to use.

build.gradle.kts (2)

4-11: LGTM - Simplified repository configuration.

Replacing the filtered google() repository with a simple google() call improves readability. The previous content filtering may have been overly restrictive for the project's needs.


26-52: LGTM - Plugin declarations properly configured.

The added plugin declarations correctly use apply false (except moduleGraph which is applied), allowing subprojects to selectively apply them. The additions support the KMP modernization, BuildKonfig integration, and other features described in the PR objectives.

Comment on lines +54 to 61
// TODO: The dependency is throwing errors.
// I am commenting it, but please verify if it is actually even required in android Main block.
// As the cmp-android source set applies firebase itself also.
androidMain.dependencies {
api(libs.gitlive.firebase.analytics)
implementation(project.dependencies.platform(libs.firebase.bom))
implementation(libs.firebase.analytics)
// implementation(libs.gitlive.firebase.analytics)
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# Search for Firebase Analytics usage in androidMain source set
fd -e kt -e java . core-base/analytics/src/androidMain --exec rg -n "FirebaseAnalytics|firebase\.analytics" {} \;

# Check if cmp-android module includes Firebase
rg -n "firebase" cmp-android/build.gradle.kts

# Also search broadly for Firebase in the main analytics module
rg -n "firebase.*analytics" core-base/analytics/

Repository: openMF/kmp-project-template

Length of output: 1804


🏁 Script executed:

cat -n core-base/analytics/src/androidMain/kotlin/template/core/base/analytics/di/AnalyticsModule.kt

Repository: openMF/kmp-project-template

Length of output: 1285


🏁 Script executed:

# Check cmp-android for Firebase dependencies
find . -path "*/cmp-android/build.gradle.kts" -o -path "*/cmp-android/build.gradle" | xargs cat -n 2>/dev/null | grep -i firebase

# Also check if there's a cmp-android directory
fd -t d cmp-android

Repository: openMF/kmp-project-template

Length of output: 83


🏁 Script executed:

cat -n cmp-android/build.gradle.kts | head -100

Repository: openMF/kmp-project-template

Length of output: 3980


🏁 Script executed:

cat -n cmp-android/build.gradle.kts | grep -A 200 "dependencies {"

Repository: openMF/kmp-project-template

Length of output: 2638


Remove the unused Firebase analytics dependency from androidMain.

The Firebase analytics dependency in androidMain (libs.firebase.analytics) is imported but never actually used. The AnalyticsModule only instantiates StubAnalyticsHelper(), while the Firebase.analytics provision is completely commented out. Additionally, the claim in the TODO that "cmp-android source set applies firebase itself" is incorrect—cmp-android has no Firebase dependencies declared. Remove the unused dependency and import to eliminate unnecessary bloat.

🤖 Prompt for AI Agents
In @core-base/analytics/build.gradle.kts around lines 54 - 61, Remove the unused
Firebase analytics dependency by deleting the
implementation(libs.firebase.analytics) entry (and its corresponding
import/alias from the build script if present) inside the
androidMain.dependencies block; confirm AnalyticsModule continues to use
StubAnalyticsHelper() and that no code references Firebase.analytics elsewhere,
and also remove any now-unnecessary firebase BOM import
(implementation(project.dependencies.platform(libs.firebase.bom))) if nothing
else in the module depends on it; do not assume cmp-android provides Firebase.

- Renamed `selectedMonthIndex` to `selectedMonthNumber` in `TasksUiState` and `TasksViewModel` to better reflect 1-based indexing.
- Updated `TasksViewModel` logic to correctly increment/decrement month navigation using `selectedMonthNumber`.
- Replaced `kotlinx.datetime.Clock` with `kotlin.time.Clock` in `TasksUiState` and `EditTaskScreen`.
- Updated `TasksUiState` companion object to use `datetimeInSystemZone.day` instead of `dayOfMonth`.
- Bumped dependency versions: `androidx-test-ext-junit` to 1.3.0 and `kotlinx-datetime` to 0.7.1.
- Moved `ConnectivityProvider` from `mobileMain` to `iosMain` source set.
- Removed unused `Instant` import in `DateTimeFormatter.kt`.
- Updated `kotlinx-datetime` and `kotlinx-datetime-jvm` from 0.6.0 to 0.7.1.
- Updated `build.gradle.kts` in `core-base:platform` to explicitly set the `DEBUG` build config field to `false` by default and `true` for debug configurations.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksViewModel.kt (1)

82-87: Fix critical crash: LocalDate constructor receives 0-based month, expects 1-based

The code is internally inconsistent about month indexing. selectedMonthNumber is 0-based (evidenced by line 83's +1 for display), but lines 151 and 168 pass it directly to LocalDate(year, month, day), which expects month to be 1..12. This causes IllegalArgumentException when selectedMonthNumber is 0 (January).

Additionally, analytics logging in selectNextMonth (line 114) and selectPreviousMonth (line 124) occurs before bounds validation, logging the wrong month value or invalid values like -1.

The proposed fix is correct: add +1 when constructing LocalDate objects (lines 151, 168) and move analytics calls after bounds checks:

Proposed fix
 private fun getDaysInMonth(month: Int, year: Int): Int {
-    val currentMonthDate = LocalDate(year, month, 1)
+    // month is 0-based (0..11); LocalDate month is 1..12
+    val currentMonthDate = LocalDate(year, month + 1, 1)
     val nextMonthDate = currentMonthDate.plus(1, DateTimeUnit.MONTH)
     return currentMonthDate.daysUntil(nextMonthDate)
 }

 fun selectNextMonth() {
-    analyticsHelper.logSelectNextMonth(selectedMonthIndex)
-    if (selectedMonthIndex < 12) {
-        _tasksUiState.value =
-            _tasksUiState.value.copy(selectedMonthNumber = selectedMonthIndex + 1)
+    val nextMonthIndex = selectedMonthIndex + 1
+    if (nextMonthIndex <= 11) {
+        analyticsHelper.logSelectNextMonth(nextMonthIndex)
+        _tasksUiState.value = _tasksUiState.value.copy(selectedMonthNumber = nextMonthIndex)
         updateDaysInMonth()
     }
 }

 fun selectPreviousMonth() {
-    analyticsHelper.logSelectPreviousMonth(selectedMonthIndex - 1)
-
-    if (selectedMonthIndex > 0) {
-        _tasksUiState.value =
-            _tasksUiState.value.copy(selectedMonthNumber = selectedMonthIndex - 1)
+    val previousMonthIndex = selectedMonthIndex - 1
+    if (previousMonthIndex >= 0) {
+        analyticsHelper.logSelectPreviousMonth(previousMonthIndex)
+        _tasksUiState.value = _tasksUiState.value.copy(selectedMonthNumber = previousMonthIndex)
         updateDaysInMonth()
     }
 }

 private fun updateDaysInMonth() {
     val daysInCurrentMonth =
         getDaysInMonth(year = selectedYear, month = selectedMonthIndex)

     val weekdaysAndDaysInSelectedMonth = mutableListOf<Pair<String, String>>()

     for (day in 1..daysInCurrentMonth) {
-        val date = LocalDate(selectedYear, selectedMonthIndex, day)
+        val date = LocalDate(selectedYear, selectedMonthIndex + 1, day)
         val weekday = shortWeekdayNames[date.dayOfWeek]

         weekdaysAndDaysInSelectedMonth.add(weekday!! to day.toString())
     }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between aaab477 and ae9d958.

📒 Files selected for processing (9)
  • cmp-android/dependencies/prodReleaseRuntimeClasspath.tree.txt
  • cmp-android/dependencies/prodReleaseRuntimeClasspath.txt
  • core-base/platform/build.gradle.kts
  • core/data/src/iosMain/kotlin/org/mifos/core/data/util/ConnectivityProvider.ios.kt
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/task/EditTaskScreen.kt
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksUiState.kt
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksViewModel.kt
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/utils/DateTimeFormatter.kt
  • gradle/libs.versions.toml
🚧 Files skipped from review as they are similar to previous changes (3)
  • core-base/platform/build.gradle.kts
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/tasks/TasksUiState.kt
  • feature/home/src/commonMain/kotlin/org/mifos/feature/home/utils/DateTimeFormatter.kt
🔇 Additional comments (8)
cmp-android/dependencies/prodReleaseRuntimeClasspath.txt (2)

388-392: Clarify Kotlin stdlib version across JDK variants.

The manifest includes mixed Kotlin versions: kotlin-stdlib at 2.3.0 but kotlin-stdlib-jdk7 and kotlin-stdlib-jdk8 at 1.8.22. Confirm this is expected from your BOM/version catalog strategy and not a resolution conflict.


344-349: No action needed — version divergence is intentional for Kotlin Multiplatform.

The org.jetbrains.androidx.* packages are JetBrains' official Kotlin Multiplatform variants of androidx libraries, maintained separately from the standard androidx.* artifacts. Their different versions (lifecycle 2.9.6 vs 2.9.4, navigation 2.9.1, savedstate 1.4.0) are expected and intentional, as they are independently released for KMP compatibility. Both sets coexist in the classpath with different group IDs and pose no dependency resolution issues.

Likely an incorrect or invalid review comment.

feature/home/src/commonMain/kotlin/org/mifos/feature/home/task/EditTaskScreen.kt (1)

304-304: No changes needed. The code at line 304 is valid and follows the same pattern successfully used in TasksUiState.kt. The kotlin.time.Clock.System.now() result is compatible with kotlinx.datetime.toLocalDateTime() through the library's provided extension functions.

Likely an incorrect or invalid review comment.

gradle/libs.versions.toml (5)

161-161: LGTM: New library entries are correctly formatted.

The new library entries for BuildKonfig and Firebase Common KTX follow the correct Gradle version catalog format with proper version references.

Also applies to: 337-337


349-349: LGTM: Plugin entries align with PR objectives.

The new plugin entries for android-kotlin-multiplatform-library and codingfeline-buildKonfig are correctly formatted and align with the PR's goal to modernize multiplatform configuration and provide build-time constants.

Also applies to: 353-353


59-65: No action needed—Kotlin and KSP versions are compatible.

Kotlin 2.3.0 exists and is stable. KSP 2.3.4 is the correct version and is fully compatible with Kotlin 2.3.0. KSP2 (KSP 2.x series) uses independent versioning—it is not bound to the Kotlin compiler version format as KSP1 was. The 2.3.4 version number is standard for KSP2 releases and correctly supports Kotlin 2.3.0.

Likely an incorrect or invalid review comment.


4-4: Android Gradle Plugin 8.13.2 is a valid, stable release published to Google's Maven repository and documented in the official Android Developers release notes. The version follows standard patch release cadences (8.13.0 → 8.13.1 → 8.13.2) with documented bug fixes and Kotlin 2.3 support. No verification is needed.

Likely an incorrect or invalid review comment.


8-8: No known security vulnerabilities exist in the updated dependency versions: Firebase BOM 34.7.0, Room 2.8.4, and BuildKonfig 0.17.1 (as of January 2026).

@TheKalpeshPawar
Copy link
Author

@niyajali Bhaiya please review this PR. Also I need to connect with you to discuss some things so, please connect with me at your earliest convenience.

@niyajali niyajali changed the title Version update chore: Update Project Dependencies to Latest Version Jan 12, 2026
@niyajali
Copy link
Collaborator

@TheKalpeshPawar We appreciate your Pull Request. As previously discussed, a migration to Kotlin 2.3 is currently not reasonable due to extensive configuration modifications on the Android platform and incompatible library dependencies. Consequently, we will retain this Pull Request for future consideration. Thank you for your understanding.

@niyajali
Copy link
Collaborator

I'm converting this PR to "Draft" and will be open when all libraries are updated with the new version of Kotlin and ready to intregate on this project.

@niyajali niyajali marked this pull request as draft January 12, 2026 15:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants