This document is the final report for my GSoC 2026 project with the Mifos Initiative (part of the Apache Fineract ecosystem). My project focused on building an AI-Powered Loan Contract Analysis & Summarization Tool an intelligent system that uses Large Language Models to extract financial terms from loan contracts, validate data accuracy through multi-layer verification, and generate plain-language summaries that empower borrowers to make informed decisions.
The project was built from scratch over 15 weeks (95 working days): a FastAPI + Python backend powering an AI analysis pipeline, a React 19 + Vite frontend, full Apache Fineract integration, support for 5 LLM providers (including local inference via Ollama), and document upload with OCR all production-ready with Docker, CI/CD, and comprehensive testing.
Note
Accepted GSoC Proposal (Reference) If you'd like a concrete example of a strong proposal β structure, milestones, and approach: View my accepted GSoC 2026 proposal (PDF) Β»
Tip
All my contributions: Browse all commits by me Β» Β· View the full repository Β»
Project OverviewProject TimelineArchitecturePhase 1 β AI Extraction & Analysis PipelinePhase 2 β Apache Fineract IntegrationPhase 3 β Document Upload & OCRDemosTechnical HighlightsKey MetricsChallenges & LearningsDocumentationFuture WorkConclusion
Millions of borrowers worldwide especially in developing economies β sign loan agreements they don't fully understand. Complex legal language, hidden fees, predatory clauses, and language barriers prevent informed decision-making, driving financial exclusion and debt traps.
An AI-powered system that takes a loan contract (pasted text, uploaded PDF/DOCX, or pulled directly from Mifos X / Apache Fineract) and delivers:
| Capability | What it does |
|---|---|
| π Smart Extraction | |
| Extracts 20+ financial entities (rates, fees, penalties, terms) with 88β100% accuracy | |
| β 5-Layer Validation | |
| Levenshtein matching, TF-IDF cosine similarity, numerical cross-check, EMI math verification, hallucination detection | |
| β οΈ Risk Scoring | |
| 0β10 risk scale with predatory lending detection, borrower protection scoring, and negotiation tips | |
| π Plain-Language Summary | |
| Clear, borrower-friendly summaries in English & Hindi | |
| π¬ WhatsApp Export | |
| Compact <300-char summary for easy mobile sharing | |
| π Fineract Integration | |
| Direct data pull from Mifos X β bypasses LLM extraction for 100% accurate structured data | |
| π Document Upload | |
| PDF, DOCX, TXT, and image uploads with OCR (Tesseract) | |
| π€ 5 LLM Providers | |
| Gemini, Groq, Ollama (local), Cerebras, HuggingFace β with timeout-based automatic fallback |
15 Weeks Β· 95 Days Β· From Zero to Production-Ready AI System
Core AI pipeline: extraction, validation, risk scoring, summarization, React frontend, CI/CD
Built the entire AI analysis engine from scratch a multi-stage async pipeline that takes raw loan contract text and produces structured, validated financial data with confidence scores, risk analysis, and borrower-friendly summaries.
| Area | What was built |
|---|---|
| FastAPI Backend | |
| REST API skeleton, routers, middleware (CORS, logging, rate limiting), async request handling | |
| Pydantic Schemas | |
LoanAgreementSchema with 20+ typed financial entity fields, request/response models |
|
| LLM Provider Registry | |
| Pluggable provider system supporting Gemini, Groq, Ollama, Cerebras, HuggingFace with retry logic | |
| Extraction Pipeline | |
| Prompt engineering for structured JSON extraction, 3-tier extraction path (Instructor / Native JSON / Raw), provider-aware routing | |
| Contract Segmentation | |
| 3 strategies header-based regex, NLTK sentence-based, TF-IDF semantic chunking β with adaptive selection | |
| 5-Layer Validation | |
Levenshtein fuzzy matching (80% threshold), TF-IDF cosine similarity, numerical cross-check, EMI math verification (Decimal -based), hallucination detection |
|
| Risk Analysis | |
| 0β10 risk scoring, RBI-guideline-based thresholds, predatory lending detection, default clause classification (standard vs. predatory) | |
| Financial Calculator | |
Reducing balance & flat rate EMI formulas, total cost calculation β all using Python Decimal for financial precision |
|
| Summarizer | |
| LLM-powered plain-language summaries (EN/HI), WhatsApp-ready <300-char export, language-aware provider routing | |
| Input Sanitization | |
| Prompt injection detection & prevention, delimiter-based prompt hardening | |
| React Frontend | |
ContractInput , AnalysisView , EntityCard , RiskBadge , ExportButton , states, error boundaries |
|
| Testing | |
| 95+ unit & integration tests, 85% coverage, security tests for prompt injection | |
| CI/CD | |
| GitHub Actions (CI, CD, Security scanning β Bandit, Safety, npm audit, Trivy) | |
| Docker | |
| Multi-stage Dockerfiles, docker-compose with health checks, production-ready config |
π Key Commits (Phase 1) - click to expand
| Commit | Description |
|---|---|
1cd4940 |
6d51b63
78f5d5b
c8ade26
72cd7e8
3a93b6a
7b796ad
697b4aa
39ab329
b68076e
bdd1a65
Direct Mifos X integration, Ollama local LLM support, production hardening, comprehensive documentation
Integrated the app directly with Apache Fineract / Mifos X. The key architectural insight: bypass LLM extraction entirely for Fineract products β build the LoanAgreementSchema
directly from Fineract's structured JSON (100% accurate, no hallucination risk), and use the LLM only for human-readable summary generation.
Also built a complete Ollama integration (325-line native provider) using Ollama's HTTP API directly β enabling fully local, offline, privacy-preserving loan analysis.
| Area | What was built |
|---|---|
| Fineract Service | |
fineract_service.py (711 lines) β async HTTP client with connection pooling, caching (5-min TTL), retry logic (tenacity), SSL config (3 modes), Basic Auth + tenant headers |
|
| Direct Schema Builder | |
build_schema_from_fineract() β maps every Fineract field to LoanAgreementSchema directly from JSON. Interest rate normalization (per-period β annual), charge classification (7 fee categories), down payment handling, grace periods, multi-disbursement support |
|
| Charge Classification | |
Maps Fineract charge arrays to specific fee fields using chargeTimeType + name-based classification: processing, late, prepayment, insurance, admin, other β with percentage vs. flat distinction |
|
| API Endpoints | |
GET /loanproducts (cached list), GET /loanproducts/{id} (product detail), POST /loanproducts/refresh (cache invalidation), enhanced /health with Fineract connectivity status |
|
| Currency Utilities | |
50+ ISO 4217 currency codes β display symbols, format_currency() and format_currency_precise() β multi-currency support (INR, USD, KES, etc.) |
|
| Ollama Provider | |
325-line native provider generate_native() (streaming text), generate_json() (Ollama JSON mode), auto-model-pull, health check, 120s timeout for local inference |
|
| Loan Simulator | |
/simulator endpoint full amortization schedule with month-by-month EMI breakdown, flat/reducing rate support, Decimal precision |
|
| Frontend | |
MifosProductPicker component auto-fetch products, /error/retry states, refresh button, product count, graceful Fineract-down fallback |
|
| Testing | |
test_fineract_service.py (444 lines) + test_integration_fineract.py (416 lines) β 19 test classes covering SSL, auth, API, caching, health check |
|
| Documentation | |
CONTRIBUTING.md (550 lines), DOCKER_SETUP.md (693 lines), LLM_PROVIDER_COMPARISON.md (531 lines), LOCAL_MODEL_SETUP_GUIDE.md (1,029 lines) |
π Key Commits (Phase 2) β click to expand
| Commit | Description |
|---|---|
c17e72a |
bdcc3f6
d0d0236
999b01e
e20c2cd
2274ba0
c1bb952
75de5a5
2237504
PDF/DOCX/image upload, Tesseract OCR, frontend polish
Built a complete document processing pipeline β users can upload loan agreements as files (PDF, DOCX, TXT, or images) and the system automatically extracts the text (with OCR for scanned documents) before feeding it through the existing AI analysis pipeline. Also wrote 4 comprehensive documentation guides totaling 2,800+ lines.
| Area | What was built |
|---|---|
| PDF Service | |
pdf_service.py (473 lines) β PyMuPDF text extraction, Tesseract OCR fallback (per-page, 300 DPI), DOCX (paragraphs + tables), TXT (multi-encoding fallback chain), image OCR (PNG/JPG) |
|
| Text Cleanup | |
_clean_extracted_text() β null byte stripping, form feed β newline, hyphenated line-break repair (agree-\nment β agreement ), whitespace normalization |
|
| File Validation | |
Extension check, 10MB size limit, empty file detection, encrypted PDF detection, .doc vs .docx format guidance |
|
| API Endpoint | |
POST /analyze/pdf β multipart/form-data , UploadFile , rate-limited (10/min), specific error messages per failure mode |
|
| React Component | |
PdfUpload (318 lines) β drag-and-drop zone with visual feedback, file type badges (color-coded by format), size display, upload progress bar, /error states |
|
| Frontend Integration | |
Tab-based input switching (paste / upload / Fineract), analyzeFile() hook, proper state cleanup on tab switch |
|
| Clipboard Paste | |
| Image paste from clipboard via Clipboard API β OCR β analysis | |
| Docker OCR | |
tesseract-ocr + tesseract-ocr-hin installed in backend container for out-of-box OCR support |
π Key Commits (Phase 3) β click to expand
| Commit | Description |
|---|---|
b68076e |
Paste a loan contract β AI extracts 20+ entities β 5-layer validation β risk score β plain-language summary
Select a loan product from Mifos X β schema built directly from Fineract JSON (no LLM extraction) β validated β summarized
Upload a PDF/DOCX/image β text extracted (with OCR for scanned docs) β full AI analysis pipeline
The most impactful architectural decision was creating two separate analysis paths:
Path A: Text/PDF β LLM Extraction β Validation β Summary (user-uploaded contracts)
Path B: Fineract β Direct JSON Map β Validation β Summary (Mifos X products)
Path B bypasses LLM extraction entirely every value comes from Fineract's authoritative API. The LLM is used only for summary generation (the one thing it excels at). This gives 100% data accuracy with 2β3Γ faster response times.
After a brutal debugging session (Day 34) where floating-point arithmetic turned Rs. 8,885
into 8884.999999999998
, the entire financial calculation layer was rewritten to use Python's Decimal
module.
Rule: never use float for money. This is non-negotiable for financial applications.
Instead of fighting instructor
compatibility, I built a native Ollama provider using Ollama's HTTP API directly:
Streaming generation viahttpx.stream
(no timeouts on slow hardware)JSON mode(format: "json"
) for95%+ parse success rate vs. ~70% with prompt-based JSONAuto-model-pull on first run setOLLAMA_MODEL=llama3.2:latest
and the app handles the restDetailed health check reports running status, model availability, installed models
The risk analysis system distinguishes between standard default triggers ("miss 3 payments") and predatory ones ("at lender's sole discretion"). Only predatory clauses increase the risk score.
Fineract's flat charge array is automatically classified into 7 fee categories using a combination of chargeTimeType
codes and name-based pattern matching with percentage vs. flat distinction for each:
disbursement time β processing_fee
overdue time β late_fee (flat) / late_payment_interest (%)
name: prepayment β prepayment_penalty
name: insurance β insurance_fee
name: admin β administrative_fee
everything else β other_fee
| |
| Layer | Technologies |
|---|---|
| Backend | |
| Python 3.11, FastAPI, Pydantic v2, httpx (async), Tenacity (retry) | |
| AI/ML | |
| LangChain, Instructor, NLTK, scikit-learn (TF-IDF), tiktoken | |
| LLM Providers | |
| Google Gemini, Groq, Ollama (local), Cerebras, HuggingFace Inference | |
| Document Processing | |
| PyMuPDF, python-docx, Tesseract OCR, Pillow | |
| Frontend | |
| React 19, Vite, Tailwind CSS, Axios, i18n | |
| Infrastructure | |
| Docker (multi-stage), docker-compose, Nginx, GitHub Actions | |
| Security | |
| Bandit, Safety, Trivy, npm audit, API key auth, input sanitization | |
| Testing | |
| pytest, pytest-asyncio, pytest-cov, unittest.mock |
| # | Challenge | What went wrong | What I learned |
|---|---|---|---|
| 1 | Floating-point precision | ||
float math turned 8885 into 8884.999999999998 . EMI validation flagged correct values as wrong. |
|||
Never use Python's float for money.Decimal module exists for a reason. Rewrote the entire financial calculator. |
|||
| 2 | Async event loop blocking | ||
| Sync LLM API calls froze FastAPI β the whole app hung on concurrent requests. | asyncio.to_thread() wraps sync calls to play nice with async. Now handles 10+ concurrent requests. |
||
| 3 | Prompt engineering | ||
| First prompts returned paragraphs of explanation instead of JSON. LLMs confused "late fee" with "late payment interest." | Be painfully explicit: "Return ONLY valid JSON." Include the schema in the prompt. Add disambiguation instructions. Took ~10 iterations to get 85%+ accuracy. | ||
| 4 | Ollama + Instructor | ||
The instructor library works with OpenAI-compatible APIs but breaks with Ollama's quirks. 5β10 seconds wasted per request on failed attempts. |
|||
Built a native Ollama provider using the HTTP API directly. Ollama's format: "json" mode is far more reliable than prompt-based JSON. |
|||
| 5 | Docker networking | ||
Containers couldn't communicate. Ollama on host unreachable from Docker backend (localhost resolves to the container, not the host). |
|||
host.docker.internal resolves to the host machine. Set up Docker early β not in Week 5 when the project is complex. |
Daily stand-ups with mentor learned to communicate blockers early instead of debugging alone for hoursPR discipline conventional commits, clear descriptions, linking to issuesDocumentation as a first-class deliverable 4 comprehensive guides totaling 2,800+ lines
| Document | Lines | Description |
|---|---|---|
README.md |
CONTRIBUTING.md
DOCKER_SETUP.md
LLM_PROVIDER_COMPARISON.md
LOCAL_MODEL_SETUP_GUIDE.md
GSoC_Daily_Work_Log.md
These are areas I'd love to see the project grow into:
| Area | Description |
|---|---|
| Batch Processing | |
| Analyze multiple contracts at once for MFIs processing loan portfolios | |
| More Languages | |
| Expand to other language for global MFI coverage | |
| Fine-Tuned Models | |
| Train a domain-specific model for higher extraction accuracy | |
| Mobile App | |
| React Native or KMP client for field officers to scan contracts on-the-go | |
| Regulatory Compliance | |
| Auto-check against country-specific lending regulations (RBI, CFPB, etc.) | |
| Borrower Dashboard | |
| Track multiple loans, compare offers, monitor risk over time | |
| Webhook Notifications | |
| Alert MFI admins when a high-risk loan product is detected |
This summer, I built a production-ready AI system from scratch from the first git init
to a deployed Docker application with 120+ tests, 5 LLM providers, Apache Fineract integration, OCR-powered document processing, and comprehensive documentation.
On the technical side, I learned to ship real software: async Python at scale, LLM reliability engineering (prompt iteration, structured output, fallback chains), financial precision (Decimal
, not float
), multi-provider architecture, and the discipline of CI/CD and security scanning from Day 1.
On the human side, I learned to work in the open: daily stand-ups, clear commit messages, scope negotiation, and writing documentation that helps the next contributor. I kept a 95-day engineering diary that documents every decision, failure, and lesson including the ones I'm not proud of.
The project matters because financial literacy shouldn't require a law degree. If this tool helps even one borrower spot a predatory clause or understand the true cost of their loan, it was worth building.
Huge thanks to:
Akshat Sharma andRahul Goel for fast feedback loops, honest design reviews, and the patience to say "start simple" when I was overengineeringfor building the infrastructure that makes financial inclusion possibleMifos Initiativefor the opportunity, structure, and funding that made this work possibleGoogle Summer of Codethe core banking platform this tool integrates withApache Fineract- The open-source LLM ecosystem Gemini, Groq, Ollama, and the communities behind them
Built with β€οΈ during GSoC 2026
π Repository Β· π Daily Work Log Β· π API Docs Β· π GSoC Proposal