ayushcodes27 opened a new pull request, #204:
URL: https://github.com/apache/fineract-consumer-facing/pull/204
## What and why
Transfers from a customer's savings account to their own loan account
currently lack server-side validation against the loan's outstanding balance,
allowing overpayments that require manual backoffice approval to credit back.
This PR adds validation in the BFF transfers command service to enforce
payment limits against the loan's current outstanding balance
(`totalOutstanding`) and active status:
- Verifies ABAC resource ownership first before querying the loan, avoiding
unauthorized lookups or leaking loan state to non-owners.
- Validates loan status (`active == true`) and balance (`amount <=
totalOutstanding`) during `initiate` (preventing step-up OTP issuance for
invalid amounts) and re-validates during `confirm` (guarding against balance
changes during the OTP window).
- Rejects overpayments with HTTP 422 `TransferLoanOverpaymentException` and
inactive/zero-balance loans with HTTP 422 `TransferLoanNotActiveException`.
- Adds i18n error translations for English and Hindi.
Closes #114
> [!NOTE]
> **Design Considerations:**
> - **Accrual considerations:** The limit is based on
`loan.summary.totalOutstanding`. Note that this has not been benchmarked
against products with complex mid-cycle daily interest recalculations or
early-foreclosure fees.
> - **Configurability:** Currently enforced as a standard domain rule
capping repayments at `totalOutstanding`. Happy to make this configurable per
product or via application property if maintainers prefer allowing intentional
prepayment on specific products.
## Verification
- Ran `TransfersCommandServiceImplTest` (28 unit tests passing):
- `initiate` and `confirm` allow transfers where amount < outstanding.
- Symmetrical boundary tests where amount == outstanding pass at both
`initiate` and `confirm`.
- Amount > outstanding throws `TransferLoanOverpaymentException` at
`initiate` (verifying no OTP or step-up token is issued) and at `confirm`
(verifying no upstream call).
- Inactive loans and zero-balance loans throw
`TransferLoanNotActiveException` at both phases.
- Unowned loans fail ownership check first with
`TransferAccessDeniedException` without calling `LoansQueryService`.
- Ran `ModulithArchitectureTest`
(`ApplicationModules.of(ConsumerApplication.class).verify()`): PASSED.
- Ran `CodingConventionsArchitectureTest` (ArchUnit conventions): PASSED.
- Validated JSON syntax for `en.json` and `hi.json`: PASSED.
## Screenshots
Not applicable (backend validation & error code translations).
## AI assistance (optional)
- Tool / model: Gemini
- Harness / workflow: Assisted in workflow testing, code reviews, debugging,
and end-to-end validation.
## Checklist
- [x] I did not hand-edit generated files under
`frontend/src/openapi-client/`.
- [x] Backend code follows the feature and CQRS layout in
[AGENTS.md](AGENTS.md#backend-conventions-consumer) (command and query sides,
module boundaries); frontend code goes through the adapters in
`frontend/src/app/core/adapters/`.
- [x] I did not add entries to a lint or architecture baseline
(suppressions, frozen violations) to get the build passing.
- [x] User-facing strings use translation keys.
- [x] I added or updated tests appropriate to this change, or explained why
tests were not needed.
- [x] UI workflow changes include suitable e2e coverage, including
real-backend testing where relevant.
- [x] Commits are signed — see [Signing your
commits](CONTRIBUTING.md#signing-your-commits) in CONTRIBUTING.md.
- [x] I followed the [AI-assisted contributions
guidance](CONTRIBUTING.md#ai-assisted-contributions).
- [x] If this adds a feature or changes what a consumer can see or do, I
raised it on
[[email protected]](https://lists.apache.org/[email protected])
first, or it is a bug fix, refactor or test change, where that does not apply.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]