Cosmic Module

O

Qubits of DPK

March 20, 2026

Core Open Source

Group E — Build, Test & Utilities

These modules aren't financial products — they're the scaffolding that holds the entire project together: build packaging, documentation, testing infrastructure, and test runners.

1. fineract-war

What it is

The deployment packaging module — combines all other modules into a single deployable application file.

Layman Analogy

All the other modules are like individual LEGO bricks. fineract-war is the finished LEGO set — it assembles all pieces into one complete thing that can be deployed to a server.

What is a WAR/JAR?

  • WAR (Web Application Archive): Old Java web app packaging for Tomcat/JBoss
  • Fat JAR (also called uber-JAR): Single executable file with all dependencies included
  • Fineract builds a fat JAR via Spring Boot: fineract.jar

Build Output

bash
QUBITS OF DPK
1./gradlew :fineract-war:bootJar
2# Produces: fineract-war/build/libs/fineract.jar (~200MB)
3
4java -jar fineract.jar
5# Starts the complete Fineract server on port 8443

What fineract-war Does

  1. #
    Depends on all other modules in build.gradle
  2. #
    Spring Boot Plugin collects all .jar files
  3. #
    Embeds Tomcat so no separate web server needed
  4. #
    Bundles Liquibase changelogs so DB migrations run on startup

Docker Image

The official Fineract Docker image is built from this:
docker
QUBITS OF DPK
1FROM eclipse-temurin:21-jre
2COPY fineract.jar /app/fineract.jar
3ENTRYPOINT ["java", "-jar", "/app/fineract.jar"]

Key Configuration

fineract-war/src/main/resources/application.properties:
  • Server port: 8443 (HTTPS)
  • Database connection details
  • Spring Batch settings
  • Feature flags (events, external access, etc.)

2. fineract-doc

What it is

The documentation generation module — produces the OpenAPI (Swagger) specification and API documentation.

Layman Analogy

When developers want to know "how do I call the Create Client API?", they need documentation showing the URL, required fields, example request/response. fineract-doc automatically generates this documentation from the code annotations.

What It Generates

  1. #
    OpenAPI Spec (openapi.json / openapi.yaml)
  2. #
    Swagger UI (accessible at /swagger-ui/index.html when running)

How OpenAPI Annotations Work

java
QUBITS OF DPK
1@Operation(summary = "Create Client",
2    responses = {
3        @ApiResponse(responseCode = "200", content = @Content(
4            schema = @Schema(implementation = PostClientsResponse.class)
5        ))
6    }
7)
8@PostMapping("/clients")
9public PostClientsResponse create(@RequestBody PostClientsRequest request) {
10    // ...
11}
This annotation tells the OpenAPI Generator:
  • Endpoint: POST /clients
  • Request body class: PostClientsRequest
  • Success response class: PostClientsResponse
The generator reads this and adds it to the spec.

The Generate-Regenerate Cycle

javascript
QUBITS OF DPK
1Developer adds new API endpoint + @Operation annotation
23./gradlew generateOpenApiDocs
45openapi.yaml updated
67./gradlew :fineract-client:compileJava  (runs openapi-generator)
89New model classes appear in fineract-client/build/generated/
1011Developers use new classes in integration tests

3. fineract-progressive-loan-embeddable-schedule-generator

What it is

A standalone, embeddable library that exposes the progressive loan amortization calculator so external systems can use it without running a full Fineract server.

Layman Analogy

Imagine a loan officer using a mobile app in the field with no internet connection. The app needs to calculate the repayment schedule on-the-spot. This module is a mini calculator library that can be embedded in such apps — no server required.

Why It Exists

  • The fineract-progressive-loan module requires Spring, JPA, the full Fineract environment
  • Sometimes you just need the math without the full stack
  • This module strips out all the infrastructure, leaving only the pure calculation logic

What's Stripped Out

  • No @Service, @Repository, @Entity annotations
  • No database calls
  • No Spring context at all
  • Pure Java: input → calculation → output

Typical Use Case

java
QUBITS OF DPK
1// Loan origination mobile app, offline capable:
2ProgressiveLoanScheduleGenerator generator = new ProgressiveLoanScheduleGenerator();
3LoanScheduleModel schedule = generator.generate(
4    principal: 10000,
5    annualInterestRate: 12.0,
6    numberOfRepayments: 12,
7    repaymentFrequency: MONTHLY
8);
9// Returns: list of installments with principal/interest split

4. fineract-e2e-tests-core

What it is

The shared test infrastructure library for end-to-end (E2E) tests — provides reusable utilities, base classes, and helpers used by E2E tests.

Layman Analogy

When building many different tests, you don't want to repeat the same setup code everywhere. fineract-e2e-tests-core is like a shared toolkit — common tools that all your tests can import and use.

What's Inside

Test Base Classes
  • BaseIntegrationTest — sets up auth, HTTP client, common config
  • BaseLoanTest — creates test loan products, disburses, runs COB
Step Definitions
  • Business scenario steps written in a behavior-driven style
  • E.g., LoanSteps.createLoan(), ClientSteps.createClient(), COBSteps.runCOB()
Assertions
  • Domain-specific assertion helpers
  • LoanAssertions.assertInstallment(installment, principal, interest, totalOutstanding)
  • Cleaner than raw JUnit assertions — gives better error messages
Data Builders
  • Test data factories: LoanProductTestDataBuilder, ClientTestDataBuilder
  • Provide sensible defaults so tests only specify what they care about

Why Separate from integration-tests?

  • fineract-e2e-tests-core — shared library (imported as dependency)
  • fineract-e2e-tests-runner — actual test scenarios (runs the tests)
  • integration-tests — original integration test suite (being migrated to feign client)

5. fineract-e2e-tests-runner

What it is

The E2E test execution module — contains the actual end-to-end test scenarios written using the shared infrastructure from fineract-e2e-tests-core.

Layman Analogy

If e2e-tests-core is the testing toolkit, e2e-tests-runner is the actual test scripts — the numbered steps in a QA checklist that say "do this, then verify that".

Test Scenarios Inside

Loan Scenarios
  • Full loan lifecycle: create product, apply, approve, disburse, repay schedule, close
  • Edge cases: late payment, partial payment, prepayment, charge waiver
  • COB processing: overdue classification, interest accrual, delinquency buckets
Savings Scenarios
  • Open account, deposit, withdraw, apply annual fee, close account
  • Fixed deposit: create, mature, premature close
Investor Scenarios (newer)
  • Create external asset owner, transfer loan, buyback
Working Capital Scenarios
  • FINERACT-2455: WC delinquency bucket management (newest addition)

How Tests Are Structured

java
QUBITS OF DPK
1@Test
2public void testLoanDelinquency() {
3    // Given: a loan is created
4    Long loanId = loanSteps.createAndDisburseLoan(loanProductId, clientId);
5
6    // When: COB runs for 31 days past due date
7    cobSteps.fastForwardCOB(31);
8
9    // Then: loan should be in 30-day delinquency bucket
10    LoanResponse loan = loanSteps.getLoan(loanId);
11    loanAssertions.assertDelinquencyBucket(loan, "1-30 Days");
12}

Running E2E Tests

bash
QUBITS OF DPK
1./gradlew :fineract-e2e-tests-runner:test
2# Requires a running Fineract instance at localhost:8443

6. integration-tests

What it is

The original integration test suite — the largest collection of tests in Fineract, covering every API endpoint and business scenario. This is where your GSoC work (FINERACT-2441) lives.

Layman Analogy

integration-tests is like a massive QA test book with hundreds of test cases. Each test case calls the real Fineract API and verifies the result. It was originally written using RestAssured (raw HTTP calls) and is being migrated to fineract-client-feign (typed Java client).

Directory Structure

javascript
QUBITS OF DPK
1integration-tests/src/test/java/org/apache/fineract/integrationtests/
2├── ClientExternalIdTest.javaYour PR #5659
3├── InstanceModeIntegrationTest.javaYour PR #5658
4├── LoanAccountTest.javaMassive loan test file
5├── SavingsIntegrationTest.javaSavings account tests
6├── common/Shared test helpers
7│   ├── ClientHelper.javaYour helpers added here
8│   ├── SchedulerJobHelper.javaYour PR #5658 changes
9│   ├── LoanTransactionHelper.javaAlready migrated to feign
10│   ├── Utils.javaShared utilities
11│   └── FineractClientHelper.javaCreates FineractClient instance
12└── support/JUnit extensions
13    └── instancemode/
14        ├── ConfigureInstanceMode.javaAnnotation for mode setup
15        └── InstanceModeSupportExtension.java

RestAssured vs Feign: The Migration You're Doing

Old way (RestAssured) — being removed:
java
QUBITS OF DPK
1// Step 1: Build request spec manually
2RequestSpecification requestSpec = new RequestSpecBuilder()
3    .setContentType(ContentType.JSON).build();
4requestSpec.header("Authorization", "Basic " + Utils.loginIntoServerAndGetBase64EncodedAuthenticationKey());
5ResponseSpecification responseSpec = new ResponseSpecBuilder().expectStatusCode(200).build();
6
7// Step 2: Build JSON manually
8String jsonPayload = ClientHelper.getBasicClientAsJSON(officeId, legalFormId, null);
9
10// Step 3: Raw HTTP call, get back untyped Map
11PostClientsResponse clientResponse = ClientHelper.addClientAsPerson(requestSpec, responseSpec, jsonPayload);
New way (Feign) — being added:
java
QUBITS OF DPK
1// One call, typed, no boilerplate:
2PostClientsResponse clientResponse = ClientHelper.addClientAsPerson(
3    ClientHelper.DEFAULT_OFFICE_ID,
4    ClientHelper.LEGALFORM_ID_PERSON,
5    null  // no externalId
6);

Test Execution

bash
QUBITS OF DPK
1# Run all integration tests (needs running Fineract + DB)
2./gradlew :integration-tests:test
3
4# Run a specific test class
5./gradlew :integration-tests:test --tests "*.ClientExternalIdTest"
6
7# Run with verbose output
8./gradlew :integration-tests:test --info

What Makes a Good Integration Test

  1. #
    Arrange: Create test data (client, loan product, loan)
  2. #
    Act: Perform the action being tested (disburse, repay, reject)
  3. #
    Assert: Verify the outcome (status changed, balance correct, accounting entries created)
  4. #
    Cleanup: (Optional) Reset configuration changes (globalConfigurationHelper.manageConfigurations(..., false))

Summary Table — Group E

The Big Picture: How All Modules Fit Together

javascript
QUBITS OF DPK
1┌────────────────────────────────────────────────────────┐
2FINERACT-WAR (assembles everything)3│  ┌─────────────┐  ┌────────────┐  ┌────────────┐  │
4│  │ GROUP A      │  │ GROUP B      │  │ GROUP C      │  │
5│  │ Core Infra   │  │ Financial    │  │ Advanced     │  │
6│  │ fineract-core│  │ fineract-loan│  │ fineract-cob │  │
7│  │ fineract-db  │  │ fineract-sav │  │ fineract-inv │  │
8│  │ fineract-cmd │  │ fineract-acc │  │ fineract-rpt │  │
9│  └─────────────┘  └────────────┘  └────────────┘  │
10│  ┌─────────────┐  ┌────────────┐              │
11│  │ GROUP D      │  │ GROUP E      │              │
12│  │ Integration  │  │ Build/Test   │              │
13│  │ fineract-cli │  │ integration- │              │
14│  │ fineract-avro│  │ tests        │              │
15│  │ fineract-mix │  │ e2e-tests    │              │
16│  └─────────────┘  └────────────┘              │
17└────────────────────────────────────────────────────────┘
Request flow:
javascript
QUBITS OF DPK
1HTTP Client
23fineract-provider (Spring MVC controller)
45fineract-command (CommandRouterHandler)
67fineract-loan / fineract-savings (domain logic)
89fineract-charge / fineract-tax (fee calculation)
1011fineract-accounting (journal entries)
1213fineract-avro-schemas (event streaming)
1415fineract-db (Liquibase-managed MySQL/PostgreSQL)