Skip to content

feat(loan): implement create guarantor screen - #2698

Merged
revanthkumarJ merged 3 commits into
openMF:devfrom
sahilshivekar:create-guarantor
Jul 9, 2026
Merged

feat(loan): implement create guarantor screen#2698
revanthkumarJ merged 3 commits into
openMF:devfrom
sahilshivekar:create-guarantor

Conversation

@sahilshivekar

@sahilshivekar sahilshivekar commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Fixes - Jira-#683

Before

create_guarantor_before.mp4

After

create_guarantor_after.mp4

@sahilshivekar
sahilshivekar requested a review from a team July 8, 2026 11:36
@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

Walkthrough

Adds a create-guarantor flow across model, network, data, domain, and feature layers, including new screen and navigation wiring, plus removal of the Originators loan profile action and its strings.

Changes

Create Guarantor feature

Layer breakdown
Layer / File(s) Summary
Guarantor models and network layer
[CreateGuarantor.kt](core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantor.kt), [CreateGuarantorInput.kt](core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorInput.kt), [GuarantorTemplate.kt](core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/GuarantorTemplate.kt), [CreateGuarantorResponseDto.kt](core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/CreateGuarantorResponseDto.kt), [GuarantorRequestDto.kt](core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorRequestDto.kt), [GuarantorTemplateDto.kt](core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorTemplateDto.kt), [DataManagerLoan.kt](core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerLoan.kt), [LoanService.kt](core/network/src/commonMain/kotlin/com/mifos/core/network/services/LoanService.kt), [GetMakerCheckerResponse.kt](core/network/src/commonMain/kotlin/com/mifos/core/network/model/GetMakerCheckerResponse.kt)
Adds guarantor domain models and DTOs, three new loan guarantor endpoints, corresponding data manager methods, and changes loanId to Int? in GetMakerCheckerResponse.
Data mappers and repository
[GuarantorMapper.kt](core/data/src/commonMain/kotlin/com/mifos/core/data/mappers/loan/GuarantorMapper.kt), [LoanCreateGuarantorRepository.kt](core/data/src/commonMain/kotlin/com/mifos/core/data/repository/LoanCreateGuarantorRepository.kt), [LoanCreateGuarantorRepositoryImp.kt](core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanCreateGuarantorRepositoryImp.kt), [RepositoryModule.kt](core/data/src/commonMain/kotlin/com/mifos/core/data/di/RepositoryModule.kt)
Adds DTO-to-domain and input-to-DTO mappings, defines the guarantor repository contract and implementation, and registers it in Koin.
Domain use cases
[CreateGuarantorUseCase.kt](core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/CreateGuarantorUseCase.kt), [GetGuarantorTemplateUseCase.kt](core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/GetGuarantorTemplateUseCase.kt), [GetGuarantorAccountTemplateUseCase.kt](core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/GetGuarantorAccountTemplateUseCase.kt), [UseCaseModule.kt](core/domain/src/commonMain/kotlin/com/mifos/core/domain/di/UseCaseModule.kt)
Adds three guarantor use cases and registers them in the domain dependency graph.
Create Guarantor UI and navigation
[MifosSearchableDropdown.kt](core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosSearchableDropdown.kt), [CreateGuarantorScreen.kt](feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorScreen.kt), [CreateGuarantorScreenRoute.kt](feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorScreenRoute.kt), [CreateGuarantorViewModel.kt](feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorViewModel.kt), [LoanModule.kt](feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/di/LoanModule.kt), [LoanAccountActionNavigation.kt](feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionNavigation.kt), [LoanNavigation.kt](feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt), [strings.xml](feature/loan/src/commonMain/composeResources/values/strings.xml)
Adds the reusable searchable dropdown, the create-guarantor screen and route, viewmodel state/action handling, navigation registration, DI wiring, and new UI strings.
Remove Originators loan action
[LoanAccountProfileActionItem.kt](feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/components/LoanAccountProfileActionItem.kt), [LoanAccountProfileScreen.kt](feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt), [strings.xml](feature/loan/src/commonMain/composeResources/values/strings.xml), [strings.xml](feature/loan/src/commonMain/composeResources/values-es/strings.xml)
Removes the Originators action object, list entry, and related string resources.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

Create guarantor submission flow
sequenceDiagram
  participant User
  participant CreateGuarantorScreen
  participant CreateGuarantorViewModel
  participant CreateGuarantorUseCase
  participant LoanCreateGuarantorRepository

  User->>CreateGuarantorScreen: fill form and tap submit
  CreateGuarantorScreen->>CreateGuarantorViewModel: Submit action
  CreateGuarantorViewModel->>CreateGuarantorViewModel: validateInput
  CreateGuarantorViewModel->>CreateGuarantorUseCase: invoke(loanId, CreateGuarantorInput)
  CreateGuarantorUseCase->>LoanCreateGuarantorRepository: createGuarantor(loanId, input)
  LoanCreateGuarantorRepository-->>CreateGuarantorUseCase: DataState<CreateGuarantor>
  CreateGuarantorUseCase-->>CreateGuarantorViewModel: result
  CreateGuarantorViewModel-->>CreateGuarantorScreen: success/failure event + navigate back
Loading

Possibly related PRs

Suggested reviewers: revanthkumarJ, niyajali, Nagarjuna0033


Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Jira Link And Before/After Sections ❌ Error Jira link is present, but the Before/After sections are empty and contain no media. Add non-empty Before: and After: sections, each with at least one image/video, and keep the valid Jira link.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Title check ✅ Passed The title follows the required feat(scope): subject format and accurately summarizes the new guarantor screen work.
Description check ✅ Passed The description is related to the PR and references the same Jira-backed create guarantor flow.
✨ 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.

@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: 7

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

41-43: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Avoid non-trivial default modifier values.

When a caller passes their own modifier, the defaults (.clip(DesignToken.shapes.medium).fillMaxWidth()) are silently lost. The standard Compose convention is modifier: Modifier = Modifier with internal defaults applied in the composable body.

♻️ Proposed fix
 fun MifosSearchableDropdown(
     value: String,
     onValueChanged: (String) -> Unit,
     onOptionSelected: (Int, String) -> Unit,
     options: List<String>,
-    modifier: Modifier = Modifier
-        .clip(DesignToken.shapes.medium)
-        .fillMaxWidth(),
+    modifier: Modifier = Modifier,
     label: String? = null,
     enabled: Boolean = true,
     errorMessage: String? = null,
 ) {
     // ...
         OutlinedTextField(
             // ...
-            modifier = modifier.menuAnchor(
+            modifier = modifier
+                .clip(DesignToken.shapes.medium)
+                .fillMaxWidth()
+                .menuAnchor(
                 type = ExposedDropdownMenuAnchorType.PrimaryEditable,
                 enabled = enabled,
             ),
             // ...
         )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosSearchableDropdown.kt`
around lines 41 - 43, The default modifier chain in MifosSearchableDropdown is
non-trivial and causes caller-provided modifiers to override the built-in
clip/fill behavior. Update the MifosSearchableDropdown composable to use
modifier: Modifier = Modifier and apply DesignToken.shapes.medium clipping and
fillMaxWidth inside the composable body so the defaults are preserved alongside
any caller modifier.
core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorInput.kt (1)

14-29: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Remove API serialization concerns (dateFormat, locale) from the domain model.

dateFormat and locale are API transport details that leak into the domain model. The domain CreateGuarantorInput should represent business intent only; the mapper or DTO layer should supply dateFormat and locale defaults when constructing GuarantorRequestDto.

♻️ Proposed refactor: move API defaults to the mapper
 data class CreateGuarantorInput(
     val clientRelationshipTypeId: Long,
-    val dateFormat: String = "dd-MM-yyyy",
+    // dateFormat and locale removed — they are API concerns
     val entityId: Int? = null,
     val guarantorTypeId: Long,
-    val locale: String = DateConstants.LOCALE,
     val firstname: String? = null,
     val lastname: String? = null,
     val dateOfBirth: String? = null,
     val addressLine1: String? = null,
     val addressLine2: String? = null,
     val city: String? = null,
     val zip: String? = null,
     val mobileNumber: String? = null,
     val housePhoneNumber: String? = null,
 )

Then in GuarantorMapper.kt, supply the API defaults:

 fun CreateGuarantorInput.toDto(): GuarantorRequestDto {
     return GuarantorRequestDto(
         clientRelationshipTypeId = clientRelationshipTypeId,
-        dateFormat = dateFormat,
+        dateFormat = "dd-MM-yyyy",
         entityId = entityId,
         guarantorTypeId = guarantorTypeId,
-        locale = locale,
+        locale = DateConstants.LOCALE,
         firstname = firstname,
         lastname = lastname,
         dateOfBirth = dateOfBirth,
         addressLine1 = addressLine1,
         addressLine2 = addressLine2,
         city = city,
         zip = zip,
         mobileNumber = mobileNumber,
         housePhoneNumber = housePhoneNumber,
     )
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorInput.kt`
around lines 14 - 29, CreateGuarantorInput currently mixes domain data with API
transport defaults by carrying dateFormat and locale, so remove those fields
from the domain model and keep only business intent properties. Update the
GuarantorMapper path that builds GuarantorRequestDto to supply the API defaults
there instead, using the existing DateConstants values or equivalent mapper-side
defaults. Make sure any constructor calls or mappings referencing
CreateGuarantorInput are adjusted to match the slimmer model.
core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerLoan.kt (1)

16-16: 🗄️ Data Integrity & Integration | 🔵 Trivial | 💤 Low value

Move CreateGuarantorResponseDto into the network DTO package. CreateGuarantorResponseDto.kt is treated as a transport response alongside GuarantorRequestDto, GuarantorTemplateDto, and GuarantorAccountTemplateDto, so keeping it under core/model makes the layering inconsistent.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerLoan.kt`
at line 16, Move CreateGuarantorResponseDto out of the core model layer and into
the network DTO package so guarantor transport types are colocated with
GuarantorRequestDto, GuarantorTemplateDto, and GuarantorAccountTemplateDto.
Update the CreateGuarantorResponseDto definition and its import sites,
especially DataManagerLoan, to reference the new package path and keep the
network/data layering consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@core/domain/src/commonMain/kotlin/com/mifos/core/domain/di/UseCaseModule.kt`:
- Around line 92-93: `UseCaseModule` is missing Koin wiring for
`GetGuarantorAccountTemplateUseCase`, so add its import alongside the other
guarantor use cases and register it in the relevant module definitions where
`CreateGuarantorUseCase` and `GetGuarantorTemplateUseCase` are declared. Make
sure the symbol `GetGuarantorAccountTemplateUseCase` is included wherever the
guarantor use cases are bound so any ViewModel constructor injection can resolve
it successfully.

In
`@core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorResponseDto.kt`:
- Around line 14-19: Move CreateGuarantorResponseDto out of core/model because
it is a network response DTO and must not keep `@Serializable` in the domain
layer. Relocate the type to core/network/dto, then update
LoanService.createGuarantor() to return the relocated DTO and adjust
GuarantorMapper to map between CreatedGuarantor and the new response DTO. Keep
the domain model separate and ensure any imports/usages of
CreateGuarantorResponseDto point to the network package.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorScreen.kt`:
- Around line 267-296: The DatePicker dialog is embedded inline inside
CreateGuarantorContent, but it should be extracted into its own composable to
match the UI structure rules. Move the entire showDatePicker block, including
rememberDatePickerState, DatePickerDialog, and DatePicker, into a dedicated
composable such as CreateGuarantorDatePickerDialog, and pass in the needed
state/callbacks like state.dateOfBirthMillis, onAction, and the show/dismiss
handlers. Then call that composable from CreateGuarantorContent instead of
keeping the dialog logic inline.
- Around line 124-129: CreateGuarantorContent currently violates the Layer 2
contract by accepting a separate navigateBack lambda alongside onAction. Update
CreateGuarantorContent and its call sites so it only receives state and a single
onAction, and route back requests through a CreateGuarantorAction.Cancel (or
equivalent) instead of direct navigation. Then update the ViewModel handling for
that action to emit a CreateGuarantorEffect.NavigateBack, with the route
composable consuming the effect and performing the actual back navigation.
- Around line 132-138: Move the submit-enable logic out of CreateGuarantorScreen
and into the ViewModel/state layer. The relationship/client/name validation in
canSubmit is business logic, so add canSubmit to CreateGuarantorState and
compute it in the reducer inside the ViewModel’s handleAction whenever state
changes. Then update the composable to read state.canSubmit directly instead of
deriving it locally.

In
`@feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorViewModel.kt`:
- Around line 366-397: The `searchClients` flow collector in
`CreateGuarantorViewModel` is mutating state and sending UI events directly,
which breaks the MVI reducer pattern. Refactor
`searchRepository.searchResources(...).collect { ... }` so it only translates
each `DataState` result into internal actions via `sendAction(...)`, and move
the `mutableStateFlow.update` and
`sendEvent(CreateGuarantorEffect.ShowMessage(...))` logic into `handleAction`
for the corresponding action type. Keep the existing `searchClients` entry
point, but make it dispatch results instead of updating `searchedClientOptions`
itself.
- Around line 193-214: The non-existing-client flow in CreateGuarantorViewModel
lacks a reliable source for guarantorTypeId, so validateInput can only pass if
stale existing-client state is present. Update the existing-client toggle
handling to clear guarantorTypeId when switching away from existing client, and
add logic in the non-existing-client path to populate guarantorTypeId from the
appropriate guarantor template data so validation can succeed independently.

---

Nitpick comments:
In
`@core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosSearchableDropdown.kt`:
- Around line 41-43: The default modifier chain in MifosSearchableDropdown is
non-trivial and causes caller-provided modifiers to override the built-in
clip/fill behavior. Update the MifosSearchableDropdown composable to use
modifier: Modifier = Modifier and apply DesignToken.shapes.medium clipping and
fillMaxWidth inside the composable body so the defaults are preserved alongside
any caller modifier.

In
`@core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorInput.kt`:
- Around line 14-29: CreateGuarantorInput currently mixes domain data with API
transport defaults by carrying dateFormat and locale, so remove those fields
from the domain model and keep only business intent properties. Update the
GuarantorMapper path that builds GuarantorRequestDto to supply the API defaults
there instead, using the existing DateConstants values or equivalent mapper-side
defaults. Make sure any constructor calls or mappings referencing
CreateGuarantorInput are adjusted to match the slimmer model.

In
`@core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerLoan.kt`:
- Line 16: Move CreateGuarantorResponseDto out of the core model layer and into
the network DTO package so guarantor transport types are colocated with
GuarantorRequestDto, GuarantorTemplateDto, and GuarantorAccountTemplateDto.
Update the CreateGuarantorResponseDto definition and its import sites,
especially DataManagerLoan, to reference the new package path and keep the
network/data layering consistent.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 993e7c0a-4772-48a3-b9b8-bb085e2f7a8a

📥 Commits

Reviewing files that changed from the base of the PR and between 928fc44 and 7b9e75a.

📒 Files selected for processing (28)
  • core/data/src/commonMain/kotlin/com/mifos/core/data/di/RepositoryModule.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/mappers/loan/GuarantorMapper.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repository/LoanCreateGuarantorRepository.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanCreateGuarantorRepositoryImp.kt
  • core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosSearchableDropdown.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/di/UseCaseModule.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/CreateGuarantorUseCase.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/GetGuarantorAccountTemplateUseCase.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/GetGuarantorTemplateUseCase.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorInput.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorResponseDto.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreatedGuarantor.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/GuarantorTemplate.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerLoan.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorRequestDto.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorTemplateDto.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/model/GetMakerCheckerResponse.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/services/LoanService.kt
  • feature/loan/src/commonMain/composeResources/values-es/strings.xml
  • feature/loan/src/commonMain/composeResources/values/strings.xml
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorScreenRoute.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorViewModel.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/di/LoanModule.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionNavigation.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/components/LoanAccountProfileActionItem.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt
💤 Files with no reviewable changes (2)
  • feature/loan/src/commonMain/composeResources/values-es/strings.xml
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/components/LoanAccountProfileActionItem.kt
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: PR Checks / Static Analysis Check
🧰 Additional context used
📓 Path-based instructions (11)
**/{core-base,core}/**/*.kt

⚙️ CodeRabbit configuration file

**/{core-base,core}/**/*.kt: Critical Module Change Detection:

  • Changes in core-base module must be treated as high-impact.
  • Flag any PR that modifies files inside core-base for careful review.
  • Verify that modifications in core-base are necessary and minimal.
    Output:
  • Clearly highlight that core-base is a shared foundational module and requires extra review attention.

Files:

  • core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosSearchableDropdown.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/model/GetMakerCheckerResponse.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorResponseDto.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/CreateGuarantorUseCase.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/GetGuarantorTemplateUseCase.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorRequestDto.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/di/RepositoryModule.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorInput.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreatedGuarantor.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/GetGuarantorAccountTemplateUseCase.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/GuarantorTemplate.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repository/LoanCreateGuarantorRepository.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanCreateGuarantorRepositoryImp.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/di/UseCaseModule.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerLoan.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/mappers/loan/GuarantorMapper.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/services/LoanService.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorTemplateDto.kt
**/*.kt

⚙️ CodeRabbit configuration file

**/*.kt: Additional Code Review Guidelines:

  1. Null Safety & Stability
  • Avoid using !! operator
  • Handle null cases explicitly using safe calls or proper state handling
  • Do not assume values are always non-null without guarantees
  1. Architecture Boundaries
  • ViewModel must not depend on specific network/library implementations
  • Ensure proper separation between data, domain, and presentation layers
  • Do not format data (currency, dates, calculations) inside the UI layer
  • All formatting must be handled in the ViewModel and exposed via state (e.g., StateFlow)
  1. Performance Considerations
  • Avoid unnecessary recompositions in Compose
  • Do not attach heavy logic to frequently changing states (e.g., scrollState)
  • Prefer lifting state up instead of recomputing in child composables
  1. Compose & Navigation Best Practices
  • NEVER trigger navigation functions or side-effects directly during composition
  • Always wrap navigation calls inside LaunchedEffect or EventsEffect to avoid repeated execution on recomposition
  • Avoid triggering intensive side-effects during recomposition
  • Navigation routes must be type-safe.
  • Ensure all route classes or objects used for navigation are annotated with @Serializable.
  1. UI Structure
  • Dialogs must be separated into their own composables
  • Do not embed dialogs inline within complex main screens
  1. Localization Consistency
  • Ensure all supported languages are updated consistently across modules
  • Verify translations exist for newly added UI strings
  1. Code Cleanliness
  • Avoid unnecessary inline comments unless critical
  • Remove leftover debug or commented code
  1. Focus on correctness, readability, and maintainability over cosmetic nitpicks.
  • Avoid reviewing README, config, or asset files.
  • Prioritize identifying bugs, performance issues, and architectural concerns.
  1. Naming & Intent Rules:

Files:

  • core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosSearchableDropdown.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/model/GetMakerCheckerResponse.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorResponseDto.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/CreateGuarantorUseCase.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/GetGuarantorTemplateUseCase.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorRequestDto.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/di/LoanModule.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/di/RepositoryModule.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorInput.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreatedGuarantor.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/GetGuarantorAccountTemplateUseCase.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionNavigation.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/GuarantorTemplate.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repository/LoanCreateGuarantorRepository.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanCreateGuarantorRepositoryImp.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/di/UseCaseModule.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerLoan.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/mappers/loan/GuarantorMapper.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/services/LoanService.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorTemplateDto.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorScreenRoute.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorViewModel.kt
**/network/**/*.kt

⚙️ CodeRabbit configuration file

**/network/**/*.kt: Network Layer API Guidelines:

  • One-shot API calls MUST use suspend, return raw response T, and MUST NOT use Flow or DataState.
  • Streaming APIs MUST return Flow<T> and MUST NOT use suspend or DataState.

Files:

  • core/network/src/commonMain/kotlin/com/mifos/core/network/model/GetMakerCheckerResponse.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorRequestDto.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
  • core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorTemplateDto.kt
**/core/model/**/*.kt

⚙️ CodeRabbit configuration file

**/core/model/**/*.kt: Domain Model Rules (:core:model):

  • Classes defined in this module are strictly Domain Models.
  • They must be plain Kotlin data classes.
  • They MUST NOT contain network-specific annotations (e.g., @Serializable) or database-specific annotations (e.g., @Entity).
  • Rule: These are the ONLY models that should be passed to or used within ViewModels and UI Screens.
  • Flag: If a Domain model is used directly as an API request/response body or a Room database table.

Files:

  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorResponseDto.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorInput.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreatedGuarantor.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/GuarantorTemplate.kt
**/network/dto/**/*.kt

⚙️ CodeRabbit configuration file

**/network/dto/**/*.kt: DTO Rules (:core:network:dto):

  • Classes here are Data Transfer Objects (DTOs) used strictly for API communication.
  • Rule: DTOs MUST NOT be used in ViewModels, Screens, or the Domain layer.
  • Flag: If a DTO is returned directly by a Repository interface or used in UI state.

Files:

  • core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorRequestDto.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorTemplateDto.kt
**/data/repository/**/*.kt

⚙️ CodeRabbit configuration file

**/data/repository/**/*.kt: Repository Interface Guidelines:

  • One-shot operations MUST use suspend fun and return DataState<T>. MUST NOT use Flow.
  • Streaming operations MUST return Flow<DataState<T>> and MUST NOT use suspend.
  • Repository interfaces must consistently return Domain models (from :core:model) wrapped in DataState or Flow.
  • Flag: Any interface method that returns a DTO or an Entity.

Files:

  • core/data/src/commonMain/kotlin/com/mifos/core/data/repository/LoanCreateGuarantorRepository.kt
**/data/repositoryImp/**/*.kt

⚙️ CodeRabbit configuration file

**/data/repositoryImp/**/*.kt: Repository Implementation Guidelines:

  • MUST convert T -> DataState<T> for one-shot APIs, and Flow<T> -> Flow<DataState<T>> using .asDataStateFlow().
  • MUST perform network availability checks, handle exceptions, and apply appropriate dispatchers.
  • Repositories act as the boundary translator. They MUST use mappers to convert DTOs (from network) and Entities (from database) into Domain Models (from :core:model) before returning data.
  • Flag: If a repository implementation returns a raw DTO or Entity directly to the caller instead of a Domain model.

Files:

  • core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanCreateGuarantorRepositoryImp.kt
**/data/mappers/**/*.kt

⚙️ CodeRabbit configuration file

**/data/mappers/**/*.kt: Mapper Consistency Rules (:core:data:mappers):

  • All mapping logic MUST be centralized in this directory.
  • Allowed mappings:
    1. DTO -> Domain Model
    2. Entity <-> Domain Model
  • Flag: Any mapper functions found in any module outside of :core:data:mappers.

Files:

  • core/data/src/commonMain/kotlin/com/mifos/core/data/mappers/loan/GuarantorMapper.kt
**/*Screen.kt

⚙️ CodeRabbit configuration file

**/*Screen.kt: Screen architecture rules:

Each screen must follow a 2-layer structure:

  1. Layer 1 (Entry/Route Composable):

    • Function Name: Typically *ScreenRoute or the entry-point composable.
    • Responsibilities: Inject ViewModel (e.g., koinViewModel), take navigation lambdas, collect the StateFlow, and handle ViewModel events.
    • Logic: Should only handle ViewModel interaction, state collection, and triggering navigation in response to ViewModel events.
  2. Layer 2 (Stateful/Content Composable — *Screen or *ScreenContent):

    • Parameters: MUST only take state (the UI state object) and a single onAction lambda (e.g., onAction: (FeatureAction) -> Unit).
    • Responsibilities: Render the UI based strictly on the provided state.
    • Rule: MUST NOT pass multiple separate lambda functions for different UI interactions; consolidate them into the single onAction.
    • Constraint: Must NOT contain any business logic or ViewModel/Navigation references.

Internal/private helper composables (e.g., dialogs, sections, sub-components):

  • These are NOT subject to the single onAction rule.
  • They may accept specific, focused lambdas (e.g., onRetry: () -> Unit) or a narrowed onAction as appropriate.
  • However, they must NOT be passed the ViewModel or navigation controllers directly.

UI consistency:

  • Avoid hardcoded values (dp, sp, padding, fontSize, colors)
  • Use DesignToken, KptTheme, AppColors, MifosTypography for spacing, typography, and colors

Code quality:

  • Keep Composables small and readable
  • Avoid deeply nested UI

Flag:

  • Missing Layer 2 (*Screen/*ScreenContent) separation from the entry-point composable
  • Layer 2 (*Screen/*ScreenContent) receiving multiple separate lambdas instead of a single onAction
  • UI logic inside the entry-point composable
  • Business logic inside any Composable
  • Hardcoded strings instead of using string resources
  • Hardcoded dp/sp values
  • Direct styling instead of using DesignToken or KptTheme

Files:

  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorScreen.kt
**/composeResources/values*/strings.xml

⚙️ CodeRabbit configuration file

**/composeResources/values*/strings.xml: String resource conventions:

Naming:

  • All keys must follow:
    feature_{feature_name}_{ui_text_in_snake_case}

Examples:
"In Advance" → feature_loan_in_advance
"Outstanding" → feature_loan_outstanding

  • Avoid generic names like: title, text1, label
  • The suffix should be a short, readable representation of the UI text
  • Avoid multiple keys representing the same UI text
  • Keys must be lowercase and use snake_case

Flag:

  • Incorrect naming pattern
  • Generic or unclear key names
  • Duplicate keys for same UI text

Files:

  • feature/loan/src/commonMain/composeResources/values/strings.xml
**/*ViewModel.kt

⚙️ CodeRabbit configuration file

**/*ViewModel.kt: MVI architecture rules:

  • All new features must follow MVI
  • ViewModel must extend BaseViewModel
  • The ViewModel MUST maintain a single UI state (e.g., a single StateFlow)
    instead of multiple separate state variables.

Required:

  • Use *State, *Event, *Action
  • Naming must be consistent (FeatureViewModel, FeatureState, FeatureEvent, FeatureAction)
  • Follow unidirectional flow:
    Action → ViewModel → State → UI

Internal reducer/action architecture rules:

  • Async operations MUST NOT directly mutate UI state repeatedly inside
    Flow collectors, suspend callbacks, or repository result handlers.

  • Repository/network/database results MUST be converted into internal
    actions using sendAction(...).

  • handleAction(...) must act as the primary reducer responsible for:

    • state mutation
    • reducer-style state transitions
    • triggering follow-up actions
  • Large async methods must be split into:

    1. async collection layer
    2. internal action dispatching
    3. reducer/state handling
  • Avoid directly calling another business/data-loading method from
    repository collectors or async callbacks.
    Prefer dispatching follow-up internal actions instead.

Preferred pattern:
repository result
-> sendAction(...)
-> handleAction(...)
-> mutableStateFlow.update { ... }

Anti-pattern examples:
mutableStateFlow.update { ... } inside collect { }
fetchX() -> directly calls fetchY() inside async collector
large methods mixing:
- collection
- state mutation
- navigation
- business chaining

Flag:

  • Multiple mutableStateFlow.update {} calls inside collect { }
  • Direct state mutation inside async repository callbacks
  • Async methods performing both collection and reducer logic
  • Direct business-flow chaining from async collectors
  • Missing internal reducer actions for async results
  • Missing *State / *Event / *Action
  • ViewModel not...

Files:

  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorViewModel.kt
🧠 Learnings (4)
📚 Learning: 2026-02-06T13:15:16.968Z
Learnt from: sahilshivekar
Repo: openMF/android-client PR: 2603
File: feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanTransaction/LoanTransactionsViewModel.kt:43-106
Timestamp: 2026-02-06T13:15:16.968Z
Learning: Guideline: When a Kotlin function parameter is nullable (e.g., balance: Double?, currencyCode: String?, maximumFractionDigits: Int?) and downstream calls require a non-null value, add null-safety handling in all implementations. Specifically, avoid calling Currency.getInstance(currencyCode) with a possibly null currencyCode; provide a safe default (e.g., currencyCode ?: "$") or validate before use. Ensure all platform targets (Android/Desktop/Native) follow consistent null handling, and consider centralizing currencyCode normalization in the common layer if feasible. Add tests covering null currencyCode to prevent NPEs.

Applied to files:

  • core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosSearchableDropdown.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/model/GetMakerCheckerResponse.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorResponseDto.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/CreateGuarantorUseCase.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/GetGuarantorTemplateUseCase.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorRequestDto.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/di/LoanModule.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/di/RepositoryModule.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorInput.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreatedGuarantor.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/GetGuarantorAccountTemplateUseCase.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionNavigation.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/GuarantorTemplate.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repository/LoanCreateGuarantorRepository.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanCreateGuarantorRepositoryImp.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/di/UseCaseModule.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerLoan.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/mappers/loan/GuarantorMapper.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/services/LoanService.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorTemplateDto.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorScreenRoute.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorViewModel.kt
📚 Learning: 2026-04-01T05:03:14.323Z
Learnt from: kartikey004
Repo: openMF/mifos-x-field-officer-app PR: 2659
File: feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanDisbursement/LoanAccountDisbursementScreen.kt:190-195
Timestamp: 2026-04-01T05:03:14.323Z
Learning: In this repo, existing `SelectableDates` / `SelectableDates.isSelectableDate(utcTimeMillis: Long)` implementations use `Clock.System.now().toEpochMilliseconds()` (UTC epoch millis) for date-boundary checks. During PR reviews, do not flag these checks for not using a timezone-aware `LocalDate` start-of-day approach; treat it as an established project-wide pattern. If a change is desired, handle it as a coordinated project-wide improvement rather than as a per-PR review issue.

Applied to files:

  • core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosSearchableDropdown.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/model/GetMakerCheckerResponse.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorResponseDto.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/CreateGuarantorUseCase.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/GetGuarantorTemplateUseCase.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorRequestDto.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/di/LoanModule.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/di/RepositoryModule.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreateGuarantorInput.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreatedGuarantor.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/GetGuarantorAccountTemplateUseCase.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionNavigation.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt
  • core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/GuarantorTemplate.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repository/LoanCreateGuarantorRepository.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanCreateGuarantorRepositoryImp.kt
  • core/domain/src/commonMain/kotlin/com/mifos/core/domain/di/UseCaseModule.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/datamanager/DataManagerLoan.kt
  • core/data/src/commonMain/kotlin/com/mifos/core/data/mappers/loan/GuarantorMapper.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/services/LoanService.kt
  • core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorTemplateDto.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorScreen.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorScreenRoute.kt
  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorViewModel.kt
📚 Learning: 2026-02-16T08:26:18.398Z
Learnt from: kartikey004
Repo: openMF/android-client PR: 2610
File: core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/theme/DesignToken.kt:328-337
Timestamp: 2026-02-16T08:26:18.398Z
Learning: In core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/theme/DesignToken.kt, ensure size tokens in AppSizes use raw dp-based names like dp5, dp18, dp20, dp42, dp48, dp72, dp100, dp120, dp128, etc., rather than relying solely on semantic names. This naming convention should be accepted for design token definitions in this file and should guide future token definitions without requiring semantic aliases.

Applied to files:

  • core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosSearchableDropdown.kt
📚 Learning: 2026-03-16T11:58:32.496Z
Learnt from: sahilshivekar
Repo: openMF/mifos-x-field-officer-app PR: 2647
File: feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt:96-96
Timestamp: 2026-03-16T11:58:32.496Z
Learning: In feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt (Kotlin/Compose Multiplatform), navigateToDashboard uses a direct method reference navController::navigateToLoanDashboardScreen without an ID guard. This is intentional: LoanAccountProfileScreen always provides a valid loanId, and LoanDashboardScreen handles invalid/missing data by showing a 'Failed to fetch Loan details' error state. Do not flag the absence of an ID guard here in future reviews.

Applied to files:

  • feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt
🔇 Additional comments (21)
core/designsystem/src/commonMain/kotlin/com/mifos/core/designsystem/component/MifosSearchableDropdown.kt (1)

48-119: LGTM!

feature/loan/src/commonMain/composeResources/values/strings.xml (1)

701-718: LGTM!

feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorScreen.kt (1)

72-120: LGTM!

feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/navigation/LoanNavigation.kt (1)

21-22: LGTM!

Also applies to: 71-74, 133-133

feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountProfile/LoanAccountProfileScreen.kt (1)

120-129: LGTM!

Also applies to: 384-384

feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/createGuarantor/CreateGuarantorScreenRoute.kt (1)

17-32: LGTM!

feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/di/LoanModule.kt (1)

13-13: LGTM!

Also applies to: 51-51

feature/loan/src/commonMain/kotlin/com/mifos/feature/loan/loanAccountAction/LoanAccountActionNavigation.kt (1)

27-27: LGTM!

Also applies to: 47-47

core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/CreatedGuarantor.kt (1)

12-16: LGTM!

core/model/src/commonMain/kotlin/com/mifos/core/model/objects/account/loan/guarantor/GuarantorTemplate.kt (1)

12-34: LGTM!

core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorRequestDto.kt (1)

14-31: LGTM!

core/network/src/commonMain/kotlin/com/mifos/core/network/dto/loans/GuarantorTemplateDto.kt (1)

13-39: LGTM!

core/network/src/commonMain/kotlin/com/mifos/core/network/services/LoanService.kt (1)

100-114: Endpoints follow network layer guidelines correctly.

All three new guarantor endpoints are suspend functions returning raw DTOs without Flow or DataState, consistent with the one-shot API call rules. The @GET/@POST/@Path/@Body/@Query annotations are correct for Ktorfit. The CreateGuarantorResponseDto placement issue is already flagged in DataManagerLoan.kt.

core/data/src/commonMain/kotlin/com/mifos/core/data/repository/LoanCreateGuarantorRepository.kt (1)

18-31: LGTM!

core/data/src/commonMain/kotlin/com/mifos/core/data/mappers/loan/GuarantorMapper.kt (1)

25-28: 🗄️ Data Integrity & Integration

No missing GuarantorTemplate fields

GuarantorTemplateDto and GuarantorTemplate both only expose allowedClientRelationshipTypes, so this mapper is complete as written.

			> Likely an incorrect or invalid review comment.
core/network/src/commonMain/kotlin/com/mifos/core/network/model/GetMakerCheckerResponse.kt (1)

67-67: 🗄️ Data Integrity & Integration

loanId as Int? is fine here
The surrounding loan DTOs already model loanId as Int, so this change doesn’t introduce a caller-side mismatch.

			> Likely an incorrect or invalid review comment.
core/data/src/commonMain/kotlin/com/mifos/core/data/repositoryImp/LoanCreateGuarantorRepositoryImp.kt (1)

25-68: LGTM!

core/data/src/commonMain/kotlin/com/mifos/core/data/di/RepositoryModule.kt (1)

50-50: LGTM!

Also applies to: 121-121, 205-205

core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/CreateGuarantorUseCase.kt (1)

17-24: LGTM!

core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/GetGuarantorAccountTemplateUseCase.kt (1)

16-28: LGTM!

core/domain/src/commonMain/kotlin/com/mifos/core/domain/useCases/createGuarantor/GetGuarantorTemplateUseCase.kt (1)

16-22: LGTM!

@sonarqubecloud

sonarqubecloud Bot commented Jul 9, 2026

Copy link
Copy Markdown

@revanthkumarJ
revanthkumarJ merged commit 4482d73 into openMF:dev Jul 9, 2026
10 checks passed
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.

2 participants