18 KiB
Executable File
Mini AI .202 - riconciliazione banca/incassi
Obiettivo
Usare la macchina .202 come motore di suggerimenti per riconciliare incassi, movimenti bancari e scritture contabili. La mini AI non deve scrivere sul gestionale: deve restituire proposte controllabili dall'operatore.
Primo perimetro reale
- Stabile:
0016/stabile_id=17 - Fonte incassi iniziale:
netgescon.incassi, importata dasingolo_anno.mdb.incassi - Fonte movimenti banca:
contabilita_movimenti_banca, import Fucino validato - Stato
in_da_ec: opzionale; se vuota, il payload usa automaticamentenetgescon.incassi
Configurazione NetGescon
Sul nodo applicativo impostare:
MINI_AI_ENABLED=true
MINI_AI_BASE_URL=http://192.168.0.202:8000
MINI_AI_RECONCILIATION_PATH=/api/v1/reconciliation/incassi
MINI_AI_TIMEOUT=30
Se la mini AI espone autenticazione bearer, aggiungere anche:
MINI_AI_TOKEN=<token locale della macchina .202>
Poi eseguire:
php artisan config:clear
php artisan netgescon:mini-ai-incassi --codice-stabile=0016 --limit=2 --dry-run
php artisan netgescon:mini-ai-incassi --codice-stabile=0016 --limit=20
Se la UI admin-filament/contabilita/incassi mostra Mini AI non abilitata, il controllo locale e:
php artisan tinker --execute='dump(config("services.mini_ai"));'
php artisan config:clear
La pagina salva comunque la richiesta in ai_requests, ma non prova la POST verso .202 finche MINI_AI_ENABLED=true non e attivo.
Endpoint atteso su .202
La macchina .202 deve esporre:
POST /api/v1/reconciliation/incassi
Input: JSON prodotto da NetGescon con:
task = reconcile_incassi_movimenti_bancarimode = read_only_suggestionssnapshot.metasnapshot.records[]snapshot.records[].payer_referencequando il bonifico contieneCoord.Ordinante,Banca Ordinante,Cro
Output richiesto:
{
"summary": "string",
"warnings": ["string"],
"suggestions": [
{
"legacy_key": "inc:11172",
"confidence": 0.82,
"suggested_incasso_id": 11172,
"suggested_movimento_id": 15800,
"suggested_action": "review",
"reason": "Importo coincidente; data lontana, richiede controllo umano.",
"allocations": [
{
"rate_id": 42230,
"amount": 177.00,
"ci": "C",
"gestione": "2024/25",
"reason": "Acconto gestione corrente indicato nella causale."
}
]
}
]
}
Regole operative HUB incassi
- La coda operativa deve mostrare solo movimenti banca interni alla finestra delle gestioni ordinarie aperte.
- Per lo stabile
0016la finestra verificata e2024/25+2025/26; la UI deve poter comunque spostare la competenza sulla gestione chiusa immediatamente precedente2023/24quando la causale banca indica saldi o conguagli dell anno precedente. - I riferimenti
Coord.Ordinante,Banca Ordinante,BIC/SWIFTeCROvanno trattati come indizi forti: se l operatore conferma il soggetto corretto, il mapping deve essere memorizzato per accelerare i pagamenti successivi della stessa banca/IBAN. - Nel blocco C/I dell HUB il nominativo operatore deve seguire questo ordine:
unita_immobiliari.denominazione, poigescon_import.condomin.nom_cond, solo in ultima istanzasoggettilegacy. - Le spese straordinarie aperte vanno tenute in una sezione separata dalle rate ordinarie e devono restare visibili fino a chiusura effettiva, anche se la coda operativa ordinaria lavora su una finestra di gestioni piu stretta.
- Nel riepilogo del C/I il gestionale deve esporre anche i parziali del dovuto per tipo (
ordinarie/straordinarie), per gestione e il totale generale dovuto: servono per solleciti e chiusure contabili in partita doppia. - Se una gestione straordinaria esiste in
gestioni_contabili/lavori_straordinarima non produce righe residue sull interno, la UI deve segnalarla come possibile buco di import/materializzazione delle spese straordinarie.
Azioni ammesse:
link: proposta molto forte, comunque da confermare in NetGesconreview: caso plausibile ma da verificareignore: non sembra riconciliabileduplicate: sospetto duplicato o movimento gia coperto
Prompt da dare all'agent sulla .202
Sei la mini AI banca/contabilita di NetGescon. Devi esporre un servizio HTTP locale su /api/v1/reconciliation/incassi che riceve snapshot JSON read-only da NetGescon.
Regole:
- Non scrivere mai sul gestionale.
- Non chiamare API di update.
- Restituisci solo suggerimenti JSON.
- Usa importo, data, descrizione, nominativo, scala/interno, ricevuta, protocollo e candidati movimento.
- Le spese bancarie ricorrenti, bolli, commissioni e canoni banca vanno classificate come casi facili ma non collegate a incassi condominiali.
- I CBILL vanno riconosciuti dal codice/causale quando presente.
- Se la confidenza e bassa o ci sono piu candidati simili, usa suggested_action=review.
- Se un movimento sembra gia registrato o duplicato, usa suggested_action=duplicate.
- Rispondi sempre con JSON valido: summary, warnings, suggestions[].
Schema suggestion:
legacy_key, confidence, suggested_incasso_id, suggested_movimento_id, suggested_action, reason, allocations[].
Quando il record contiene `candidate_rates`, devi valorizzare `allocations[]` con il sottoinsieme di rate selezionato. Ogni elemento deve contenere almeno: `rate_id`, `amount`, `ci`, `gestione`, `reason`.
Nella UI di NetGescon, le allocazioni della risposta vengono mostrate nel pannello mini AI e possono essere trasferite sulle imputazioni manuali del movimento selezionato con il comando `Applica allocazioni AI alle rate`.
La chiusura della riconciliazione resta comunque bloccata alla quadratura esatta tra importo banca e totale imputato.
Apprendimento progressivo
Nella prima fase l'apprendimento avviene salvando:
- payload inviato in
ai_requests.request_text - risposta in
ai_requests.response_text - feedback operatore nella UI incassi / feedback AI
Solo dopo una serie di risposte corrette si potra introdurre una tabella regole o una memoria dedicata per pattern ricorrenti come spese bancarie, CBILL, MAV e bonifici con causali standard.
Servizio persistente su .202 con systemd
Quando l'endpoint risponde correttamente ai test manuali, renderlo persistente con systemd. Esempio di unit, da adattare al percorso reale dell'app mini AI sulla .202:
[Unit]
Description=NetGescon Mini AI Reconciliation API
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=michele
WorkingDirectory=/home/michele/mini-ai-reconciliation
Environment=MINI_AI_TOKEN=
ExecStart=/home/michele/mini-ai-reconciliation/.venv/bin/uvicorn app:app --host 0.0.0.0 --port 8000 --workers 2
Restart=always
RestartSec=5
[Install]
WantedBy=multi-user.target
Comandi sulla .202:
sudo nano /etc/systemd/system/netgescon-mini-ai.service
sudo systemctl daemon-reload
sudo systemctl enable --now netgescon-mini-ai.service
sudo systemctl status netgescon-mini-ai.service
journalctl -u netgescon-mini-ai.service -f
Se si abilita token bearer, impostare MINI_AI_TOKEN nella unit e configurare lo stesso valore sul nodo NetGescon con MINI_AI_TOKEN=<token>. Non salvare token nei documenti o in chat.
Caso guida: Barone Michele, bonifico 1.285,70
Movimento banca reale:
contabilita_movimenti_banca.id = 15523- data
2025-01-16 - importo
1.285,70 - descrizione banca:
BONIFICO A VOSTRO FAVORE NETHOME DI BARONE MICHELE E C. SOCI Data Regolamento: 16/01/25 Coord.Ordinante: IT85 H010 3003 2710 0000 1540 577 Banca Ordinante: 01030/01697-PASCITMM Cro: A100267492801030480320003200IT Note: SALDO CONDOMINIO ANNO 2024 E ACC.TO 2025 E/C R IF. sc.B int.4 BARONE MICHELE Id.Operazione: 277385815
Comando NetGescon per generare il payload:
php artisan netgescon:mini-ai-incassi --movimento-id=15523 --limit=30 --dry-run > payload-barone-15523.json
curl -sS -X POST 'http://192.168.0.202:8000/api/v1/reconciliation/incassi' \
-H 'Content-Type: application/json' \
-d @payload-barone-15523.json
Regola attesa:
- leggere
sc.B int.4eBARONE MICHELE - attribuire il movimento al ramo
Cse le rate candidate sonoci=C - interpretare
SALDO CONDOMINIO ANNO 2024 E ACC.TO 2025come:- saldo gestione chiusa/adiacente
2023/24 - acconto gestione corrente
2024/25
- saldo gestione chiusa/adiacente
- non andare su gestioni molto vecchie
- non selezionare rate successive al pagamento se esiste una combinazione esatta sulle rate gia emesse alla data del versamento
- scegliere la combinazione che torna a
1.285,70
Allocazione attesa per il caso Barone:
{
"legacy_key": "mov:15523",
"confidence": 0.98,
"suggested_incasso_id": null,
"suggested_movimento_id": 15523,
"suggested_action": "link",
"reason": "La causale indica saldo condominio anno 2024 e acconto 2025; scala/interno e nominativo coincidono; la somma delle rate selezionate coincide con il bonifico.",
"allocations": [
{
"rate_id": 41225,
"amount": 87.84,
"ci": "C",
"gestione": "2023/24",
"reason": "Conguaglio esercizio precedente, saldo anno 2024."
},
{
"rate_id": 41457,
"amount": 87.84,
"ci": "C",
"gestione": "2023/24",
"reason": "Conguaglio esercizio precedente, saldo anno 2024."
},
{
"rate_id": 41261,
"amount": 87.84,
"ci": "C",
"gestione": "2023/24",
"reason": "Conguaglio esercizio precedente, saldo anno 2024."
},
{
"rate_id": 41077,
"amount": 241.00,
"ci": "C",
"gestione": "2023/24",
"reason": "Rata giugno-luglio 2024 inclusa nel saldo anno 2024."
},
{
"rate_id": 41517,
"amount": 241.00,
"ci": "C",
"gestione": "2023/24",
"reason": "Rata agosto-settembre 2024 inclusa nel saldo anno 2024."
},
{
"rate_id": 42230,
"amount": 177.00,
"ci": "C",
"gestione": "2024/25",
"reason": "Prima rata gestione 2024/25, acconto 2025."
},
{
"rate_id": 42276,
"amount": 177.00,
"ci": "C",
"gestione": "2024/25",
"reason": "Seconda rata gestione 2024/25, acconto 2025."
},
{
"rate_id": 41668,
"amount": 93.09,
"ci": "C",
"gestione": "2023/24",
"reason": "ATTO AeR ricevuto 05/07/24, prima rata."
},
{
"rate_id": 41597,
"amount": 93.09,
"ci": "C",
"gestione": "2023/24",
"reason": "ATTO AeR ricevuto 05/07/24, seconda rata."
}
]
}
Somma attesa allocations.amount: 1.285,70.
Nota per l'agent .202: nel payload Barone sono presenti anche rate candidate non selezionate. Non vanno scelte se non servono alla quadratura o se sono fuori dalla causale. In particolare, con questa causale non selezionare rate provvisorie vecchie o la 3/6 Rata FEBBRAIO-MARZO 25 se la combinazione sopra quadra gia esattamente.
Caso guida: Barone Michele, bonifico 960,79
Movimento banca reale:
contabilita_movimenti_banca.id = 15953- data
2025-12-23 - importo
960,79 - descrizione banca:
BONIFICO A VOSTRO FAVORE NETHOME DI BARONE MICHELE E C. SOCI Data Regolamento: 23/12/25 Coord.Ordinante: IT85 H010 3003 2710 0000 1540 577 Banca Ordinante: 01030/01697-PASCITMM Cro: A108446418101030480320003200IT Note: SALDO CONDOMINIO ANNO 2025 E ACC.TO 2026 E/C R IF. sc.B int.4 BARONE MICHELE Id.Operazione: 304017429
Comando NetGescon per generare il payload:
php artisan netgescon:mini-ai-incassi --movimento-id=15953 --limit=40 --dry-run > payload-barone-15953.json
curl -sS -X POST 'http://192.168.0.202:8000/api/v1/reconciliation/incassi' \
-H 'Content-Type: application/json' \
-d @payload-barone-15953.json
Regola attesa:
- leggere
sc.B int.4eBARONE MICHELE - attribuire il movimento al ramo
Cse le rate candidate sonoci=C - interpretare
SALDO CONDOMINIO ANNO 2025 E ACC.TO 2026come:- saldo gestione
2024/25 - acconto gestione
2025/26
- saldo gestione
- includere i conguagli negativi se servono alla quadratura
- non selezionare rate successive non necessarie se esiste una combinazione esatta
- scegliere la combinazione che torna a
960,79
Allocazione attesa:
{
"legacy_key": "mov:15953",
"confidence": 0.98,
"suggested_incasso_id": null,
"suggested_movimento_id": 15953,
"suggested_action": "link",
"reason": "La causale indica saldo condominio anno 2025 e acconto 2026; scala/interno e nominativo coincidono; la somma delle rate selezionate coincide con il bonifico.",
"allocations": [
{
"rate_id": 41878,
"amount": 177.00,
"ci": "C",
"gestione": "2024/25",
"reason": "3/6 rata gestione 2024/25, saldo anno 2025."
},
{
"rate_id": 42355,
"amount": 177.00,
"ci": "C",
"gestione": "2024/25",
"reason": "4/6 rata gestione 2024/25, saldo anno 2025."
},
{
"rate_id": 42546,
"amount": -0.61,
"ci": "C",
"gestione": "2024/25",
"reason": "Conguaglio negativo da includere nella quadratura."
},
{
"rate_id": 42468,
"amount": 177.00,
"ci": "C",
"gestione": "2024/25",
"reason": "5/6 rata gestione 2024/25, saldo anno 2025."
},
{
"rate_id": 42706,
"amount": 177.00,
"ci": "C",
"gestione": "2024/25",
"reason": "6/6 rata gestione 2024/25, saldo anno 2025."
},
{
"rate_id": 42803,
"amount": 177.00,
"ci": "C",
"gestione": "2025/26",
"reason": "Prima rata gestione 2025/26, acconto 2026."
},
{
"rate_id": 42134,
"amount": 38.20,
"ci": "C",
"gestione": "2024/25",
"reason": "Lav. facciata lato parrocchia, prima rata capitolato."
},
{
"rate_id": 42194,
"amount": 38.20,
"ci": "C",
"gestione": "2024/25",
"reason": "Lav. facciata lato parrocchia, seconda rata capitolato."
}
]
}
Somma attesa allocations.amount: 960,79.
Nota per l'agent .202: nel payload mov:15953 sono presenti anche rate candidate non selezionate, come 1/6 e 2/6 2024/25 o rate successive 2025/26. Non vanno scelte se il saldo indicato dalla causale quadra gia con la combinazione sopra.
BUG risolto nel primo collaudo
Il payload da 20 righe supera 64 KB; ai_requests.request_text e response_text devono essere LONGTEXT. La migration 2026_06_07_130000_expand_ai_requests_text_columns.php applica questa correzione.
Collaudo end-to-end 07/06/2026
Endpoint .202 verificato:
POST http://192.168.0.202:8000/api/v1/reconciliation/incassi
Esito con payload di esempio fornito dall'agent .202:
- HTTP
200 - risposta valida con
summary,warnings,suggestions[] - match forte su esempio
inc:11172 -> movimento 15800,confidence=0.99,suggested_action=link
Esito con payload reale prodotto da NetGescon:
MINI_AI_ENABLED=true MINI_AI_BASE_URL=http://192.168.0.202:8000 MINI_AI_RECONCILIATION_PATH=/api/v1/reconciliation/incassi php artisan netgescon:mini-ai-incassi --codice-stabile=0016 --limit=2
ai_request_id=2- risposta ricevuta e salvata in
ai_requests status=answeredrequest_len=4600response_len=734- risposta:
2 record analizzati; 2 review - suggerimenti su
inc:11172 -> movimento 15800einc:11170 -> movimento 15822, entrambiconfidence=0.45esuggested_action=review
Interpretazione: il collegamento funziona. La qualita del suggerimento e volutamente prudente per i primi dati reali, perche i candidati hanno importi uguali ma date distanti o ambigue.
Esito successivo con payload movimento Barone:
- comando:
php artisan netgescon:mini-ai-incassi --movimento-id=15523 --limit=30 - richiesta generata:
legacy_key=mov:15523,candidate_rates=14 - risposta
.202attuale: link al movimento conconfidence=0.99, ma senzaallocations[] - prossimo aggiornamento richiesto all'agent
.202: usarecandidate_ratese restituire la scomposizione rate nel formato indicato sopra.
Esito con payload movimento Barone 960,79:
- comando:
php artisan netgescon:mini-ai-incassi --movimento-id=15953 --limit=40 - richiesta generata:
legacy_key=mov:15953,candidate_rates=12 - risposta
.202attuale: link al movimento conconfidence=0.99, maallocations=[] - prossimo aggiornamento richiesto all'agent
.202: includere conguagli negativi e selezionare il sottoinsieme esatto da960,79.
Caso guida: Caschetto Lucia / Curatola Antonio, bonifico 1.968,23
Movimento banca reale:
contabilita_movimenti_banca.id = 15803- data
2026-04-30 - importo
1.968,23 - descrizione banca:
BONIFICO A VOSTRO FAVORE CURATOLA ANTONIO Data Regolamento: 30/04/26 Coord.Ordinante: IT57 F020 0805 2120 0000 3789 819 Banca Ordinante: 01020/02080-UNCRITMM Cro: 1101261190461826 Note: estratto conto condominiale Germanico 96 del 0 8.04.2026 Id.Operazione: NOTPROVIDED
Particolarita anagrafica:
- il bonifico non indica
B/18 - il nominativo banca e
Curatola Antonio - nel legacy l'unita corretta e
B/18 - Caschetto Lucia gescon_import.condomin.presso = c/o Avv. Curatolagescon_import.condomin.e_mail_condominocontienecuratola.antonio@libero.it,lcaschetto@gmail.com
Regola attesa:
- usare
pressoed email come alias di riconoscimento, senza cambiare il nominativo principale della unita - mantenere
Caschetto Luciacome intestatario principale - usare le rate candidate
ci=C - scegliere tutte le 12 rate candidate perche la somma coincide con
1.968,23
Esito test NetGescon:
php artisan netgescon:mini-ai-incassi --movimento-id=15803 --limit=40 --dry-run
legacy_key=mov:15803nominativo=Caschetto Luciascala=B,interno=18candidate_rates=12- somma candidate
1.968,23
Esito .202 dopo aggiornamento agent:
ai_request_id=5confidence=0.98suggested_action=linkallocations[]valorizzato con le 12 rate candidate- risposta corretta per il primo caso con alias
presso/email