priyam99 opened a new pull request, #169:
URL: https://github.com/apache/fineract-loan-origination/pull/169

   ## Description
   
   Invalid loan lifecycle actions returned `500 Internal Server Error` instead 
of `409 Conflict`.
   
   `LoanOriginationStateMachine.transition()` throws 
`LoanStateTransitionException` when a transition is not allowed (for example, 
submitting an `APPROVED` application). `GlobalExceptionHandler` had no handler 
for it, so it fell through to the generic `Exception` handler and was reported 
as a server error. The REST API docs (`docs/api/rest-api.adoc`) and the backend 
architecture doc already specify `409` for invalid transitions.
   
   This PR adds a `LoanStateTransitionException` handler that returns `409 
Conflict` with the standard `ErrorResponse` (`status`, `error`, `message`, 
`timestamp`), next to the existing `409` handlers. No other behaviour changes. 
Terminal-state attempts already returned `409` through the existing 
`IllegalStateException` handler and are unaffected.
   
   Closes #162
   
   ## Verification
   
   - [x] `./mvnw spotless:apply`
   - [x] `./mvnw clean verify`: build succeeds. 190 unit tests (including the 4 
new ones) and 7 Cucumber integration tests (Testcontainers PostgreSQL) pass 
with 0 failures, and the Spotless check passes.
   - [x] `./mvnw apache-rat:check`
   - [x] Frontend changes: not applicable, because there are no frontend 
changes.
   
   New tests:
   - `GlobalExceptionHandlerTest`: `LoanStateTransitionException` maps to `409` 
with the transition message.
   - `LoanApplicationControllerTest` (MockMvc with the real service and state 
machine, mocked repositories):
     - `APPROVED` → submit returns `409`, the status stays `APPROVED`, and 
nothing is saved.
     - `DRAFT` → start-review returns `409`, the status stays `DRAFT`, and 
credit scoring is not triggered.
     - `DRAFT` → submit still returns `200` with status `SUBMITTED`.
   
   I also confirmed the two `409` tests fail with `500` when the new handler is 
removed.
   
   ## AI assistance (optional)
   
   - Tool / model: Claude Code (Claude Opus 5.5)
   - How it was used: traced the exception path, drafted the handler and tests, 
and ran the checks. I reviewed every line.
   
   ## Checklist
   
   - [x] This PR is one logical change, not a code dump.
   - [x] I added or updated tests, or explained why tests are not needed.
   - [x] New files carry the ASF license header.
   - [x] Docs (and `AGENTS.md`, if commands, paths, or architecture rules 
changed) are updated. (No doc change needed; the docs already specify `409`.)
   - [x] All commits are signed.
   - [x] I followed the [AI 
Policy](https://github.com/apache/fineract/blob/develop/CONTRIBUTING.md#ai-policy)
 and the [ASF Generative Tooling 
Guidance](https://www.apache.org/legal/generative-tooling.html).
   


-- 
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]

Reply via email to