AI-powered Personal Finance Platform β membantu nasabah memahami pola pengeluaran mereka lewat AI Financial Coach.
FinSight adalah capstone project DBS Coding Camp 2026. Platform ini menganalisis transaksi nasabah menggunakan beberapa model Machine Learning (deteksi anomali, clustering persona, klasifikasi NLP) lalu menghasilkan laporan keuangan mingguan & bulanan yang dirangkai oleh LLM melalui pipeline RAG.
- Arsitektur
- Struktur Monorepo
- Tech Stack
- Pipeline Machine Learning
- Alur Scheduler
- Prasyarat
- Setup & Menjalankan
- Ringkasan API
- Environment Variables
- Tim
FinSight memakai arsitektur dua backend dengan pembagian tanggung jawab yang jelas:
ββββββββββββββββββββββββββββ
β React Native (Expo) β
β Mobile / Web Frontend β
ββββββββββββββ¬ββββββββββββββ
β REST (JWT)
βΌ
ββββββββββββββββββββββββββββ
β NestJS Backend β βββ Backend utama
β Auth Β· Transactions Β· β (source of truth)
β Reports Β· Scheduler/Cron β
ββββββββ¬βββββββββββββ¬ββββββββ
internal key β β TypeORM
βΌ βΌ
ββββββββββββββββββββ ββββββββββββββββββββ
β FastAPI Backend β β PostgreSQL DB β
β ML Orchestrationββββ€ (shared, async) β
β (internal only) β ββββββββββββββββββββ
ββββββββββββββββββββ
β load models
βΌ
Autoencoder Β· K-Means Β· NLP (TF-IDF) Β· RAG + LLM
- NestJS = backend utama / source of truth. Memegang autentikasi (JWT), transaksi, laporan, dan menjadwalkan cron job. Hanya NestJS yang menghadap publik.
- FastAPI = ML orchestration layer internal. Tidak menghadap publik β hanya dipanggil NestJS dengan internal key. Memuat seluruh model ML & menjalankan pipeline laporan.
- PostgreSQL = database tunggal yang dibagi keduanya (NestJS via TypeORM, FastAPI via asyncpg read-only).
CAPSTONE/
βββ nestjs-backend/ # Backend utama: Auth, Transactions, Reports, Scheduler (NestJS 11 + TypeORM)
βββ fastapi-backend/ # ML orchestration layer (FastAPI, VSA + DDD)
βββ reactnative-frontend/ # Aplikasi mobile/web (Expo Router + React Native 0.81)
βββ notebook-model/ # Notebook training & artefak model (.keras, .pkl)
βββ streamlit/ # Dashboard admin untuk eksplorasi clustering
βββ .gitignore
| Layer | Teknologi |
|---|---|
| Frontend | React Native 0.81, Expo 54, Expo Router 6, TypeScript, Axios, expo-secure-store |
| Backend Utama | NestJS 11, TypeORM 0.3, PostgreSQL, JWT (passport-jwt), bcrypt, Swagger, @nestjs/schedule (cron) |
| ML Backend | FastAPI, SQLAlchemy + asyncpg, Pydantic v2, Uvicorn |
| Machine Learning | TensorFlow/Keras (Autoencoder), scikit-learn + UMAP (K-Means), TF-IDF (NLP), OpenRouter/OpenAI-compatible LLM |
| Dashboard | Streamlit, Plotly, scikit-learn, UMAP |
| Database | PostgreSQL |
Empat komponen ML diorkestrasi oleh FastAPI (semua model di-preload saat startup via preload_all_models()):
- NLP (TF-IDF + classifier) β mengklasifikasikan transaksi Transfer P2P ke kategori (Needs/Wants) berdasarkan deskripsi. Output:
(vectorizer, model). - Autoencoder (Keras) β deteksi anomali transaksi. Threshold MAE adaptif per kombinasi
(customer_id, sub_category). Preprocessing: One-Hot Encoding sub-kategori,log1pnominal, Z-score per user-kategori, lalu MinMaxScaler. - K-Means Clustering β pipeline
StandardScaler β UMAP β K-Meansuntuk menentukan persona nasabah dari 10 fitur behavioral (wants_ratio, fixed_costs_ratio, savings_rate, wants_frequency, small_leaks_ratio, night_owl_spending, weekend_surge, early_month_depletion, balance_volatility, survival_mode_days). - RAG + LLM β konteks dirangkai manual dari knowledge base keuangan (
ml/knowledge/financial_kb.json) + ringkasan transaksi, lalu dikirim ke LLM (OpenRouter, API OpenAI-compatible) untuk menulis narasi laporan.
Artefak model tersimpan di
notebook-model/model/(autoencoder.keras,kmeans_all_umap.pkl,umap_all.pkl,scaler_all.pkl,nlp_model.pkl,tfidf_vectorizer.pkl, dll). Path-nya dikonfigurasi via env FastAPI.
NestJS menjadwalkan cron, lalu memanggil endpoint internal FastAPI:
- Weekly β
POST /scheduler/weeklysetiap Senin 06:00 WIB Query 7 hari transaksi β NLP (klasifikasi P2P) β Autoencoder (anomali) β hitung rasio Wants/Needs β RAG + LLM β laporan mingguan. - Monthly β
POST /scheduler/monthlysetiap tanggal 1, 00:05 WIB Query 30 hari transaksi β NLP β K-Means (update persona) β hitung savings rate & rasio Wants/Needs β RAG + LLM β laporan bulanan. - Reset Ratio β NestJS mereset
currentNeedsRatio/currentWantsRatio = 0tepat 00:00 tanggal 1 (sebelum monthly scheduler jalan).
Endpoint scheduler dilindungi internal key (verify_internal_key) dan mendukung dry_run (diblokir di environment production).
- Node.js β₯ 20 dan pnpm (frontend) / npm (nestjs)
- Python β₯ 3.13 β direkomendasikan
uv(FastAPI memakaipyproject.toml+uv.lock) - PostgreSQL β₯ 14 (database bersama)
- Expo CLI (otomatis via
npx expo) - API key LLM (OpenRouter) untuk pipeline RAG
Clone repo:
git clone https://github.com/FinSight-DBS/Finsight.git
cd FinsightTiap komponen punya
.envsendiri. Salin dari.env.examplelalu sesuaikan. Jangan commit.envβ sudah di-ignore.
cd nestjs-backend
cp .env.example .env # isi DB, JWT_SECRET, FASTAPI_URL, FASTAPI_INTERNAL_KEY
npm install
npm run migration:run # apply skema database
npm run seed # (opsional) isi data awal
npm run start:dev # http://localhost:3000 Β· Swagger: /api/docsScript berguna: npm run migrate:fresh:seed (drop β migrate β seed), npm run test, npm run lint.
cd fastapi-backend
cp .env.example .env # isi DB, path model, LLM_API_KEY, INTERNAL_API_KEY
# dengan uv (disarankan)
uv sync
uv run python main.py # http://localhost:8000 Β· docs: /docs
# atau dengan pip
pip install -r requirements.txt
python main.pyPastikan path model di
.envmenunjuk ke artefak yang ada (mis. darinotebook-model/model/). Model di-preload saat startup.
cd reactnative-frontend
cp .env.example .env 2>/dev/null || true # set EXPO_PUBLIC_API_URL ke URL NestJS
pnpm install
pnpm start # tekan: a (Android) Β· i (iOS) Β· w (web)Script lain: pnpm android, pnpm ios, pnpm start:clear, pnpm typecheck, pnpm lint.
cd streamlit
pip install streamlit pandas numpy plotly scikit-learn umap-learn scipy
streamlit run dashboard.py # http://localhost:8501Notebook training ada di notebook-model/code/ (auto-encoder/, clustering/, nlp/, data-generator/). Jalankan dengan Jupyter/VS Code untuk melatih ulang model; output disimpan ke notebook-model/model/.
Base URL NestJS: http://localhost:3000 Β· Dokumentasi interaktif: GET /api/docs (Swagger).
| Method | Endpoint | Keterangan |
|---|---|---|
| POST | /auth/register |
Registrasi β { token } |
| POST | /auth/login |
Login β { token } |
| GET | /auth/profile |
Profil user (income, savingsGoal, persona, rasio) |
| POST | /auth/logout |
Logout (invalidasi active token) |
| Method | Endpoint | Keterangan |
|---|---|---|
| POST | /transactions |
Buat transaksi |
| GET | /transactions/customer/:customerId?limit |
Daftar transaksi nasabah |
| GET | /transactions/:id |
Detail transaksi |
| Method | Endpoint | Keterangan |
|---|---|---|
| PATCH | /users/:id |
Update profil user |
| Method | Endpoint | Keterangan |
|---|---|---|
| GET | /reports/weekly/:customerId |
List laporan mingguan |
| GET | /reports/weekly/:customerId/:reportId |
Detail mingguan ({ report, anomalies }) |
| GET | /reports/monthly/:customerId |
List laporan bulanan |
| GET | /reports/monthly/:customerId/:reportId |
Detail bulanan |
| POST | /reports/trigger-weekly/:customerId |
Trigger manual laporan mingguan |
| POST | /reports/trigger-monthly/:customerId |
Trigger manual laporan bulanan |
| Method | Endpoint | Keterangan |
|---|---|---|
| POST | /scheduler/weekly |
Jalankan pipeline mingguan |
| POST | /scheduler/monthly |
Jalankan pipeline bulanan |
Frontend menurunkan balance, analitik kategori, dan notifikasi dari data transaksi + laporan (tidak ada endpoint khusus untuk itu). Lihat
reactnative-frontend/services/analytics.ts.
NODE_ENV=development
PORT=3000
DB_HOST=localhost
DB_PORT=5432
DB_USERNAME=postgres
DB_PASSWORD=postgres
DB_DATABASE=finsight_db
DB_SSL=false
JWT_SECRET=ganti-dengan-secret-yang-kuat
JWT_EXPIRES_IN=7d
FASTAPI_URL=http://localhost:8000
FASTAPI_INTERNAL_KEY=dev-internal-keyAPP_ENV=production
PORT=8000
DB_HOST=localhost
DB_PORT=5432
DB_NAME=finsight_db
DB_USER=finsight_user
DB_PASSWORD=<password_rahasia>
AUTOENCODER_MODEL_PATH=/app/model/autoencoder/autoencoder.keras
KMEANS_MODEL_PATH=/app/model/clustering/kmeans_all_umap.pkl
KMEANS_LABEL_MAP_PATH=/app/model/clustering/label_map.json
NLP_MODEL_PATH=/app/model/nlp/nlp_model.pkl
NLP_TOKENIZER_PATH=/app/model/nlp/tfidf_vectorizer.pkl
LLM_API_URL=https://openrouter.ai/api/v1
LLM_API_KEY=<your-openrouter-key>
LLM_MODEL=minimax/minimax-m2.5:free
INTERNAL_API_KEY=<secret_internal_key>EXPO_PUBLIC_API_URL=http://localhost:3000Capstone Project β DBS Coding Camp 2026 Β· Tim FinSight-DBS.
Built with β€οΈ for DBS Coding Camp 2026