Skip to content

Instantly share code, notes, and snippets.

@JebronLames32
Last active December 31, 2025 20:58
Show Gist options
  • Select an option

  • Save JebronLames32/b74ff1ac089722d9db8530d610b5e9fb to your computer and use it in GitHub Desktop.

Select an option

Save JebronLames32/b74ff1ac089722d9db8530d610b5e9fb to your computer and use it in GitHub Desktop.
Reactive Loan Risk-Assessment Engine for Mifos X — GSoC 2025 Final Report

Reactive Loan Risk-Assessment Engine for Mifos X — GSoC 2025 Final Report

gsocXmifos

Student: Abhinav R Cillanki (GitHub: JebronLames32)
Organization: The Mifos Initiative
Project: Reactive Loan Risk-Assessment Engine for Mifos X
Mentors: Victor Romero, Akshat Sharma
Program: Google Summer of Code 2025


Contents

  1. Abstract
  2. Links
  3. Project Goals and Scope
  4. System Design
  5. Key Components
  6. Data Model overview
  7. External Integrations
  8. Resilience & Observability
  9. Developer UX
  10. Merged Pull Requests
  11. Testing
  12. Challenges & Solutions
  13. Results & Impact
  14. What I Learned
  15. Future Work
  16. Acknowledgements

1. Abstract

This project delivers a reactive, event-driven microservice that ingests loan & document events from Apache Fineract via Kafka, fetches & organizes borrower documents, and orchestrates external risk checks (Bank Statement Analysis and Credit Bureau Pulls) in a resilient, non-blocking way. Results are stored in a reactive PostgreSQL database (R2DBC), and lightweight HTML/PDF endpoints are provided for quick operator review and audits. The service is extensible (SPI for credit bureaus), observable, and production-minded (timeouts, retries/backoff, safe reprocessing).

Architecture Overview:
architecture_view drawio


2. Links


3. Project Goals and Scope

3.1 Goals

  • Stand up a reactive event ingestion foundation (Kafka → WebFlux → R2DBC).
  • Build a document pipeline: fetch Fineract attachments, store locally, track status.
  • Integrate Bank Statement Analysis (BSA) and integrate Arya AI as a first provider.
  • Introduce a Credit Bureau SPI, and integrate iSoftPull as a first provider.
  • Provide developer-friendly UI endpoints (JSON/PDF) to inspect results.
  • Add resilience & observability: timeouts, concurrency limits, backoff/retries, safe replay.

4. System Design

4.1 Event Ingestion & Persistence

  • Kafka consumer subscribes to Fineract external-events (loan + document).
  • Events are persisted to event_message with R2DBC; schema managed via Liquibase.
  • Unprocessed Event Runner replays failed messages safely and idempotently.

4.2 Document Handling

  • On DocumentCreated, the service downloads the attachment from Fineract via reactive WebClient.
  • Files are stored via a pluggable ObjectStorageClient (initially Local FS).
  • DocumentMeta tracks storage path, statuses, and linkage to loans/clients.

4.3 Orchestration

  • Aggregator evaluates readiness (e.g., required docs available) and then triggers external services.
  • Calls fan out in parallel with timeouts, retries/backoff, concurrency limits.
  • Normalized results persist to dedicated tables. HTML/PDF endpoints expose snapshots.

4.4 Extensibility via SPIs

  • Credit Bureau Service provider interface: uniform interface for multiple providers.
  • Bank Statement Analysis service provider unifor interface for multiple BSA providers.
  • Provider packs (e.g., iSoftPull) adapt internal DTOs ↔ provider request/response.

Event Flow diagram Screenshot from 2025-08-31 22-14-22


5. Key Components

  • Kafka Consumer & Dispatcher: Routes events to the appropriate handler (loan/document).
  • Loan Handlers: Created/Updated/Withdrawn/Rejected → update Aggregator state.
  • Document Handlers: Created/Deleted → fetch/store + update DocumentMeta.
  • Aggregator: Determines readiness & orchestrates BSA/Credit Bureau calls.
  • External Services:
    • BSA (Arya): Submit bank statements, receive analysis, store results & reports.
    • Credit Bureau pull (iSoftPull): Query bureau, store normalized responses.
  • Persistence: R2DBC repositories, Liquibase changelogs (events, documents, bsa, cb).
  • UI/Reports: Minimal HTML list views, PDF report streaming for BSA.

6. Data Model overview

  • event_message — Stores raw events and their processing state, one row per event.
  • aggregator — Central per-loan record that tracks document uploads, external service statuses and aggregated scores.
  • loan_snapshot — Captures a snapshot of a loan’s data at a specific time.
  • document_meta — Metadata describing uploaded documents for loans.
  • bank_statement_analysis_result — Holds the outcome of bank-statement analysis for a loan.
  • credit_bureau_result — Stores credit-bureau data tied to a loan.

DB Entities
Screenshot from 2025-08-31 22-27-28


7. External Integrations

7.1 Bank Statement Analysis (Arya)

  • Non-blocking WebClient, request ID correlation.
  • Persist raw/normalized summary; PDF report downloadable via endpoint /bsa/report/{id}.

Arya AI report summary sample image
Screenshot from 2025-08-31 22-35-33

7.2 Credit Bureau (iSoftPull via SPI)

  • SPI abstraction for future providers.
  • Config-toggled enablement (feature flags) i.e. can be disabled if not required by the user.
  • Request/response mappers; persisted normalized JSON. Link to the detailed report is provided in the JSON response.

Sample iSoftPull results:

Screenshot from 2025-08-31 22-36-48 Screenshot from 2025-08-31 22-37-03

8. Resilience & Observability

  • Timeouts for outbound calls.
  • Retry with backoff for transient errors; max concurrency caps.
  • Unprocessed Event Runner: safe replay to handle failures.
  • Database transactions implemented so that proper rollbacks happen and application state is maintained
  • Structured logs; hooks for metrics/tracing (ready for production wiring).

9. Developer UX

9.1 Monitoring Dashboard (/analysis/dashboard)

To give operators a single place to see the latest risk-assessment outcome per loan, a dashboard is backed by the /analysis/dashboard endpoint. This endpoint aggregate the most recent Bank Statement Analysis (BSA) and Credit Bureau results per loan.

What it shows

  • Loan ID & Client Name (from stored loan snapshots)
  • Bank Statement Analysis status (Success / Failure / Pending / Not Available (if not configured))
  • Credit Bureau status (Success / Not Available / Pending / Not Available (if not configured))
  • Clickable success buttons: when a service has succeeded, the button links to the corresponding result endpoint so operators can drill down quickly.
loanrisk_dashboard

9.2 Endpoints (dev/operator views)

UI endpoints to view the results of bank statement analysis and credit bureau pulls:

  • GET /bsa – page listing all Bank Statement Analysis results as pretty-printed JSON.
  • GET /bsa/loan/{loanId} – page showing BSA results for the specified loanId as pretty-printed JSON.
  • GET /bsa/report/{id} – Streams the BSA PDF report for the given result id inline (if available).
  • GET /cb – page listing all Credit Bureau results as pretty-printed JSON.
  • GET /cb/loan/{loanId} – page showing Credit Bureau results for the specified loanId as pretty-printed JSON.

9.3 Local Run (fineract already running on port 8443)

# Build
./gradlew clean build

# Bring up infra + service
docker compose up --build

# Health
curl -s http://localhost:8080/actuator/health

Local Dev Stack
Screenshot from 2025-08-31 23-15-31


10. Merged Pull Requests (selected)

Short titles only (long descriptions kept in commit/PR bodies).

PR# Title
#1 Project setup: Kafka consumer, R2DBC, Liquibase, scaffolding
#3 Templates for Aggregator/Services/Handlers
#6 Loan event handlers (Created/Updated/Withdrawn/Rejected)
#7 Dockerfile + docker-compose (Postgres, Kafka, service)
#14 Unit tests (handlers, aggregator, dispatcher, converters)
#21 Document event handlers + doc fields + Unprocessed runner
#23 Database transactions & unprocessed-event replayer
#25 Fineract attachment fetch/store + DocumentMeta
#28 Bank Statement Analysis integration + persistence
#32 BSA results table & HTML/PDF endpoints
#34 Credit Bureau SPI + Integrate iSoftPull credit bureau pull
#35 Add UI controller to display results of BSA and credit report

In Apache Fineract repository:

PR# Description
#4752 Emit external events on document upload and delete (FINERACT-2309)
#4809 add LoanApplicationModifiedBusinessEvent & LoanWithdrawnByApplicantBusinessEvent (FINERACT-2318)

11. Testing

  • Unit tests for Loan/Document handlers, Aggregator, Dispatcher, ByteBufferConverter, ServiceStatus.
  • Provider mappers tests (BSA / iSoftPull).
  • Future: add integration tests (Testcontainers for Kafka/Postgres).

12. Challenges & Solutions

During the course of development, I encountered several technical and architectural challenges.

  • Event ordering & consistency
    Because the system consumes streams of events, ensuring that they are applied in the correct order and without duplication was critical. To solve this, I implemented idempotent persistence logic, meaning that replayed or duplicate events don’t corrupt state. Additionally, I introduced a replay runner, allowing missed or failed events to be safely reprocessed, ensuring consistency.

  • Document readiness gating
    Risk assessment services often require specific documents (e.g., bank statements, IDs) to be uploaded before analysis can proceed. Initially, services were triggered prematurely, leading to errors. I solved this by consolidating all document checks within the Aggregator component, which now blocks downstream workflows until the required documents exist, guaranteeing correctness.

  • Provider variability
    Different external service providers (e.g., bank statement analyzers, credit bureaus) often expose inconsistent APIs and payload formats. To isolate these differences, I introduced a Service Provider Interface (SPI) layer. With dedicated mappers and configurable toggles, each provider can be integrated behind a uniform contract, simplifying extensibility and maintenance.

  • Local TLS/testing
    Testing integrations locally with external APIs posed challenges because of secure transport requirements. I addressed this by using self-signed certificates and Spring profiles dedicated to development. This allowed me to simulate TLS-secured communication in a safe and controlled environment.


13. Results & Impact

The architectural choices and solutions I implemented produced measurable improvements:

  • Reactive throughput
    By removing blocking waits and embracing fully reactive pipelines, throughput increased significantly. The service can now process multiple loan applications in parallel without sacrificing responsiveness.

  • Operational visibility
    To aid audits and troubleshooting, I introduced lightweight HTML and PDF reporting views. These make it easy for operators and auditors to inspect analysis results without needing deep technical knowledge.

  • Extensibility
    The SPI-based design allows me to integrate new providers (e.g., an additional credit bureau or another bank statement analysis service) quickly, without rewriting core logic. This lowers friction when scaling across markets.

  • Reliability
    Built-in retries, exponential backoff, and controlled reprocessing mean fewer jobs are dropped when external providers fail or respond slowly. This materially improves the system’s stability in production environments.


14. What I Learned

This project was also a rich personal learning journey. My key takeaways include:

  • Reactive pipeline design
    Working with WebFlux, R2DBC, and Kafka gave me practical experience in building non-blocking, backpressure-aware data pipelines.

  • Event-driven architecture in BFSI
    I learned how to apply event-driven design principles to financial workflows, ensuring traceability and responsiveness in a heavily regulated industry.

  • Provider SPI development
    Designing SPI contracts and robust mapping layers taught me how to build flexible integrations that abstract away third-party inconsistencies while maintaining clean internal models.

  • Resilience patterns and release engineering
    I gained hands-on experience applying resilience techniques like retries, backoff, and circuit breakers, as well as managing microservice deployment concerns with proper TLS and profile-based configuration.


15. Future Work

  • Add KYC providers via SPI with shared DTOs.
  • Integrate with Mifos native solutions for Bank Statement Analysis.
  • Composite risk scoring & explainability; dashboard visualizations (Better UI)
  • Production circuit breakers, metrics (Micrometer), tracing (OpenTelemetry).
  • Full multi-tenancy and secret management polish needs to be achieved.
  • Rich admin console (filters, drill-downs, timelines) can be added for enabling the operator to choose what risk analysis services to opt for what kind of loans.

16. Acknowledgements

Huge thanks to my mentors Akshat Sharma and Victor Romero for their guidance and reviews, and to the Mifos community for thoughtful feedback, code reviews, and input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment