Aman-Mittal opened a new issue, #756: URL: https://github.com/apache/fineract-backoffice-ui/issues/756
### Summary Save buttons don't guard against a second click while the first request is in flight. One double-click submits the form twice. On the loan **Repayment** form both requests succeeded, so **two repayments were posted for one payment**. The same happened on **Create Client** (two clients created) and on loan **Approve** (second request refused only because the loan was already approved). ### Environment - App: https://aman-mittal.github.io/fineract-backoffice-ui (deployed `main`) - Backend: `sandbox.mifos.community`, tenant `default` (demo server, test data prefixed `E2E-AUDIT-20261016`) - Role: superuser - Chrome (Playwright) 1440×900, 2026-10-16 ### Preconditions An active loan. Here: loan `000000002` (product `E2E-AUDIT-20261016 Monthly Loan`, 10,000 disbursed) for client `E2EAudit ClientOne`. ### Steps to reproduce 1. Open the loan → **Repayment**. 2. Enter amount `100`, choose a payment type. 3. **Double-click** Save. ### Expected behavior Exactly one `POST /loans/{id}/transactions?command=repayment`. The Save button is disabled (with a busy indicator) from the first click until the response arrives. ### Actual behavior Two POSTs, both **200**: ``` POST /loans/2/transactions?command=repayment → 200 resourceId 5 POST /loans/2/transactions?command=repayment → 200 resourceId 6 ``` `GET /loans/2?associations=transactions` afterwards: two `Repayment` transactions of 100.00 on 2026-10-15, `summary.totalRepayment = 200`, outstanding reduced by 200. The same pattern, one double-click each: | Form | Requests | Outcome | |---|---|---| | Create Client (`/clients/create`, step 3) | `POST /clients` ×2 → **200, 200** | Two clients created (ids 3 and 4, both "E2EAudit DoubleSubmit") | | Loan Approve (`/products/loan/2/action/approve`) | `POST /loans/2?command=approve` → 200, then → **400** | Second refused by the platform only because the state had changed | | Loan Repayment | ×2 → **200, 200** | Double-posted payment | ### Evidence Request/response pairs above, captured from the browser's network events. The duplicate repayment (#6) was reversed afterwards via Adjust Transaction (amount 0) to restore the loan. ### Impact - **Financial integrity.** A cashier who double-clicks, or clicks again because the UI looked unresponsive, posts the payment twice. The borrower's balance and the GL are both wrong, and someone has to notice and reverse it. Deposits, withdrawals, disbursement-to-savings and transfers all go through the same kind of form and are presumably affected in the same way (not individually tested). - **Duplicate master data.** Duplicate clients break KYC uniqueness and reporting. - Commands guarded by a state transition (approve, disburse) are protected by the platform by accident. Monetary transactions aren't, because each one is valid on its own. ### Suggested investigation A shared fix at the form or button level: an `inFlight` signal that disables the submit control from click until the request completes or fails, plus ignoring re-entrant submits in the submit handler (Enter key, programmatic clicks). Ideally it lives in a shared submit-button primitive (see #684) so every form gets it. For monetary commands, consider sending a client-generated idempotency key where Fineract supports it (`Idempotency-Key` header on command endpoints in recent versions), so a retry can't double-post even across network retries. ### Verification status Reproduced on three forms. Deposit, withdrawal and transfer forms not individually tested. ### Related endpoints `POST /loans/{id}/transactions?command=repayment`, `POST /clients`, `POST /loans/{id}?command=approve`, and by extension every command endpoint. ### Acceptance criteria - A double-click (and Enter pressed twice) on any create, command or transaction form produces exactly one request. - The submit control shows a busy state and is disabled while a request is in flight, and re-enabled on error. - An e2e test double-clicks Save on the repayment form and asserts a single `POST`. ### Related issues #684 (shared UI primitives). -- 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]
