Aman-Mittal opened a new pull request, #801:
URL: https://github.com/apache/fineract-backoffice-ui/pull/801
Follow-up to #800, which is merged. Two things that PR left open, plus a
defect only a real backend surfaced.
## What and why
### The permission gate erased accessible names (a11y)
`appRequiresPermission` carried its "requires X" explanation on `attr.title`
and `attr.aria-label` through host bindings of the form `granted() ? null :
hint()`. A host binding applies *after* the element's own bindings, so the
`null` branch did not mean "leave it alone" — it removed whatever the template
had set. On a control whose only accessible name *is* its own aria-label, an
icon-only button, granting the permission left a button with no name at all for
anyone using a screen reader.
Both attributes are now written imperatively and only while refusing, and
the host's own values are restored when the permission arrives. Nothing changes
for the common case of a button named by its visible text, and the refused
state is unchanged: the hint is still the accessible name, which is deliberate
and documented.
#800 worked around this by *removing* the Working Capital waive-charge and
detach-originator row actions instead of disabling them. This restores the
intended form — disabled, with the missing code named — for both.
### Working Capital against a real Fineract
The mocked spec proves the screen posts the right command with the right
body. It cannot prove the platform accepts any of it: the request shapes, the
status gates and the order commands must be issued in are all the backend's
rules, and a mock agrees with whatever the client believes. Two backend specs
now close that gap.
**`working-capital-rbac-backend.spec.ts`** seeds a role holding *exactly
one* permission and sends each command with an empty body. Fineract authorises
before it validates or looks the loan up, so the status discriminates — 403
means the code does not authorise the command, anything else means it does. The
result is a clean diagonal: all seventeen pairs the UI declares are authorised
by their own code, and `UPDATE_WORKINGCAPITALLOAN` authorises **none** of them.
That is #777's premise, now evidence rather than inference from the module's
documentation. It is also the probe that established the term-loan map in #691,
so the two maps are now held to the same standard.
**`working-capital-loan-actions-backend.spec.ts`** seeds a real product,
client and disbursed loan, drives charge-off, goodwill credit and write-off
through the screen, and reads the loan back from the platform: charged off and
still `ACTIVE` (the tag is non-monetary), outstanding reduced,
`CLOSED_WRITTEN_OFF` with the recovery path open and no second write-off
offered.
`seed-api.ts` gains the two seeders. Their payloads were arrived at by
posting and reading the validation errors back, and the comments record what
the platform insisted on, none of which is guessable from the field names:
`paymentAllocation` must cover all six allocation types, `npvDayCount` is
mandatory under `EIR`, the product refuses a `repaymentEvery` override from the
loan, `approve` requires `expectedDisbursementDate` and `disburse` requires
`transactionAmount`.
### A defect the mock could not catch
The real backend answers the transaction template fast enough for the
response to land inside the first change-detection pass, so prefilling the
action form's request wrote to bindings that had already been checked —
`NG0100` in development, and in production an amount that appears a frame after
the field it belongs to. The form now withholds itself until the template
answers, as the application form already does after #800. The mocked spec never
saw this because its catch-all route returns `{}`, so there was nothing to
prefill.
## Verification
- `npm test` — 2156 unit tests pass across 299 files. Four new ones pin the
directive: the host's own name is left alone when granted, gives way to the
hint while refused, comes back when the permission arrives, and is not invented
for a control that never had one.
- `npx playwright test --project=backend
e2e/working-capital-*-backend.spec.ts` — 6 pass in 52s against
`apache/fineract:latest` from `deploy/docker-compose-e2e.yml`, and the `NG0100`
is gone.
- `npx playwright test --project=mocked
e2e/working-capital-loan-actions.spec.ts` — 17 pass, including the two tests
that locate the restored row actions by accessible name.
- `npx playwright test --project=mocked e2e/rbac-feature-flag.spec.ts
e2e/rbac-route-protection.spec.ts` — 29 pass, exercising the changed directive
across the rest of the application.
- All thirteen repo checks, `eslint` (no new suppressions), `prettier
--check` and `typecheck:e2e` pass.
One note for whoever next regenerates `scripts/permission-codes.json`: the
live catalogue on today's image has 707 codes against the snapshot's 720, so
the snapshot has drifted in both directions. Every code this UI names is
present live — I checked all 27 — so nothing here depends on it, but the
snapshot is due a refresh.
## Screenshots
Not applicable — no visual change. The only user-visible difference is that
a refused icon-only button is disabled with a reason rather than absent.
## Checklist
- [x] I did not hand-edit generated files under `src/app/api/`.
- [x] Backend code follows the feature and CQRS layout in AGENTS.md — not
applicable; frontend and e2e only.
- [x] I did not add entries to a lint or architecture baseline.
- [x] User-facing strings use translation keys — no new strings.
- [x] I added or updated tests appropriate to this change.
- [x] UI workflow changes include suitable e2e coverage, including
real-backend testing where relevant — that is most of this PR.
- [x] Commits are signed.
- [x] I followed the AI-assisted contributions guidance.
- [x] Bug fix and test work, so the dev-list-first rule for features 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]