-
Notifications
You must be signed in to change notification settings - Fork 1
Reference Guide
Per la configurazione dettagliata di tutti i parametri e dei provider LLM vedi developer_guide.md e la documentazione tecnica in
documents/configurazione.md.
| Pagina | Scopo |
|---|---|
| Import | Carica file CSV/XLSX, avvia la pipeline di elaborazione |
| Ledger | Vista tabellare di tutte le transazioni importate |
| Modifiche massive | Operazioni in blocco: categoria, contesto, giroconto, eliminazione da filtro |
| Analytics | Grafici e report aggregati per periodo/conto/categoria |
| Review | Transazioni con classificazione incerta o da rivedere |
| Regole | Gestione regole deterministiche di categorizzazione |
| Tassonomia | Struttura categorie/sottocategorie personalizzabile |
| Impostazioni | Backend LLM, API key, formati data/importo, lingua |
| Check List | Tabella pivot mese × conto: presenza e quantità delle transazioni |
| Assistente | Chatbot di supporto adattivo (RAG cloud/locale o FAQ deterministico) |
| Formato | Note |
|---|---|
| CSV | Auto-detect encoding (UTF-8, latin-1, cp1252), delimiter (, ; \t) |
| XLSX / XLS | Celle numeriche lette come float (il formato locale originale non è recuperabile) |
Banche riconosciute automaticamente tramite fingerprint degli header. Nessuna configurazione manuale richiesta.
File in input
│
▼
0. Pre-processing Phase 0 → rimozione righe pre-header sparse; drop colonne a bassa variabilità
0b. Header SHA256 → hash prime min(30,N) righe raw → lookup schema in DB (O(1))
1. Classificazione documento → solo se schema non trovato per SHA256: LLM Flow 2 + review UI obbligatoria
2. Normalizzazione → encoding, delimitatori, skip_rows, parse date/importi, SHA-256
3. Dedup check → scarta transazioni già presenti (zero LLM call)
4. Pulizia descrizioni → LLM estrae nome controparte, PII redatte prima/dopo
5. Rilevamento giroconti → esclude/neutralizza trasferimenti interni
6. Riconciliazione carta-c/c → elimina double-counting addebiti mensili aggregati
7. Categorizzazione a cascata → regole utente → regex statiche → LLM → fallback "Altro"
8. Persistenza → upsert idempotente per tx, link, schema (con header_sha256)
Al primo import di un file con formato sconosciuto (header SHA256 non presente in DB), l'app si ferma e mostra un form di revisione obbligatorio. L'utente vede:
- Preview raw — prime 10 righe del file grezzo (senza preprocessing)
- Selettore skip_rows — quante righe saltare prima dell'intestazione vera
- Campi schema editabili — tipo documento, colonne, convenzione segno
- Preview parsata — prime 8 transazioni con lo schema corrente (live)
Dopo conferma, lo schema viene salvato con il fingerprint header_sha256. Al re-import dello stesso formato: lookup immediato, nessuna LLM call, nessuna UI.
Se uno schema salvato (Flow 1) produce meno del 10% di transazioni parsabili rispetto alle righe totali del file, viene considerato corrotto (es. date_format sbagliato, mapping colonne obsoleto). In questo caso l'orchestrator:
- Elimina lo schema invalido dal DB
- Ritenta con Flow 2 (ri-classificazione LLM)
- Se anche Flow 2 fallisce, l'importazione restituisce errore
Inoltre, all'avvio dell'applicazione una migrazione automatica elimina gli schema orfani (righe document_schema senza header_sha256), che sarebbero irraggiungibili dal lookup per hash.
La categoria viene assegnata nell'ordine seguente; il primo match vince:
- Regole utente — definite nella pagina Regole (esatta / contiene / regex)
- Regole statiche — pattern hardcoded per casi comuni (bolli, F24, affitti standard)
- LLM — il modello configurato in Impostazioni; riceve la descrizione sanitizzata
- Fallback — categoria "Altro" se tutti i passi precedenti falliscono
La sottocategoria è la fonte di verità: se LLM o regola assegna una sottocategoria presente in tassonomia, la categoria genitore viene derivata automaticamente.
| Tipo | Comportamento | Esempio pattern |
|---|---|---|
exact |
La descrizione intera deve corrispondere (case-insensitive) | NETFLIX.COM |
contains |
Il pattern deve apparire nella descrizione (case-insensitive) | ESSELUNGA |
regex |
Espressione regolare Python | RATA\s+\d+/\d+ |
Quando salvi una nuova regola, viene applicata immediatamente a tutte le transazioni già presenti nel database, non solo alle future importazioni.
Il pulsante
Le regole vengono valutate in ordine di priorità decrescente (campo priorità, default 10). In caso di parità di priorità, l'ordine è stabile ma non garantito. La prima regola che fa match vince — l'elaborazione si ferma al primo match trovato.
Quando la banca addebita sul conto corrente il totale mensile della carta di credito, le singole spese della carta e l'addebito cumulativo sul conto sarebbero contate due volte. Spendif.ai risolve questo automaticamente:
- Le transazioni della carta rimangono visibili nel Ledger
- L'addebito aggregato sul conto viene marcato come giroconto (🔄) ed escluso dai totali
Non richiede configurazione. Se vedi comunque un duplicato, controlla in Review.
Un giroconto è un trasferimento tra due conti tuoi (es. "Bonifico a Conto Deposito"). Se contato su entrambi i lati falsifica il saldo.
Come viene rilevato: matching importo + finestra temporale (±3 giorni) tra conti diversi dello stesso titolare.
Come viene marcato: icona 🔄 nel Ledger, escluso dai totali di Analytics.
Pulsante "Rileva giroconti cross-account" in Review: riesegue la detection globalmente su tutte le transazioni. Utile se hai importato i due lati del giroconto in sessioni separate.
| Backend | Dove gira | Privacy | Configurazione |
|---|---|---|---|
| Ollama | Locale (default) | Totale — nessun dato lascia il tuo PC | Richiede Ollama installato e modello scaricato |
| llama.cpp | Locale (container Docker) | Totale — nessun dato lascia il tuo PC | File GGUF in models/, URL http://llama-cpp:8080/v1
|
| OpenAI | Remoto | PII redatte prima dell'invio | API key in Impostazioni |
| Claude | Remoto | PII redatte prima dell'invio | API key in Impostazioni |
Circuit breaker: se il backend configurato non risponde, Spendif.ai fa fallback automatico su Ollama locale. Se anche Ollama è offline, la transazione viene importata con to_review=True e descrizione grezza.
Chatbot integrato nella pagina 💬 Assistente. Tre modalità auto-selezionate in base al backend LLM configurato:
| Modalità | Backend richiesto | Come funziona |
|---|---|---|
| RAG Cloud | OpenAI / Claude / Compatible (con API key) | Retrieval semantico + risposta generata dal LLM cloud |
| RAG Local | Ollama / vLLM | Retrieval semantico + risposta generata dal LLM locale |
| FAQ Match | llama.cpp o nessuno | Match deterministico TF-IDF su FAQ preconfezionate |
La knowledge base è in chat_bot/knowledge/<lang>/ con FAQ (JSON/Markdown) e documenti per RAG.
Prima di qualsiasi chiamata a backend remoto, Spendif.ai redige:
| Dato | Esempio originale | Dopo sanitizzazione |
|---|---|---|
| IBAN | IT60X0542811101000000123456 |
<ACCOUNT_ID> |
| Numero carta | 4111 1111 1111 1111 |
<CARD_ID> |
| Codice fiscale | RSSMRA80A01H501U |
<FISCAL_ID> |
| Nome titolare | Mario Rossi |
Nome fittizio (es. Carlo Brambilla) |
La sanitizzazione avviene in memoria; il dato originale non viene mai modificato nel database.
Struttura a 2 livelli: Categoria → Sottocategoria.
- Modificabile dalla pagina Tassonomia senza riavviare l'app
- Categorie predefinite: Alimentari, Casa, Trasporti, Salute, Svago, Abbonamenti, Utenze, Istruzione, Lavoro, Finanza, Viaggi, Regali, Tasse, Altro + categorie entrata
- Puoi aggiungere sottocategorie custom senza toccare il codice
Ogni transazione viene identificata da un hash SHA-256 calcolato su: data, importo, descrizione, conto. Reimportare lo stesso file produce lo stesso set di righe; i duplicati vengono scartati senza errori.
Dalla pagina Analytics → pulsante Esporta:
| Formato | Contenuto |
|---|---|
| HTML | Report standalone con grafici Plotly interattivi |
| CSV | Tutte le transazioni filtrate, colonne canoniche |
| XLSX | Come CSV ma con formattazione Excel |
Distinte dalle regole di categorizzazione. Servono a sostituire descrizioni grezze illeggibili con testo leggibile.
- Salvate nella tabella
description_ruledel database - Applicabili in blocco dal pannello in fondo alla pagina Review
- Stessi tipi di match:
exact/contains/regex - Dopo l'applicazione, le transazioni aggiornate vengono riprocessate dal LLM per la categorizzazione
La pagina ✏️ Modifiche massive raccoglie tutte le operazioni che agiscono su più transazioni contemporaneamente.
| Sezione | Operazione |
|---|---|
| 1 · Scegli transazione | Selezione con ricerca testuale e filtro "solo da rivedere" |
| 2a · Giroconto | Toggle giroconto ↔ normale, con propagazione a tutte le tx con stessa descrizione |
| 2b · Contesto | Assegna contesto alla tx selezionata e/o alle simili (Jaccard ≥ 35%) |
| 2c · Categoria | Corregge categoria/sottocategoria, salva regola deterministica, propaga alle simili |
Permette di eliminare in blocco transazioni selezionate tramite filtri combinabili:
| Filtro | Tipo |
|---|---|
| Da / A | Intervallo date |
| Conto | Account label esatto |
| Tipo | tx_type (expense, income, card_tx, …) |
| Descrizione | Ricerca ILIKE su description e raw_description
|
| Categoria | Categoria esatta |
Comportamento:
- Se nessun filtro è impostato il pulsante di eliminazione non è disponibile (protezione da cancellazione accidentale di tutto il DB)
- Il contatore mostra in tempo reale il numero di transazioni che verranno cancellate
- Un'anteprima espandibile mostra le prime 10 righe corrispondenti
- La conferma richiede di digitare esattamente
ELIMINAnel campo testo prima di abilitare il pulsante - L'eliminazione è irreversibile — assicurarsi di avere un backup prima di procedere (vedi
documents/deployment.md) - I link di riconciliazione e giroconti associati alle transazioni eliminate vengono rimossi in cascade
La pagina ✅ Check List mostra una tabella pivot mese × conto con il numero di transazioni presenti per ogni combinazione.
- Righe: mesi in ordine decrescente (mese corrente in cima, poi a ritroso fino al mese più vecchio con dati)
-
Colonne: tutti i conti definiti nella tabella
account+ eventualiaccount_labelpresenti nelle transazioni ma non ancora formalizzati come conto - Cella con transazioni: numero intero (colore proporzionale alla quantità)
- Cella senza transazioni: simbolo — in grigio chiaro
| Colore | Intervallo |
|---|---|
| Grigio (—) | 0 transazioni |
| Azzurro tenue | 1–4 transazioni |
| Azzurro medio | 5–19 transazioni |
| Azzurro scuro | ≥ 20 transazioni |
| Filtro | Effetto |
|---|---|
| Mostra solo conti | Riduce le colonne ai conti selezionati |
| Ultimi N mesi | Limita le righe agli ultimi N mesi (0 = tutti) |
| Nascondi mesi senza tx | Rimuove le righe con tutti zeri |
Tre KPI in cima alla pagina: transazioni totali, conti monitorati, mesi con dati.
Pulsante ⬇️ Scarica CSV per esportare la tabella filtrata.
File SQLite: ledger.db nella directory dell'applicazione.
Tabelle principali:
| Tabella | Contenuto |
|---|---|
transaction |
Tutte le transazioni importate |
import_batch |
Metadati di ogni importazione (file, schema, conteggi) |
document_schema |
Template schema per Flow 1 (fingerprint colonne → configurazione) |
reconciliation_link |
Coppie carta–c/c riconciliate |
internal_transfer_link |
Coppie giroconto |
category_rule |
Regole di categorizzazione utente |
description_rule |
Regole di pulizia descrizione in blocco |
taxonomy_category |
Categorie tassonomia |
taxonomy_subcategory |
Sottocategorie tassonomia |
import_job |
Stato corrente del job di importazione |
user_settings |
Preferenze utente (formato date, separatori, LLM, contesti) |
Le migrazioni dello schema sono idempotenti: vengono eseguite automaticamente ad ogni avvio senza perdita di dati.
Il layer FastAPI (api/) espone le stesse funzionalità del ledger via HTTP/JSON — indipendente dalla UI Streamlit, usabile da script, automazioni o future app mobile/desktop.
Porta: 8000 · Docs interattive: http://localhost:8000/docs
| Metodo | Path | Descrizione |
|---|---|---|
| GET | /health |
Liveness check |
| GET | /transactions |
Lista transazioni con filtri |
| PATCH | /transactions/{id}/category |
Aggiorna categoria/sottocategoria |
| PATCH | /transactions/{id}/context |
Aggiorna contesto di vita |
| POST | /transactions/{id}/toggle-giroconto |
Alterna flag giroconto |
| DELETE | /transactions |
Eliminazione massiva per filtro |
| GET | /rules/category |
Lista regole di categorizzazione |
| POST | /rules/category |
Crea regola |
| PATCH | /rules/category/{id} |
Modifica regola |
| DELETE | /rules/category/{id} |
Elimina regola |
| POST | /rules/category/apply-to-review |
Applica regole ai pending |
| POST | /rules/category/apply-to-all |
Applica regole a tutto il ledger |
| GET/POST/DELETE | /rules/description |
CRUD regole descrizione |
| GET | /settings |
Tutte le impostazioni (API key oscurate) |
| GET/PUT | /settings/{key} |
Lettura/scrittura impostazione |
| GET/POST/DELETE | /accounts |
CRUD conti bancari |
| GET/POST/PATCH/DELETE | /taxonomy/categories |
CRUD categorie |
| POST/PATCH/DELETE | /taxonomy/categories/{id}/subcategories |
CRUD sottocategorie |
| GET | /import/jobs/latest |
Stato ultimo job importazione |
| Parametro | Tipo | Descrizione |
|---|---|---|
from_date |
YYYY-MM-DD |
Data inizio |
to_date |
YYYY-MM-DD |
Data fine |
account_label |
string | Conto bancario |
category |
string | Categoria |
tx_type |
string | Tipo transazione |
to_review |
bool | Solo da rivedere |
limit |
int (1–5000) | Numero massimo risultati (default 500) |
offset |
int | Paginazione |
-
openai_api_keyeanthropic_api_keysono sempre oscurate (***) nelle risposte - Le stesse chiavi non sono modificabili via API (403) — solo dall'UI Impostazioni
-
DELETE /transactionsrichiede almeno un filtro (422 senza filtri)
# Installazione Docker one-liner (Mac/Linux)
curl -fsSL https://raw.githubusercontent.com/drake69/spendifai/main/installer/install.sh | bash
# Installazione Docker one-liner (Windows PowerShell)
# irm https://raw.githubusercontent.com/drake69/spendifai/main/installer/install.ps1 | iex
# Avvio sviluppo (build da sorgente)
uv run streamlit run app.pyApp disponibile su http://localhost:8501.