How nandhuincede/bank-advisor works
1. This repository is a small Flask-based AI financial advisor with a single server-side application, a browser-rendered UI, a deterministic calculation layer, an LLM-backed reasoning layer, and a local SQLite persistence layer.
2. The user interface is a single HTML template in templates/index.html. It serves two main interactions: submitting a financial profile for analysis and chatting against a previously created analysis session. There is no separate frontend application or JS framework boundary visible in the repo.
3. The application entry point is run.py (with main.py also present). The Flask app is organized as a factory-style package under app/, with route registration in app/api/routes.py and database initialization in app/db/database.py.
4. The request boundary is HTTP JSON APIs. The key endpoints are POST /api/analyze for financial assessment, POST /api/chat for follow-up questions, GET /api/history for analysis summaries, and GET /api/analysis/<id> for retrieving one analysis plus its conversation history.
5. The core business logic is split into a pure computation layer in app/services/financial_calculator.py. This layer performs all financial math deterministically: EMI ratio, savings rate, credit utilization, projected annual savings, monthly surplus, and deficit detection. The README explicitly says the LLM does not perform calculations.
6. On top of that sits the agent layer in app/services/agent.py. This is the orchestration boundary where LangChain-style tool use and prompt-driven response generation happen. The agent consumes computed metrics and user context, then produces the human-readable financial report or chat answer.
7. The tool boundary is in app/tools/financial_tools.py. These tools expose calculator and lookup capabilities to the agent, such as computing metrics and fetching stored analysis/chat context. This keeps the model from directly accessing raw application internals.
8. LLM provider selection is abstracted in app/services/llm_factory.py. The README indicates support for OpenAI, Gemini, and local Ollama, so model access is a configurable infrastructure dependency rather than a hard-coded vendor integration.
9. Persistence is handled with SQLite in app/db/database.py. Two tables are central to the architecture: analysis stores the original financial inputs, computed metrics, and generated AI report; chat_history stores per-analysis conversation turns linked by analysis_id. This creates a session-scoped data model for follow-up Q&A.
10. The main data flow for analysis is: browser form submission → Flask route validation → calculator computes metrics → agent/LLM interprets results → analysis record is saved in SQLite → response is returned to the browser. The important architectural constraint is that metrics are computed before any LLM reasoning.
11. The chat flow is separate but stateful: browser question → lookup of the referenced analysis and prior chat history → agent and LLM generate a contextual answer → question/answer pair is appended to chat_history → answer is returned to the UI. The database therefore acts as both an audit trail and conversation memory.
12. Operationally, the project is lightweight: pyproject.toml and uv.lock indicate modern Python packaging with uv, and .env.example shows that runtime configuration is environment-driven. The only notable external runtime dependencies are the chosen LLM provider API or local Ollama endpoint plus the local SQLite file.
13. A useful diagram boundary for this repo is: presentation layer, Flask API layer, deterministic financial engine, LLM agent/tooling layer, and SQLite persistence layer. The central design principle is separation between numeric truth and natural-language interpretation.
Main entry points: routes.py Chat API · agent.py Advisor agent · __init__.py App factory · database.py Analysis store
Components 16
Presentation
Browser-facing UI and entrypoints
- Index page · Single browser UI for analysis and chat interactions
templates/index.html
API Layer
Flask request handling and route surface
- Routes · Defines analysis, chat, and history endpoints
app/api/routes.py - Analyze API · Validates profile and returns a financial assessment
app/api/routes.py - Chat API · Answers follow-up questions for an analysis session
app/api/routes.py - History API · Returns analysis summaries
app/api/routes.py - Analysis API · Returns one analysis with conversation history
app/api/routes.py
Core Logic
Deterministic finance logic and AI orchestration
- Calculator · Computes ratios, savings, surplus, and deficit checks
app/services/financial_calculator.py - Advisor agent · Turns computed metrics into reports and chat answers
app/services/agent.py - LLM factory · Selects OpenAI, Gemini, or local Ollama backend
app/services/llm_factory.py - Financial tools · Tool boundary for metrics and stored context access
app/tools/financial_tools.py
Data Layer
SQLite persistence and session state
- DB init · Database connection and table initialization
app/db/database.py - Analysis store · Persists input profile, computed metrics, and generated report
app/db/database.py - Chat store · Stores per-analysis question and answer history
app/db/database.py
Runtime
App bootstrap and configuration
- Run app · Primary execution entrypoint for the Flask server
run.py - Main entry · Alternate application entrypoint
main.py - App factory · Application package initialization and factory setup
app/__init__.py
Connections 25
- Run app → App factory: starts · Launches the Flask application
- Main entry → App factory: starts · Alternative application startup path
- App factory → Routes: registers · Attaches HTTP routes to the app
- App factory → DB init: initializes · Creates or prepares the SQLite schema
- Routes → Analyze API: exposes · HTTP endpoint for financial analysis
- Routes → Chat API: exposes · HTTP endpoint for follow-up chat
- Routes → History API: exposes · HTTP endpoint for analysis summaries
- Routes → Analysis API: exposes · HTTP endpoint for one analysis session
- Analyze API → Calculator: computes · Derives deterministic financial metrics
- Analyze API → Advisor agent: interprets · Turns metrics into a human-readable report
- Analyze API → Analysis store: saves · Persists the completed analysis
- Chat API → Analysis store: loads · Fetches the referenced analysis context
- Chat API → Chat store: reads/writes · Uses prior turns and appends the new exchange
- Chat API → Financial tools: uses · Supplies stored context and metric access to the agent
- Chat API → Advisor agent: answers with · Generates contextual follow-up responses
- Analysis API → Analysis store: reads · Retrieves the stored analysis record
- Analysis API → Chat store: reads · Retrieves the conversation history
- Advisor agent → LLM factory: selects model · Obtains the configured provider backend
- Advisor agent → Financial tools: invokes · Calls tools for metrics and context
- Financial tools → Calculator: wraps · Exposes deterministic calculations to the agent
- DB init → Analysis store: hosts · Physical storage for analysis records
- DB init → Chat store: hosts · Physical storage for chat history
- Index page → Analyze API: submits to · Browser form posts analysis requests
- Index page → Chat API: submits to · Browser chat UI posts follow-up questions
- Index page → Analysis API: displays · Renders a selected analysis session