Skip to content

ashbix23/AI-Financial-Assistant

Repository files navigation

AI Financial Assistant

A full-stack AI-powered financial assistant built around a Java 21 / Spring Boot gateway and a React + TypeScript frontend. Upload financial documents (10-Ks, earnings reports, prospectuses) and get grounded answers powered by Claude with retrieval-augmented context — all served through a secure REST API.

The project demonstrates:

  • Spring Boot 3.3 as a Backend-For-Frontend (BFF) — typed DTOs, validation, normalized error envelopes, request IDs, downstream-aware health checks, streaming multipart uploads via WebClient.
  • React + Vite + TypeScript + Tailwind — a polished fintech UI with drag-drop ingestion, real-time indexing status, suggested prompts, and per-session document isolation.
  • A clean three-tier separation between presentation, gateway, and the AI retrieval service it fronts.

Architecture

┌──────────────┐   ┌──────────────────────────┐   ┌──────────────────┐
│  React UI    │ ─▶│  Spring Boot Gateway     │ ─▶│  RAG Service     │
│  Vite + TS   │   │  Java 21 · Maven · :8080 │   │  Voyage·Pinecone·│
│  :5173       │   │  WebClient · Validation  │   │  Cohere · Claude │
└──────────────┘   │  Error envelope · CORS   │   │  :8000           │
                   └──────────────────────────┘   └──────────────────┘

The gateway owns everything browser-facing: it validates uploads (size, extension), forwards multipart streams to the retrieval service, normalizes errors into a typed ErrorEnvelope (with request IDs for tracing), exposes a downstream-aware /api/v1/health endpoint, and handles CORS so the React app has a clean path in.

Spring Boot gateway — what's inside

gateway/src/main/java/com/finsight/gateway/
├── GatewayApplication.java
├── config/
│   ├── AppProperties.java       # Typed @ConfigurationProperties record
│   ├── CorsConfig.java          # Locked-down /api/** CORS
│   └── WebClientConfig.java     # Reactor WebClient → upstream RAG service
├── controller/
│   ├── ChatController.java      # POST /api/v1/query
│   ├── IngestController.java    # POST /api/v1/upload, GET /api/v1/status/{id}
│   └── HealthController.java    # /api/v1/health (gateway + upstream)
├── service/
│   └── RagClient.java           # WebClient wrapper, error mapping
├── dto/
│   ├── ChatRequest.java         # @Valid @NotBlank, defaults user_id
│   ├── ChatResponse.java
│   ├── UploadResponse.java
│   ├── StatusResponse.java
│   └── ErrorEnvelope.java       # code, message, status, timestamp, requestId
└── exception/
    ├── UpstreamException.java
    └── GlobalExceptionHandler.java   # @RestControllerAdvice

Key Spring Boot patterns on display:

  • Typed configuration via @ConfigurationProperties records with sane defaults.
  • Reactive WebClient for streaming uploads and 120s LLM timeouts without thread starvation.
  • Centralized error handling with @RestControllerAdvice mapping validation errors, payload-too-large, and upstream failures to a consistent JSON envelope.
  • Bean validation (jakarta.validation) on request bodies via @Valid.
  • Spring Boot Actuator for /actuator/health alongside the custom downstream-aware health endpoint.

API

Method Path Description
GET /api/v1/health Gateway health plus upstream reachability
POST /api/v1/upload Multipart upload (file, user_id) — validated and forwarded
GET /api/v1/status/{file_id} Ingestion status (processing / completed)
POST /api/v1/query RAG query: { "query": "...", "userId": "..." }

Errors come back as:

{
  "code": "VALIDATION_FAILED",
  "message": "query must not be blank",
  "status": 400,
  "timestamp": "2026-04-28T15:21:09.184Z",
  "requestId": "8b3c…"
}

Quick Start

Prerequisites: Java 21, Maven 3.9+, Node 20+, and a running RAG service on :8000 (the gateway proxies to whatever URL RAG_SERVICE_URL points at — your existing retrieval service).

  1. Configure environment

    cp .env.example .env
    # fill in API keys; defaults are fine for everything else
  2. Run the gateway (terminal 1)

    cd gateway
    mvn spring-boot:run
    # gateway is up at http://localhost:8080
  3. Run the frontend (terminal 2)

    cd frontend
    npm install
    npm run dev
    # open http://localhost:5173

    Vite proxies /api to localhost:8080, so there's nothing to wire by hand.

  4. Run with Docker Compose (alternative)

    docker-compose up --build

Configuration

Everything is driven by .env (see .env.example). Gateway-relevant keys:

Key Default Notes
RAG_SERVICE_URL http://localhost:8000 Upstream RAG service the gateway proxies to
UPLOAD_MAX_BYTES 52428800 50 MB hard cap before forwarding
CORS_ALLOWED_ORIGINS http://localhost:5173 Comma-separated origins
VITE_API_BASE_URL http://localhost:8080 Where the React app calls

Project Layout

AI-Financial-Assistant/
├── gateway/                Spring Boot 3.3 / Java 21 / Maven
├── frontend/               React 18 + Vite + TypeScript + Tailwind
├── app/                    RAG retrieval service (Voyage / Pinecone / Cohere / Claude)
├── tests/                  Multi-tenancy isolation test
├── evaluation/             Golden dataset
├── docker-compose.yaml
└── .env.example

License

MIT. See LICENSE.

About

Full-stack AI financial assistant. Java 21 / Spring Boot BFF, React + TypeScript UI, Claude-powered RAG over Voyage embeddings + Pinecone vector search.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors