Skip to content

feat(loan): Implement undo approval screen#2665

Open
Arinyadav1 wants to merge 7 commits into
openMF:devfrom
Arinyadav1:Implement-Undo-Approval-Screen
Open

feat(loan): Implement undo approval screen#2665
Arinyadav1 wants to merge 7 commits into
openMF:devfrom
Arinyadav1:Implement-Undo-Approval-Screen

Conversation

@Arinyadav1

@Arinyadav1 Arinyadav1 commented Apr 7, 2026

Copy link
Copy Markdown
Member

Fixes - Jira-#682

@coderabbitai make a summary description of this PR

Screen_recording_20260407_192954.webm

Summary by CodeRabbit

  • New Features

    • Users can undo previously approved loans and submit an optional note.
    • Added an Undo Approval screen with navigation, ViewModel-driven form, loading indicator, and error dialog.
    • Introduced a resizable multiline text field for entering notes.
  • Chores

    • Improved offline/network handling for the undo flow and updated internal wiring and package metadata.

@Arinyadav1 Arinyadav1 requested a review from a team April 7, 2026 14:18
@coderabbitai

coderabbitai Bot commented Apr 7, 2026

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds an end-to-end "undo loan approval" feature: API endpoint, network datamanager, repository method and implementation, request model, DI/viewModel registration, navigation route, Compose screen and dialog, resizable text field component, string resource, and related build/podspec and network utilities.

Changes

Cohort / File(s) Summary
Network API & Datamanager
core/network/src/commonMain/kotlin/com/mifos/core/network/services/LoanService.kt, core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerLoan.kt
Added undoLoanApproval API endpoint in LoanService and a suspend wrapper in DataManagerLoan that calls the service and throws on non-success responses.
Repository & Model
core/data/src/commonMain/kotlin/com/mifos/core/data/repository/LoanAccountApprovalRepository.kt, core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanAccountApprovalRepositoryImp.kt, core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/LoanUndoApprovalRequest.kt
Introduced LoanUndoApprovalRequest model; repository interface gains suspend fun undoLoanApproval(...) : DataState<Unit>; implementation injects DataManagerLoan, dispatcher/network utilities, and implements the suspend method with network checks and error mapping.
Network Utilities
core/data/src/commonMain/kotlin/com/mifos/core/data/util/NetworkMonitor.kt
Added NetworkUnavailableException, requireOnline() suspend extension, and withNetworkCheck(...) Flow helper; clarified isOnline semantics.
Design System
core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosOutlinedTextField.kt
Added MifosResizableOutlinedTextField composable: multi-line OutlinedTextField with draggable resize handle and preview.
Feature — Navigation & DI
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/di/LoanModule.kt, feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt, feature/loan/src/commonMain/composeResources/values/strings.xml
Registered LoanUndoApprovalViewModel in DI, added string resource feature_loan_undo_approval_note, and registered undo-approval destination in loan navigation graph.
Feature — UI (route, screen, viewmodel)
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalRoute.kt, .../LoanUndoApprovalScreen.kt, .../LoanUndoApprovalViewModel.kt
Added serializable route and navigation helpers; new composables for screen/content/dialog; LoanUndoApprovalViewModel handles note input, submit/retry, calls repository, and emits navigation events.
Build / Podspec
cmp-shared/cmp_shared.podspec, core/data/build.gradle.kts
Bumped podspec version and adjusted resource path separator; added api(projects.coreBase.common) dependency to core/data.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI as LoanUndoApprovalScreen
    participant VM as LoanUndoApprovalViewModel
    participant Repo as LoanAccountApprovalRepository
    participant DML as DataManagerLoan
    participant API as LoanService

    User->>UI: Enter note and tap Submit
    UI->>VM: dispatch OnSubmit
    VM->>Repo: undoLoanApproval(loanId, LoanUndoApprovalRequest)
    Repo->>DML: dataManagerLoan.undoLoanApproval(loanId, noteRequest)
    DML->>API: POST /loans/{loanId}?command=undoApproval (body: note)
    API-->>DML: HttpResponse (success/failure)
    DML-->>Repo: return or throw on error
    Repo-->>VM: DataState.Success or DataState.Error
    VM-->>UI: update dialogState or emit NavigationBack
    UI-->>User: show success (navigate back) or error dialog
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • biplab1
  • revanthkumarJ
  • Nagarjuna0033

Poem

"I hopped through code with tiny paws,
Unwound an approval with gentle claws,
A note, a tug, a soft undo —
Back it goes, the loan bids adieu 🥕
— Rabbit dev, nibbling refs anew."

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 9.52% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: adding an undo approval screen for loans, which aligns with the PR's primary objective and the substantial new UI, routing, and ViewModel additions.

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

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 4

🧹 Nitpick comments (1)
core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosOutlinedTextField.kt (1)

516-530: Apply modifier at the container level to keep handle and field aligned.

On Line 517, the outer Box ignores the incoming modifier, while the text field uses it on Line 528. With caller padding/constraints, the drag handle and text field can drift out of alignment.

♻️ Suggested adjustment
-    Box(
-        modifier = Modifier
-            .fillMaxWidth(),
-    ) {
+    Box(
+        modifier = modifier.fillMaxWidth(),
+    ) {
         OutlinedTextField(
             value = value,
             onValueChange = { onValueChange(it) },
@@
-            modifier = modifier
+            modifier = Modifier
                 .fillMaxWidth()
                 .height(fieldMinHeight),
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosOutlinedTextField.kt`
around lines 516 - 530, The Box container is not applying the incoming modifier
while OutlinedTextField does, causing misalignment between the drag handle and
the field when callers supply padding/constraints; move or apply the incoming
modifier to the Box (instead of only to OutlinedTextField) so the same Modifier
passed into MifosOutlinedTextField is used on the container (Box) and keep
fieldMinHeight applied to the inner OutlinedTextField to preserve sizing—update
the Box usage and remove the duplicate modifier usage on OutlinedTextField to
ensure the handle and field remain aligned (refer to Box, OutlinedTextField,
modifier, and fieldMinHeight).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosOutlinedTextField.kt`:
- Around line 539-540: The resize handle in MifosOutlinedTextField uses
.size(DesignToken.sizes.iconAverage) with a pointerInput, which makes the touch
target too small; update the pointerInput hit area to meet accessibility
guidance by increasing the interactive area (e.g., use a larger size like
DesignToken.sizes.iconLarge or wrap the pointerInput with a minimum touch
target/padding modifier) while keeping the visual icon size unchanged if needed;
locate the call site with .size(DesignToken.sizes.iconAverage) and
pointerInput(Unit) and replace or augment it so the touch target is at least the
recommended 48.dp.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalRoute.kt`:
- Around line 22-28: The navigateToLoanUndoApprovalScreen navigation helper is
defined but never called, leaving LoanUndoApprovalRoute unreachable; wire this
navigation into the UI by adding a user-triggered callback that calls
navigateToLoanUndoApprovalScreen(loanId) from the existing entry points such as
loanAccountSummary or loanProfileAccountDestination (where the route is
registered and the function is imported), e.g., expose an onUndoApprovalClick or
include the call inside the relevant button/option handler so the NavController
uses LoanUndoApprovalRoute(loanId) to navigate when the user initiates
undo-approval.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalViewModel.kt`:
- Around line 31-37: The OnSubmit and OnRetry handlers call undoLoanApproval()
even when a request is already in flight, risking duplicate backend writes;
modify the handlers in LoanUndoApprovalViewModel (the branches handling
LoanUndoApprovalAction.OnSubmit and LoanUndoApprovalAction.OnRetry) to first
check the view state loading flag (e.g., isLoading/isUndoing) or an in-flight
guard and return early if a request is active, and ensure undoLoanApproval()
itself sets that guard (or state.isLoading) before starting the async work and
clears it on completion/error to prevent re-entrancy.
- Line 57: The dialog currently sets dialogState =
LoanUndoApprovalState.DialogState.Error(error.message.toString()), which can
render the literal "null" when error.message is null; update the dialogState
assignment in LoanUndoApprovalViewModel so it supplies a safe default (e.g., use
error.message ?: "Unknown error" or error.localizedMessage ?: "Unknown error")
instead of calling toString() on a nullable, so
LoanUndoApprovalState.DialogState.Error always receives a non-"null"
human-readable message.

---

Nitpick comments:
In
`@core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosOutlinedTextField.kt`:
- Around line 516-530: The Box container is not applying the incoming modifier
while OutlinedTextField does, causing misalignment between the drag handle and
the field when callers supply padding/constraints; move or apply the incoming
modifier to the Box (instead of only to OutlinedTextField) so the same Modifier
passed into MifosOutlinedTextField is used on the container (Box) and keep
fieldMinHeight applied to the inner OutlinedTextField to preserve sizing—update
the Box usage and remove the duplicate modifier usage on OutlinedTextField to
ensure the handle and field remain aligned (refer to Box, OutlinedTextField,
modifier, and fieldMinHeight).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 614b8863-b87e-4cb9-94d5-3b3fd9e40c9e

📥 Commits

Reviewing files that changed from the base of the PR and between 68a8040 and 501f560.

📒 Files selected for processing (12)
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repository/LoanAccountApprovalRepository.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanAccountApprovalRepositoryImp.kt
  • core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosOutlinedTextField.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/LoanUndoApprovalRequest.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerLoan.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/services/LoanService.kt
  • feature/loan/src/commonMain/composeResources/values/strings.xml
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/di/LoanModule.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalRoute.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalViewModel.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalViewModel.kt (2)

55-55: Function should be private.

undoLoanApproval() is only called from within handleAction(). Making it public exposes an internal implementation detail unnecessarily.

♻️ Suggested fix
-    fun undoLoanApproval() {
+    private fun undoLoanApproval() {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalViewModel.kt`
at line 55, The method undoLoanApproval() is public but only used internally
from handleAction(), so change its visibility to private: locate the
undoLoanApproval() function in LoanUndoApprovalViewModel and mark it private,
and ensure handleAction() (or any internal callers) still reference it
unchanged; run tests/compile to confirm no external usages rely on this method
being public.

91-103: Consider using data object for singleton sealed class members.

Kotlin 1.9+ introduces data object which provides better toString() output and consistent equals/hashCode behavior for singleton sealed members. This is a minor stylistic improvement.

♻️ Suggested changes
     sealed interface DialogState {
         data class Error(val message: String) : DialogState
-        object Loading : DialogState
+        data object Loading : DialogState
     }
 }

 sealed interface LoanUndoApprovalEvent {
-    object NavigationBack : LoanUndoApprovalEvent
+    data object NavigationBack : LoanUndoApprovalEvent
 }

 sealed interface LoanUndoApprovalAction {
     data class OnNoteChange(val note: String) : LoanUndoApprovalAction
-    object OnSubmit : LoanUndoApprovalAction
-    object OnRetry : LoanUndoApprovalAction
-    object OnNavigateBack : LoanUndoApprovalAction
+    data object OnSubmit : LoanUndoApprovalAction
+    data object OnRetry : LoanUndoApprovalAction
+    data object OnNavigateBack : LoanUndoApprovalAction
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalViewModel.kt`
around lines 91 - 103, Replace plain singleton objects with Kotlin 1.9+ data
objects for better toString/equals/hashCode: change object Loading (implementing
DialogState), object NavigationBack in LoanUndoApprovalEvent, and the singleton
members OnSubmit, OnRetry, OnNavigateBack of sealed interface
LoanUndoApprovalAction to use `data object` syntax; update their declarations
only (no behavior changes) so they remain singletons but gain data-object
semantics.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalViewModel.kt`:
- Around line 63-80: The when branch in LoanUndoApprovalViewModel handling
DataState.Loading is unreachable because repository.undoLoanApproval (called in
repository.undoLoanApproval(route.loanId, LoanUndoApprovalRequest(...))) is a
suspend function returning a single DataState value, so remove the
DataState.Loading -> Unit arm from the when expression and leave only the
DataState.Error and DataState.Success cases (or replace with a sealed when
without Loading), ensuring the when remains exhaustive or compile-clean.

---

Nitpick comments:
In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalViewModel.kt`:
- Line 55: The method undoLoanApproval() is public but only used internally from
handleAction(), so change its visibility to private: locate the
undoLoanApproval() function in LoanUndoApprovalViewModel and mark it private,
and ensure handleAction() (or any internal callers) still reference it
unchanged; run tests/compile to confirm no external usages rely on this method
being public.
- Around line 91-103: Replace plain singleton objects with Kotlin 1.9+ data
objects for better toString/equals/hashCode: change object Loading (implementing
DialogState), object NavigationBack in LoanUndoApprovalEvent, and the singleton
members OnSubmit, OnRetry, OnNavigateBack of sealed interface
LoanUndoApprovalAction to use `data object` syntax; update their declarations
only (no behavior changes) so they remain singletons but gain data-object
semantics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 59df63c8-c4af-44af-80f3-de8a3716b541

📥 Commits

Reviewing files that changed from the base of the PR and between 5c41f47 and a91eae5.

📒 Files selected for processing (3)
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repository/LoanAccountApprovalRepository.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanAccountApprovalRepositoryImp.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalViewModel.kt
🚧 Files skipped from review as they are similar to previous changes (2)
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanAccountApprovalRepositoryImp.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repository/LoanAccountApprovalRepository.kt

@Arinyadav1 Arinyadav1 requested a review from niyajali April 8, 2026 10:43
@Arinyadav1

Copy link
Copy Markdown
Member Author

@niyajali please review it again

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

♻️ Duplicate comments (3)
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalViewModel.kt (3)

67-68: ⚠️ Potential issue | 🟡 Minor

Avoid surfacing "null" as the error text.

Line 67 uses response.message, which can be the literal "null" when the throwable has no message.

Suggested fix
                 is DataState.Error -> {
+                    val message = response.exception.message?.takeIf { it.isNotBlank() }
+                        ?: "Something went wrong"
                     mutableStateFlow.update {
                         it.copy(
-                            dialogState = LoanUndoApprovalState.DialogState.Error(response.message),
+                            dialogState = LoanUndoApprovalState.DialogState.Error(message),
                         )
                     }
                 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalViewModel.kt`
around lines 67 - 68, The error state is being set with response.message which
can be the literal string "null"; update the LoanUndoApprovalViewModel code that
assigns LoanUndoApprovalState.DialogState.Error to sanitize the message (e.g.,
use response.message.takeIf { !it.isNullOrBlank() && it != "null" } ?:
response.throwable?.localizedMessage ?: "Unknown error") so we never surface the
string "null" — locate the assignment that constructs
LoanUndoApprovalState.DialogState.Error and apply this fallback/sanitization
logic.

79-79: ⚠️ Potential issue | 🟡 Minor

Remove unreachable DataState.Loading branch.

Line 79 is dead code here because repository.undoLoanApproval(...) is a suspend call returning one final DataState value.

Suggested fix
-                DataState.Loading -> Unit
             }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalViewModel.kt`
at line 79, In LoanUndoApprovalViewModel.kt, remove the unreachable
DataState.Loading -> Unit branch from the when that handles the result of
repository.undoLoanApproval(...) (inside the undo approval coroutine in the
ViewModel) since repository.undoLoanApproval is a suspend call that returns a
single final DataState; update the when to handle only the actual returned cases
(e.g., DataState.Success and DataState.Error) or use an exhaustive when/else if
needed, and clean up any unused imports or dead variables related to the Loading
branch.

55-63: ⚠️ Potential issue | 🟠 Major

Guard against duplicate in-flight undo requests.

undoLoanApproval() can be re-entered from retry/submit while already loading, which risks duplicate backend writes.

Suggested fix
-    fun undoLoanApproval() {
+    private fun undoLoanApproval() {
+        if (state.dialogState is LoanUndoApprovalState.DialogState.Loading) return
+
         mutableStateFlow.update {
             it.copy(
                 dialogState = LoanUndoApprovalState.DialogState.Loading,
             )
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalViewModel.kt`
around lines 55 - 63, The undoLoanApproval() function can be re-entered and send
duplicate requests while a previous undo is in-flight; add an early guard that
checks the current state (e.g., if state.dialogState ==
LoanUndoApprovalState.DialogState.Loading) and return immediately before
updating mutableStateFlow or launching the coroutine. In practice, read the
current state from mutableStateFlow or the state property at the top of
undoLoanApproval(), return if already Loading, otherwise proceed to set
dialogState to Loading and call repository.undoLoanApproval(...) inside
viewModelScope.launch; keep all existing state updates and error handling but
prevent re-entry to avoid duplicate backend writes.
🧹 Nitpick comments (1)
feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalScreen.kt (1)

67-96: Limit helper composable visibility to module scope.

LoanUndoApprovalDialog and LoanUndoApprovalContent look internal to this feature; consider marking them internal to avoid expanding public API surface unintentionally.

Suggested refactor
-@Composable
-fun LoanUndoApprovalDialog(
+@Composable
+internal fun LoanUndoApprovalDialog(
@@
-@Composable
-fun LoanUndoApprovalContent(
+@Composable
+internal fun LoanUndoApprovalContent(
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalScreen.kt`
around lines 67 - 96, Mark the feature-internal composables
LoanUndoApprovalDialog and LoanUndoApprovalContent as internal to restrict their
visibility to the module; update the function declarations for
LoanUndoApprovalDialog(...) and LoanUndoApprovalContent(...) to use the internal
modifier so they are not exposed as public API while leaving their parameters
and behavior unchanged.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@cmp-shared/cmp_shared.podspec`:
- Line 53: The spec.resources entry currently uses Windows backslashes which
break CocoaPods resolution; update the spec.resources value (the literal
'build\compose\cocoapods\compose-resources') to use POSIX separators
('build/compose/cocoapods/compose-resources') so CocoaPods can find the
compose-resources directory.

In
`@core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanAccountApprovalRepositoryImp.kt`:
- Around line 67-68: In undoLoanApproval(), avoid swallowing coroutine
cancellations by adding an explicit catch for
kotlin.coroutines.cancellation.CancellationException (or
java.util.concurrent.CancellationException) that immediately rethrows, before
the existing catch (e: Exception) block that returns DataState.Error(e); ensure
the catch order is: catch (ce: CancellationException) { throw ce } followed by
the broad catch that converts other exceptions to DataState.Error, referencing
the undoLoanApproval function and the existing DataState.Error(e) return to
locate where to change.

---

Duplicate comments:
In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalViewModel.kt`:
- Around line 67-68: The error state is being set with response.message which
can be the literal string "null"; update the LoanUndoApprovalViewModel code that
assigns LoanUndoApprovalState.DialogState.Error to sanitize the message (e.g.,
use response.message.takeIf { !it.isNullOrBlank() && it != "null" } ?:
response.throwable?.localizedMessage ?: "Unknown error") so we never surface the
string "null" — locate the assignment that constructs
LoanUndoApprovalState.DialogState.Error and apply this fallback/sanitization
logic.
- Line 79: In LoanUndoApprovalViewModel.kt, remove the unreachable
DataState.Loading -> Unit branch from the when that handles the result of
repository.undoLoanApproval(...) (inside the undo approval coroutine in the
ViewModel) since repository.undoLoanApproval is a suspend call that returns a
single final DataState; update the when to handle only the actual returned cases
(e.g., DataState.Success and DataState.Error) or use an exhaustive when/else if
needed, and clean up any unused imports or dead variables related to the Loading
branch.
- Around line 55-63: The undoLoanApproval() function can be re-entered and send
duplicate requests while a previous undo is in-flight; add an early guard that
checks the current state (e.g., if state.dialogState ==
LoanUndoApprovalState.DialogState.Loading) and return immediately before
updating mutableStateFlow or launching the coroutine. In practice, read the
current state from mutableStateFlow or the state property at the top of
undoLoanApproval(), return if already Loading, otherwise proceed to set
dialogState to Loading and call repository.undoLoanApproval(...) inside
viewModelScope.launch; keep all existing state updates and error handling but
prevent re-entry to avoid duplicate backend writes.

---

Nitpick comments:
In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalScreen.kt`:
- Around line 67-96: Mark the feature-internal composables
LoanUndoApprovalDialog and LoanUndoApprovalContent as internal to restrict their
visibility to the module; update the function declarations for
LoanUndoApprovalDialog(...) and LoanUndoApprovalContent(...) to use the internal
modifier so they are not exposed as public API while leaving their parameters
and behavior unchanged.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1ad7946f-4ada-4937-a4a3-d8f1de967b97

📥 Commits

Reviewing files that changed from the base of the PR and between 5a3c970 and 0b2ed83.

📒 Files selected for processing (8)
  • cmp-shared/cmp_shared.podspec
  • core/data/build.gradle.kts
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanAccountApprovalRepositoryImp.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/util/NetworkMonitor.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/LoanUndoApprovalRequest.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalRoute.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalViewModel.kt
✅ Files skipped from review due to trivial changes (2)
  • core/data/build.gradle.kts
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/LoanUndoApprovalRequest.kt
🚧 Files skipped from review as they are similar to previous changes (1)
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanUndoApproval/LoanUndoApprovalRoute.kt

Comment thread cmp-shared/cmp_shared.podspec
@Arinyadav1 Arinyadav1 requested a review from niyajali April 11, 2026 08:04
@biplab1

biplab1 commented Apr 13, 2026

Copy link
Copy Markdown
Contributor

@coderabbitai Improve PR title based on github.com/openMF/mobile-wallet/wiki/Commit-style-guide. Give us just the title.

@coderabbitai

coderabbitai Bot commented Apr 13, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

@biplab1: Based on the commit style guide (conventional commits format with lowercase present-tense summary), here is the improved PR title:

feat(loan): implement undo loan approval screen

@biplab1 biplab1 changed the title Implement undo approval screen feat(loan): Implement undo approval screen Apr 13, 2026
@niyajali

Copy link
Copy Markdown
Collaborator

@Arinyadav1 Why are we permitting users to access the undo approval screen when the loan account has not yet been approved?

@Arinyadav1

Arinyadav1 commented Apr 23, 2026

Copy link
Copy Markdown
Member Author

@niyajali This functionality will be implement when action UI will build and this is only undo approval screen.

In actions show undo approval screen action when user permitted to undo approval otherwise doesn't show undo approval action

Comment thread cmp-shared/cmp_shared.podspec
@Arinyadav1 Arinyadav1 requested a review from biplab1 April 27, 2026 15:25
@sonarqubecloud

Copy link
Copy Markdown

@biplab1

biplab1 commented May 15, 2026

Copy link
Copy Markdown
Contributor

@Arinyadav1 Please resolve the merge conflicts.

@Arinyadav1 Arinyadav1 force-pushed the Implement-Undo-Approval-Screen branch from 2387ab2 to 3f41f79 Compare June 1, 2026 18:18
@sonarqubecloud

sonarqubecloud Bot commented Jun 1, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants