Thank you for your interest in contributing! This is a back-office web client for Apache Fineract.
Use this repository's GitHub Issues for anything about the web UI — a screen that renders wrongly, a form that will not submit, a missing field.
Bugs in the platform itself belong in the ASF Jira project for apache/fineract: wrong balances, rejected API payloads, scheduler or accounting behaviour — anything the back end decides. A useful rule of thumb is the network tab: if the request succeeded and the screen is still wrong, it is a UI issue; if Fineract returned a 4xx with a defaultUserMessage explaining why, start with Jira.
Fork the repository on GitHub.
Clone your fork locally.
Create a feature branch for your changes.
Implement your changes, following the Code Style Guide.
Run local checks:
npm run lintnpm run format:checknpm test -- --watch=false — the Vitest unit suitenpm run buildnpm run check:icons — every <ion-icon name="..."> is registerednpm run i18n:check — translations are completeEnsure License Headers: All new files must include the Apache License 2.0 header. You can verify this with ./scripts/check-license.sh.
Every check that runs on a pull request — what it enforces, how to reproduce a failure locally, and the rules that most often surprise people — is documented in DOCS/CI_CHECKS.md.
Submit a Pull Request against the main branch.
Playwright specs live in e2e/, one file per use case. Most run against page.route() mocks and need no backend. The loan specs (loan-*.spec.ts, full-demo.spec.ts) drive a real Fineract instance and read their target from FINERACT_SERVER_URL.
To run the full suite against a self-contained backend:
docker compose -f deploy/docker-compose-e2e.yml up -d --wait fineract-db docker exec -i fineract-db psql -U postgres < deploy/init-db.sql docker compose -f deploy/docker-compose-e2e.yml up -d fineract-backend # wait for https://localhost:8443/fineract-provider/actuator/info to return 200 FINERACT_SERVER_URL=/fineract-provider/api/v1 npm run test:e2e -- --project=chromium
Point FINERACT_SERVER_URL at the relative proxy path, not https://localhost:8443. proxy.conf.json forwards /fineract-provider to the backend, which keeps the browser same-origin — no CORS preflight and no self-signed certificate prompt.
The same flow runs in CI via .github/workflows/e2e.yml. See DOCS/E2E_TESTING.md for writing specs, and prefer data-testid over element selectors so tests survive markup changes.
Once the backend above is up, npm run seed:demo-data populates it with a representative dataset — an office, staff, a center, a group, an active loan, a loan pending approval, a savings account, a fixed deposit, a share account, a manual journal entry and two reports — for manual sanity testing rather than the narrow fixtures an individual spec builds for itself. It prints what it created. This is its own Playwright project (demo-seed), so it never runs as a side effect of the backend project in CI.
Unit tests use Vitest and are named *.test.ts. Run the application suite with npm test -- --watch=false or npm run test:unit.
Use vi.fn() for mocks and expect for assertions. describe, it, expect and vi are globals. For a mocked service, use SpyObj<T> and createSpyObj<T>([…]) from src/app/testing/mocks.ts.
Background on the completed migration: DOCS/adr/0004-vitest-migration.md.
The UI layer is Ionic (@ionic/angular v8), configured in mode: 'md'.
Angular Material is being removed and must not be used in new code. If you touch a component that still imports @angular/material, migrate it as part of your change where the scope is reasonable. The Code Style Guide has the component-by-component equivalents, the date-picker and event idioms, and the icon registry rules.
Two conventions are easy to miss and fail silently:
src/app/core/icons.ts, or it renders as blank space. npm run check:icons turns that into a build failure.provideIonicTesting() in their TestBed, or they fail with NG0201: No provider found for _ModalController.@angular/cdk is retained deliberately — use it for unstyled primitives (cdk-table, virtual scroll, a11y) rather than reaching back to Material.
Angular Material has been fully removed. npm run lint fails on any import of @angular/material, so it cannot come back by accident.
New runtime dependencies must be Apache Category A compatible. CI enforces the allowlist MIT;Apache-2.0;BSD-2-Clause;BSD-3-Clause;ISC;0BSD via license-checker; anything GPL/LGPL/AGPL or SSPL will fail the build. Declare packages you import directly in package.json rather than relying on transitive resolution, so the audit sees them.
main requires signed commits — an unsigned commit cannot be merged. Set this up before you start work, not after.
git config user.signingkey <your-gpg-key-id> git config commit.gpgsign true
commit.gpgsign true makes signing automatic for every commit, so it isn‘t a flag you have to remember. See GitHub’s docs for full setup instructions: commit signature verification.
If you already have unsigned commits on your branch, sign them retroactively instead of starting over:
git rebase --exec 'git commit --amend --no-edit -S' <base-branch>