Your financial ledger. Ask anything.
Upload bank statements, auto-parse transactions, and chat with your financial data using AI.
Bank statements sit in downloads folders as PDFs and CSVs. Understanding spending patterns means manual spreadsheet work. Searching for a specific transaction means scrolling through pages of data.
- Upload -- Drag and drop any bank statement (PDF or CSV)
- Parse -- Transactions are automatically extracted and categorized by AI
- Embed -- Statement content is chunked and vectorized for semantic search
- Ask -- Chat with your financial data in natural language
- Visualize -- See spending patterns on interactive dashboards (coming soon)
| Feature | Status | Description |
|---|---|---|
| Statement Upload | โ | Drag-and-drop PDF/CSV with multi-bank support |
| Transaction Parsing | โ | Extensible parser strategy (PDF + CSV heuristics) |
| AI Categorization | โ | Mistral-powered batch categorization of transactions |
| Vector Embeddings | โ | pgvector storage with cosine similarity search |
| RAG Chat | โ | Natural language Q&A over your financial data |
| Agentic ReAct Loop | โ | Multi-step tool-calling agent (think โ act โ observe) |
| Adaptive Query Decomposition | โ | LLM breaks compound questions into typed sub-queries |
| Chart Data Tool | โ | Agent generates chart-ready data (label/value columns) |
| Category Updates via Chat | โ | Re-categorize transactions through conversation |
| LLM Thinking Display | โ | Transparent ReAct loop with live tool-call streaming |
| Dashboard | ๐ง | Visual analytics and spending breakdowns |
| Auth & Polish | ๐ง | User accounts and production hardening |
The agentic ReAct loop is fully transparent. While the LLM works, you see its thought process in a live-expanding accordion -- query decomposition, reasoning, SQL queries, and search results. The accordion auto-collapses when the final answer arrives.
| Thinking expanded | Response with collapsed thinking |
|---|---|
![]() |
![]() |
graph TB
subgraph Frontend ["Angular Frontend :4200"]
UP[Upload Page]
TX[Transactions View]
CH[Chat Page]
end
subgraph Backend ["NestJS Backend :3000"]
UC[Upload Controller]
TC[Transactions Controller]
RC[RAG Controller]
HC[Health Controller]
US[Upload Service]
PS["Parsers (PDF + CSV)"]
MS[Mistral Service]
CS[Chunker Service]
ES[Embeddings Service]
TS[Transactions Service]
RS[RAG Service]
AG["Agent Tools\n(think, decompose_query,\nsql_query, vector_search,\nupdate_category, chart_data, done)"]
end
subgraph Data ["PostgreSQL + pgvector"]
ST[(statements)]
TT[(transactions)]
EM[(embeddings)]
SS[(chat_sessions)]
SM[(chat_messages)]
end
subgraph External ["Mistral AI"]
CAT[Categorize]
EMB[Embed]
LLM[mistral-large-latest]
end
UP -->|POST /upload| UC
TX -->|GET /transactions| TC
CH -->|POST /chat SSE| RC
UC --> US --> PS --> MS --> CAT
US --> CS --> ES --> EMB
US --> ST
US --> TT
ES --> EM
TC --> TS --> TT
RC --> RS --> MS --> LLM
RS --> AG --> TT
RS --> AG --> EM
RS --> SS
RS --> SM
style Frontend fill:#e8f4f8
style Backend fill:#fff3cd
style Data fill:#d4edda
style External fill:#f8d7da
# Clone and install
git clone git@github.com:darth-dodo/ledger.git
cd ledger && pnpm install
# Start PostgreSQL (with pgvector)
docker compose up -d
# Configure environment
cp backend/.env.example backend/.env
# Add your MISTRAL_API_KEY to backend/.env
# Start backend (port 3000)
cd backend && pnpm dev
# Start frontend (port 4200)
cd frontend && pnpm dev# Run all tests (336 tests)
make test
# Run with coverage
make test-coverage # Backend + frontend coverage
# Individual test suites
cd backend && pnpm test # 278 backend tests
cd frontend && pnpm test # 58 frontend tests (with coverage)
# Type check
cd backend && pnpm build
# Database migrations
cd backend && pnpm migrate # Run pending migrations
cd backend && pnpm migration:revert # Revert last migration| Module | Statements | Branches | Functions | Lines |
|---|---|---|---|---|
| Backend | 96% | 91% | 100% | 96% |
| Frontend | 94% | 93% | 85% | 96% |
Coverage is enforced in CI and thresholds are set at 85% for the backend (backend/vitest.config.ts).
| Layer | Technology | Purpose |
|---|---|---|
| Frontend | Angular 21, Tailwind CSS 4, daisyUI | SPA with standalone components |
| Backend | NestJS 11, TypeORM | REST API with dependency injection |
| Database | PostgreSQL + pgvector | Relational data + vector embeddings |
| AI | Mistral AI + Vercel AI SDK | Categorization, embeddings, ReAct agent streaming |
| Testing | Vitest | Unit + integration tests (336 total) |
| Runtime | tsx, pnpm | TypeScript execution, package management |
ledger/
โโโ backend/ # NestJS API (port 3000)
โ โโโ src/
โ โโโ upload/ # POST /upload, GET/DELETE /statements
โ โโโ transactions/ # GET /transactions, PATCH /transactions/:id
โ โโโ embeddings/ # Chunking + vector embedding pipeline
โ โโโ mistral/ # Mistral AI client (categorize + embed + chatStream)
โ โโโ rag/ # Chat sessions, ReAct agent, 7 agent tools
โ โโโ health/ # GET /health
โ โโโ db/ # Migrations and data source config
โโโ frontend/ # Angular SPA (port 4200)
โ โโโ src/app/
โ โโโ core/ # Services (ApiService)
โ โโโ shared/ # Reusable components (FileDropzone)
โ โโโ features/ # Page components (Upload, Chat, Settings)
โโโ docs/
โ โโโ product.md # Product spec
โ โโโ architecture.md # System design
โ โโโ adrs/ # Architecture decision records
โ โโโ milestones/ # Milestone docs and retros
โโโ docker-compose.yml # PostgreSQL + pgvector
- Product Spec -- Vision, features, and user stories
- Architecture -- System design and data flow
- ADR-001: Upload Strategy -- File handling decisions
- ADR-002: Parser Strategy -- Multi-format parsing design
- ADR-003: Embedding Strategy -- RAG vector storage decisions
- ADR-004: LLM Thinking Display -- Transparent ReAct loop via SSE
- Adaptive Query Decomposition Design -- ReAct agent + decomposition design
- Changelog

