Aman-Mittal opened a new pull request, #800:
URL: https://github.com/apache/fineract-backoffice-ui/pull/800

   Closes #770, closes #771, closes #772, closes #777.
   
   ## What and why
   
   Four of the eight open Working Capital issues. #773, #774, #775 and #776 are 
untouched and stay open.
   
   ### RBAC (#777)
   
   Every action route was gated on `UPDATE_WORKINGCAPITALLOAN` and every action 
button on the loan screen was rendered with no check at all. Fineract 
authorises each Working Capital command with its own code, and 
`UPDATE_WORKINGCAPITALLOAN` authorises none of them — the same defect term 
loans had in #691, so it failed in both directions: an approver holding 
`APPROVE_WORKINGCAPITALLOAN` was sent to `/forbidden`, while a user with only 
read access was still offered Approve, Disburse, Delete, Waive charge and the 
rest, each of which could only ever answer 403.
   
   `WC_LOAN_COMMAND_PERMISSIONS` now resolves the code from the `:command` 
segment, exactly as `LOAN_COMMAND_PERMISSIONS` does for term loans, and the 
charge, breach, near-breach and delinquency routes carry their own codes 
instead of the portfolio one. Every write control on the loan screen is gated — 
disabled with the missing code named, which is the shape this codebase uses for 
an action on the record already on screen.
   
   The two icon-only row actions (waive a charge, detach an originator) are 
**removed** rather than disabled. `appRequiresPermission` owns 
`attr.aria-label` to carry its explanation, so on a control whose only 
accessible name *is* an aria-label it erases that name the moment it grants. 
That is a latent limitation of the shared directive rather than something 
specific to this screen; worth fixing there separately, and noted here so the 
asymmetry is not read as an oversight.
   
   No code was guessed. The module documents the pairing endpoint by endpoint, 
and all 39 Working Capital codes are present in `scripts/permission-codes.json` 
— the catalogue snapshot `check-permission-codes.mjs` enforces.
   
   ### Modifying a submitted application (#770)
   
   **Edit** navigated to `loans/edit/:id`, which the route table did not 
declare, so it fell through to the wildcard. The route is added and serves 
`wc-loan-form` in edit mode: Fineract's `PUT` body is the `POST` body, so a 
separate screen for the same fields would be two places to change whenever the 
application shape does.
   
   It sends only the fields the user changed — `PUT` is a modification command 
and audits whatever it is handed, so posting the whole form back would log 
every field as modified on every save — and it withholds the form until the 
prefill arrives, rather than filling bindings that have already been checked 
(an `NG0100` in development, an inconsistent first paint in production, and an 
empty form that fills itself a moment later for the user).
   
   ### The missing transactions (#771, #772)
   
   Repayment was the only transaction the UI could post. Added, each offered 
only in a status the platform accepts it in: **prepay**, **goodwill credit**, 
**payout refund**, **credit balance refund**, **charge-off** and its undo, 
**write-off** and its undo, and **recovery payment**.
   
   - Defaults come from `GET …/transactions/template?command=…`. The payoff 
figure and the still-recoverable amount are the platform's own numbers — the 
template caps a recovery at `totalWrittenOff - totalRecovered`, so the figure 
it offers is one the API will accept where the gross written-off amount would 
be rejected.
   - Each request carries only the fields its command takes, because Fineract 
rejects a request with a parameter the command does not support: a stray amount 
left over from another branch of the form would turn a valid undo into a 400.
   - Write-off reasons come from the **product** template, which is where 
Fineract assembles `writeOffReasonOptions`; the transaction template carries 
only the charge-off ones. Without `READ_WORKINGCAPITALLOANPRODUCT` the reason 
list is simply absent, and the write-off still posts, because the reason is 
optional.
   - `prepay` posts `command=repayment`: Fineract has no prepay command, and a 
prepayment is a repayment — which is also why it maps to 
`REPAYMENT_WORKINGCAPITALLOAN` rather than a code of its own.
   - Status gates follow the module's documentation: a charge-off is a 
non-monetary tag that leaves the loan `ACTIVE`, while a written-off loan is 
locked to everything but a recovery payment, and undoing the write-off is 
refused while any recovery stands.
   
   ## Verification
   
   - `npm test` — 2151 unit tests pass across 299 files; working-capital is 102 
tests, up from 70. New coverage: the command-to-code map including each undo 
being separable from the action it reverses, the edit-mode prefill and 
changed-fields-only `PUT`, each transaction command's posted command and body, 
and the permission gating (an approver without `UPDATE` can approve; a 
read-only user has no enabled write control).
   - `npx playwright test --project=mocked 
e2e/working-capital-loan-actions.spec.ts` — 17/17 pass, covering each new 
command's `command` query parameter, the state-dependent menu, the edit route 
end to end and a read-only role's disabled controls. Two pre-existing tests in 
that file failed on this branch until the gating was corrected, and pass now.
   - `check-route-permissions`, `check-permission-codes`, `check-api-surface`, 
`check-icons`, `check-a11y-names`, `check-ui-primitives`, 
`check-template-text`, `check-responsive`, `check-nav-ids`, 
`check-translations`, `prettier --check`, `eslint` (no new suppressions) and 
`typecheck:e2e` all pass. Hindi stays at 100% coverage, reusing the wording 
already established for the term-loan equivalents.
   
   Not verified against a live backend: these endpoints are 
recent-Fineract-only, which is why this spec is mocked, as the file's header 
already notes.
   
   ## Screenshots
   
   Not applicable — no new screens; the loan screen gains menu entries and the 
existing application form gains an edit mode.
   
   ## Checklist
   
   - [x] I did not hand-edit generated files under 
`frontend/src/openapi-client/` (nor `src/app/api/`; `api-surface.json` was 
regenerated with `check-api-surface.mjs --write`).
   - [x] Backend code follows the feature and CQRS layout in AGENTS.md — not 
applicable, this is frontend-only; the new map sits beside the existing ones in 
`core/guards/`.
   - [x] I did not add entries to a lint or architecture baseline.
   - [x] User-facing strings use translation keys (14 new keys, `en` and `hi`).
   - [x] I added or updated tests appropriate to this change.
   - [x] UI workflow changes include suitable e2e coverage, including 
real-backend testing where relevant — mocked here, for the reason above.
   - [x] Commits are signed.
   - [x] I followed the AI-assisted contributions guidance.
   - [x] These are bug fixes and the UI side of endpoints the platform already 
exposes, raised as issues #770–#777 before this change.
   


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