DEV Community

Cover image for Finovara - Building a Simple Chatbot in Spring Boot
Marcin Parśniak
Marcin Parśniak

Posted on

Finovara - Building a Simple Chatbot in Spring Boot

Recently, I added a simple chatbot to my Finovara app that answers users’ finance-related questions.

No AI, no NLP libraries — just clean architecture, enums, and text files.

It works surprisingly well for the limited scope we need. Here’s how it’s built.


The Idea

The chatbot works like this:

  1. A user asks a question.
  2. The system normalizes the input.
  3. It maps the question to a predefined entry.
  4. The entry corresponds to a SmartReportType enum.
  5. The enum is handled by a handler class.
  6. The handler generates the actual response.

This makes the system:

  • Predictable
  • Easy to extend
  • Fast and lightweight

Core Architecture

The main entry point is:

  public String generateResponse(String email, String userQuestion) {
        User user = userManagerService.getUserByEmailOrThrow(email);

        SmartReportType type = smartReportQuestionService.getTypeFromQuestion(userQuestion);

        if (type == null)
            return "I’m not smart enough to answer this question. Please ask a question from the question book!";

        SmartReportHandler handler = handlers.get(type);

        if (handler == null) {
            return "Report type not supported";
        }

        return handler.generate(user.getId());
    }

Enter fullscreen mode Exit fullscreen mode

Here’s what’s happening:

The question is mapped to a SmartReportType enum.
Each enum has its own handler.
The handler generates a response based on templates and user data.

This is basically a Strategy Pattern in action.

Mapping Questions to Enums

Instead of hardcoding questions in Java, they are stored in TXT files:

MONTH_SPENDING | how much did i spend this month
MONTH_SPENDING | monthly expenses
AVERAGE_DAY_SPENDING | average daily spending
EXPENSE_RATE | what percentage of my income is spent
SAVINGS_RATE | how much did i save
Enter fullscreen mode Exit fullscreen mode

Loader Service:

questionMap.put(question, SmartReportType.valueOf(enumName));

Enter fullscreen mode Exit fullscreen mode

Normalization:

private String normalize(String text) {
    return text.toLowerCase()
        .trim()
        .replace("?", "");
}
Enter fullscreen mode Exit fullscreen mode

Thanks to this:

  • “How much did I spend?”
  • “how much did i spend”
  • “HOW MUCH DID I SPEND??”

all map to the same key.

Handlers: Business Logic

Each enum type has its own handler:

public interface SmartReportHandler {
    SmartReportType getType();
    String generate(Long userId);
}
Enter fullscreen mode Exit fullscreen mode

Handlers are responsible for fetching user data and generating responses.

Example: Expense Rate

BigDecimal total = sumExpenses.multiply(BigDecimal.valueOf(100))
    .divide(sumRevenue, 2, RoundingMode.HALF_UP);

String template = templateService.getRandomResponse(SmartReportType.EXPENSE_RATE);
return template.replace("{amount}", total.toString());
Enter fullscreen mode Exit fullscreen mode

Dynamic Responses (Templates)

Responses are stored in text files instead of being hardcoded:

You spent {amount} this month.
Your total expenses are {amount}.
Your savings rate is {amount}%.
Enter fullscreen mode Exit fullscreen mode

Randomization makes replies feel less repetitive:

return responses.get(random.nextInt(responses.size()));
Enter fullscreen mode Exit fullscreen mode

*Thanks for reading! *

If you’re curious to see the full project or try it yourself, check out the code on GitHub:

GitHub logo M4rc1nek / finovara-backend

Backend service for a personal finance management application

💰 Finovara — Backend

Backend REST API for a personal finance management application built with Java 25 and Spring Boot 4.


📖 About the Project

Finovara is a personal finance platform designed to help users take full control of their money. The backend exposes a secure REST API that powers tracking of income and expenses, budget management, savings goals, and financial reporting — all wrapped in a bank-grade security model based on JWT authentication.

The application is designed with scalability in mind and is fully containerized via Docker, with separate production and test database environments managed through Docker Compose.


🎯 Key Features

  • 🔐 Authentication & Authorization — JWT-based stateless security with Spring Security; access and refresh token flow with device/user-agent detection
  • 💸 Income & Expense Tracking — full CRUD for financial operations with category tagging
  • 📊 Statistics & Reports — aggregated financial summaries, spending trends, and exportable PDF reports
  • 🏦…




Top comments (0)