netgescon-day0/docs/support/BUG-RISOLTI-E-VALIDAZIONI.md

36 KiB
Executable File

Bug risolti e validazioni

Obiettivo

Questa sezione tiene separato il materiale di fix dal manuale generale. Qui annotiamo:

  • bug corretti
  • fix applicato
  • stato della verifica
  • eventuali controlli ancora da fare su staging

Registro sintetico

Import GESCON: fallback storico su id_cond quando il legacy sposta cod_cond

  • Problema: in archivi come 0026 il vecchio amministratore ha riallineato i nominativi nel legacy spostando cod_cond tra una gestione e la successiva, mentre id_cond e rimasto stabile. Questo rompeva import di unita, cronologia nominativi, rate e incassi perche il dominio usava ancora cod_cond come chiave forte.
  • Causa tecnica: ImportGesconFullPipeline preferiva cod_cond per valorizzare unita_immobiliari.legacy_cond_id, ricostruiva la storia condomin filtrando cod_cond e risolveva le unita di rate/incassi dal solo cod_cond senza ancora stabile su id_cond.
  • Fix applicato: app/Console/Commands/ImportGesconFullPipeline.php ora ancora il dominio su id_cond / legacy_id_cond, usa cod_cond come fallback annuale e, per la cronologia condomin, prova prima id_cond e poi il nominativo (nom_cond / proprietario_denominazione) se il codice annuale non basta. La UI di Importazione archivi e stata anche orientata sul flusso ultima aperta -> ritroso.
  • Stato: [P] validato su codice, helper privato e smoke test reale 0026/0001: extractStableLegacyCondId() preferisce id_cond rispetto a cod_cond e l'import reale sul tenant stabile_id=32 completa correttamente il ciclo. La verifica specifica dello shift cross-year di cod_cond resta pendente finche lo staging non espone piu annualita dello stesso stabile.

Import GESCON 0026: rerun non idempotente su rate_emesse e dati_bancari

  • Problema: rilanciando gescon:import-full su 0026 / anno 0001 / stabile_id=32 il numero righe restava stabile ma la somma di rate_emesse raddoppiava (11300.27 -> 22600.54) e dati_bancari cresceva a ogni rerun (3 -> 4 -> 5) pur trattandosi dello stesso conto CCB.
  • Causa tecnica: nel ramo update di stepRate() gli importi venivano ricalcolati come existing + importo, quindi ogni reimport aggiungeva di nuovo lo stesso addebito; in stepBanche() il lookup dell'esistente usava $iban e $numero originali invece dei valori realmente risolti (resolvedIban e fallback cod_cassa), mancando il match e inserendo duplicati.
  • Fix applicato: app/Console/Commands/ImportGesconFullPipeline.php ora rende idempotente l'update di rate_emesse azzerando il baseline del record al primo touch del run e aggregando solo gli eventuali duplicati della stessa esecuzione; stepBanche() usa i valori risolti per il match e consolida gli esatti duplicati gia presenti sullo stesso conto.
  • Stato: [U] validato end-to-end su 0026 / anno 0001 / stabile_id=32 con tre esecuzioni consecutive del comando. Contatori finali: rate_emesse=81, rate_emesse_sum_addebitato=11300.27, dati_bancari=1, incassi=0.

Staging GESCON operazioni: scope stabile assente e reload non idempotente

  • Problema: la tab Filament admin-filament/gescon/ordinarie filtra operazioni per stabile solo se nello staging esiste cod_stabile. Nel database di sessione la tabella gescon_import.operazioni era stata creata senza quella colonna, quindi il tab Operazioni poteva mischiare scritture di stabili diversi. Al primo tentativo di riallineamento i reload slice-aware fallivano inoltre con duplicate key sulle righe gia presenti.
  • Causa tecnica: LoadGesconMdbToStaging valorizzava cod_stabile e legacy_year solo se le colonne esistevano gia, ma non faceva evoluzione schema sulle tabelle storiche create in precedenza. In piu il caricamento di operazioni usava solo insert, quindi un reload sullo stesso id_operaz collassava sulla PK legacy invece di aggiornare la riga esistente.
  • Fix applicato: app/Console/Commands/LoadGesconMdbToStaging.php ora aggiunge in best-effort le colonne di slice mancanti (cod_stabile, legacy_year) alla tabella di staging selezionata e, per operazioni, rende il reload idempotente con updateOrInsert su id_operaz.
  • Stato: [U] validato in sessione. Reload riusciti su 0016/0914, 0016/0913, 0016/0912 con staging finale annotato 0016|0914|61, 0016|0913|168, 0016|0912|250. Per 0026/0001 operazioni resta 0, coerente con il contenuto del file annuale in questa sessione.

Ordinarie legacy e import banca Fucino su 0016

  • Problema: admin-filament/gescon/ordinarie andava in Undefined variable $query nel mapping delle righe Operazioni. In parallelo la sezione legacy incassi su 0016 continuava a vedere righe duplicate perche convivevano slice annuali corrette (legacy_year=0912/0913/0914) e righe storiche orfane con legacy_year=null. Sul lato banca, i file reali Banca del Fucino arrivavano in .xls e la UI esponeva ancora il formato come solo XLSX.
  • Causa tecnica: in Ordinarie.php era rimasta una chiamata a $query->where(...) dentro una map() dove il builder non esiste. Per incassi mancava una regola di preferenza per gli slice annuali annotati, quindi i record orfani di staging continuavano a inquinare UI e import dominio. La UI movimenti banca accettava di fatto Excel legacy via parser, ma non lo dichiarava esplicitamente nei form.
  • Fix applicato: rimosso il riferimento fuori scope in app/Filament/Pages/Gescon/Ordinarie.php; applyIncassiFilters() e ImportGesconFullPipeline::stepIncassi() ora ignorano le righe legacy_year=null quando per lo stesso stabile esistono gia slice annotate. Nello staging gescon_import.incassi e stato anche eseguito un cleanup mirato che ha eliminato 1753 righe orfane nulle duplicate di slice gia ricaricate. La UI banca in CasseBancheMovimenti e DatiBancariDettaglio dichiara ora anche .xls e il formato Excel XLS/XLSX.
  • Stato: [U] validato in sessione. getOperazioniProperty() torna a costruire un LengthAwarePaginator; operazioni duplicate esatte su 0016/0026 = 0; incassi duplicate esatte su 0016/0026 = 0 dopo il cleanup dei null orphan. Importati su 0016 / stabile_id=17 / conto_id=14 / legacy_cod_cassa=CCB 1935 movimenti banca da file Fucino, con range 2022-02-03 -> 2026-06-03; 891 righe sono state scartate come duplicati attesi fra estratti sovrapposti.

Consultazione legacy-aligned: gestioni visibili vs gestioni conteggiabili

  • Problema: sia l'estratto conto soggetto sia la scheda unità filtravano i dati con la logica del solo anno attivo, mentre per il controllo legacy serve una distinzione piu precisa: anni correnti da conteggiare, ultima gestione chiusa ancora visibile per confronto, storico piu vecchio nascosto salvo filtro.
  • Causa tecnica: la UI usava AnnoGestioneContext come unico discriminante temporale; gestioni_contabili non veniva usata per decidere se un esercizio fosse solo consultabile oppure ancora conteggiabile nel dovuto corrente.
  • Fix applicato: e stato introdotto app/Support/GestioneVisibility.php. Regola attuale: anni visibili = tutte le gestioni aperte/attive + l'ultima gestione chiusa; anni conteggiabili = solo gestioni aperte/attive. EstrattoContoSoggetto, UnitaImmobiliarePage e GestioniArchivio usano ora questa policy per nascondere lo storico piu vecchio e togliere dal dovuto gli esercizi chiusi mantenuti solo per controllo.
  • Stato: [U] validato in sessione. Per stabile_id=17 (0016) la policy finale e visible_years=[2025,2024,2023], countable_years=[2025,2024], closed_visible_years=[2023]. Verifica tecnica su scheda unità: unita_id=660 scende a 24 rate e 12 incassi visibili, unita_id=662 a 48 rate e 62 incassi visibili, con range anni 2023 -> 2025.

Super Admin ACL: HUB rapido a matrice per programmi

  • Problema: la gestione ACL programmi era disponibile solo nella scheda dettaglio allow/deny, poco adatta a variazioni rapide per gruppi principali.
  • Causa tecnica: mancava una vista a matrice ruolo-programma che permettesse di abilitare o disabilitare velocemente la visibilita per ruolo.
  • Fix applicato: app/Filament/Pages/SuperAdmin/ProgrammiAcl.php e resources/views/filament/pages/super-admin/programmi-acl.blade.php ora espongono un HUB con matrice programmi x ruoli, checkbox rapidi e reset al default catalogo; la scheda esistente e stata mantenuta come tab separata. E stata aggiunta anche una seconda tab che mostra il baseline attuale R/W per gruppi/menu, in attesa di un backend dedicato agli override granulari.
  • Stato: [U] validato localmente: nessun errore editor sulla page Filament e sulla blade.

Palazzine stabile: mappa visiva per scala, piano e adiacenze

  • Problema: la vista admin-filament/condomini/stabile?tab=palazzine era disallineata e poco utile per gestire incidenti tecnici come perdite d acqua, dove serve capire subito chi sta accanto, sopra e sotto una unità.
  • Causa tecnica: la pagina mostrava solo card riassuntive per palazzina, senza ordinamento operativo delle unita e senza una lettura per scala/piano/interno.
  • Fix applicato: app/Http/Controllers/Admin/PalazzineController.php ora ordina le unita per scala, piano e interno; resources/views/admin/palazzine/index.blade.php espone una mappa per scala e per piano con card unita che mostrano adiacenze orizzontali e riferimenti verticali (accanto, sopra, sotto).
  • Stato: [U] validato localmente: nessun errore editor su controller e blade.

Unita immobiliare 0016: estratto vuoto con incassi presenti e relazioni correnti discordanti

  • Problema: sulle unità 0016-B-4 (unita_id=660, legacy_cond_id=49) e 0016-B-5 (unita_id=662, legacy_cond_id=50) la scheda unità mostrava Persone collegate incoerenti e l estratto rate & incassi vuoto, pur avendo incassi importati per i codici legacy 49/50.
  • Causa tecnica: per 0016 non esistono righe in rate_emesse (0 su stabile_id=17), mentre sono presenti 3789 righe nella tabella legacy gescon_import.rate; la pagina unità leggeva solo rate_emesse e costruiva gli incassi partendo dalle note delle rate emesse. In piu, quando proprieta e rubrica_ruoli/persone_unita_relazioni non concordavano, la sezione persone privilegiava i diritti proprietari storici.
  • Fix applicato: app/Filament/Pages/UnitaImmobiliarePage.php ora usa un fallback legacy su gescon_import.rate e incassi quando una unità non ha rate_emesse; per Persone collegate preferisce la storia legata alla unità (unita_immobiliare_nominativi) e integra i comproprietari legacy correnti della stessa legacy_cond_id quando la materializzazione storica manca o è incompleta. La testata della scheda non mostra piu come etichetta un nominativo storico scaduto, ma ripiega sul codice unità.
  • Stato: [U] validato via hydration diretta pagina. unita_id=660 torna con 48 righe estratto e 38 incassi e come proprietario corrente Le Foche Ermanno-Bianchin M.; unita_id=662 torna con 96 righe estratto e 78 incassi e mostra Barone Michele piu i comproprietari legacy correnti Nardi Camillo e Flavia e Nardi Flavia.

Unita immobiliare 0016: payload legacy completo, CF corretti, selettore corrente e bonifica incassi

  • Problema: dopo l allineamento di 0016, la ricerca nominativi apriva la unità giusta ma il selettore restava su etichette storiche (MASTRANGELI...), i CF in pagina continuavano a derivare da rubrica stantia, i blocchi cond_* / catasto_* / pertinenze_* / diritti_* / inquilin_* non arrivavano fino alla UI e l estratto compatto mostrava ancora righe duplicate o a zero.
  • Causa tecnica: unita_immobiliare_nominativi.legacy_payload salvava solo un sottoinsieme dei campi legacy; gescon:materialize-persone-relazioni privilegiava CF/contatti gia presenti in rubrica; gescon:sync-rubrica-ruoli non correggeva i record esistenti; refreshUnitaOptions() leggeva proprieta; nella contabilità incassi su stabile_id=17 erano rimaste 936 righe duplicate extra e 207 righe a importo zero.
  • Fix applicato: ImportGesconFullPipeline ora salva nei payload i prefissi cond_*, catasto_*, pertinenze_*, diritti_*, inquilin_* e usa condomin.inquilin_contratto_dal / inquilin_cod_fisc; GesconMaterializePersoneRelazioniCommand usa legacy_payload come sorgente autorevole per CF/contatti e puo correggere CF/P.IVA stantii se univoci; GesconSyncRubricaRuoli aggiorna la rubrica da Persona; UnitaImmobiliarePage usa il nominativo attivo di unita_immobiliare_nominativi nel selettore e mostra in cronologia anche CF, contratto e catasto; resources/views/filament/pages/unita-immobiliare.blade.php compatta l estratto in una riga principale per rata/conguaglio con dovuto, pagato e data pagamento. Sul DB incassi di 0016 e stata eseguita una bonifica stretta che ha eliminato tutti i duplicati esatti e tutte le righe a zero senza associazioni utili.
  • Stato: [U] validato localmente sul DB. incassi per condominio_id=17: duplicate_extra_rows = 0, zero_total = 0, remaining_total = 2102. La UI e pronta a usare i payload completi non appena termina il rebuild --solo=unita -> --solo=relazioni -> gescon:sync-rubrica-ruoli in corso sulla sessione.

Unita immobiliare 0016: estratto compatto cross-year da rate_emissioni_dettaglio con split C/I

  • Problema: l estratto compatto della scheda unità continuava a leggere solo gescon_import.rate o le rate_emesse dominio, perdendo la distinzione C/I, il periodo reale di gestione (2024/25, 2025/26) e i riferimenti avviso richiesti dal legacy; in piu legacy_cond_id su alcune unità (B-4) era ormai storico e non bastava piu per recuperare tutte le righe corrette della stessa unità.
  • Causa tecnica: UnitaImmobiliarePage risolveva i cod_cond correnti da gescon_import.condomin, ma quando questi esistevano smetteva di considerare il legacy_cond_id salvato sull unità; su 0016-B-4 questo faceva perdere proprio il ramo autoritativo cod_cond=47 di rate_emissioni_dettaglio. La Blade inoltre mostrava il riferimento proprietario dal set relazioni/comproprietari invece che dal record condomin corrente.
  • Fix applicato: la pagina mantiene tutti i candidati cod_cond ma, per l estratto compatto da rate_emissioni_dettaglio, preferisce il legacy_cond_id salvato quando esistono righe reali sulla stessa unità/stabile; su 0016-B-4 questo ancora il rendering a cod_cond=47. La scheda unità continua a usare rate_emissioni_dettaglio come sorgente prioritaria, separa i movimenti C/I in Blade, raggruppa per anno_gestione e per il campo Condomino di riferimento espone condomin.nom_cond invece del primo non-comproprietario trovato nelle relazioni.
  • Stato: [U] validato via reflection sulla pagina per unita_id=658. Con gestione=2024/25 il campione autoritativo restituito ora e 52 -> 177,00, 196 -> 177,00, 268 -> 177,00, 626 -> 177,00, 697 -> 177,00, 697 -> Conguaglio es.precedente -0,61, 766 -> 177,00, tutti tipo=C; getLegacyCondominoRiferimentoNome() restituisce Barone Michele.

Import rate 0016: popolamento gestioni_annuali da generale_stabile.mdb

  • Problema: per 0016 la staging gescon_import.gestioni_annuali era vuota, quindi la UI non aveva una fonte stabile per i periodi ordinaria_dal / ordinaria_al e il reload rate restava calendar-year biased.
  • Causa tecnica: il pipeline gescon:import-full --solo=rate non popolava gestioni_annuali dal generale_stabile.mdb prima di materializzare piani/rate dominio.
  • Fix applicato: ImportGesconFullPipeline ora sincronizza gestioni_annuali dalla tabella anni di generale_stabile.mdb all avvio dello step rate, salvando almeno cartella, anno_ordinario, ordinaria_dal, ordinaria_al, riscaldamento_dal, riscaldamento_al e payload raw. Nelle note delle rate_emesse vengono inoltre persistiti anno_gestione, numero_ricevuta, legacy_year, cond_inq e avviso_code.
  • Stato: [P] validato sul DB con gestioni_annuali_0016 = 6 e rate_emesse_0016 = 2517 dopo php artisan gescon:import-full --stabile=0016 --solo=rate. La UI compatta usa gia la sorgente staging corretta; il dominio storico importato prima del fix avviso mantiene ancora alcuni avviso_code precedenti finche non si esegue un reload pulito dedicato delle sole rate_emesse esistenti.

Gestioni contabili 0016: tab stabile allineato ai periodi cross-year reali

  • Problema: il tab gestioni dello stabile continuava a mostrare esercizi dominio con periodi 01/01-31/12, anche quando generale_stabile.mdb -> anni definiva esercizi reali 2024/25, 2025/26 con date ordinarie_dal/al.
  • Causa tecnica: ImportGestioniFromLegacy e la sync automatica del tab stabile creavano o selezionavano gestioni_contabili usando solo anno_gestione numerico, senza preferire la riga legacy canonica e senza applicare i periodi di gestioni_annuali.
  • Fix applicato: ImportGestioniFromLegacy, ImportGesconFullPipeline e GestioniStabileTable ora derivano label e date da gestioni_annuali/anni, preferiscono la riga canonica con label cross-year (Ordinaria 2024/25) e nel tab stabile filtrano la sola gestione canonica per tenant + stabile + anno + tipo.
  • Stato: [U] validato su 0016 con php artisan gescon:import-gestioni --stabile=0016; selezione canonica verificata via query applicativa: 2024 | ordinaria | Ordinaria 2024/25 | 2024-10-01 | 2025-09-30, 2025 | ordinaria | Ordinaria 2025/26 | 2025-10-01 | 2026-09-30.

Estratto conto soggetto: esposizione vecchia numerazione legacy

  • Problema: nelle rate_emesse rielaborate o lavorate manualmente l estratto conto soggetto mostrava il progressivo dominio ma non il riferimento legacy completo richiesto dall operatività (Gestione 2024/25 · ricevuta n.138).
  • Causa tecnica: EstrattoContoSoggetto leggeva dalle note solo n_emissione, ignorando metadati gia presenti come anno_gestione, numero_ricevuta e avviso_code.
  • Fix applicato: la pagina ora estrae dai metadati note anno_gestione, numero_ricevuta e avviso_code e rende sotto la descrizione un riferimento esplicito tipo Gestione 2024/25 · ricevuta n.138, con fallback su avviso legacy se la ricevuta manca.
  • Stato: [U] validato via reflection sull helper buildLegacyReferenceLabel() con output Gestione 2024/25 · ricevuta n.138.

Estratto conto soggetto 0016-B-4: nominativo in testata preso dal soggetto storico e non dalla unità corrente

  • Problema: l URL admin-filament/contabilita/estratto-conto/7680?vista=unita&unita_id=658 mostrava in testata Leardini Alessandra anche se l unità 0016-B-4 ha come riferimento corrente Barone Michele.
  • Causa tecnica: EstrattoContoSoggetto usava sempre il record route (soggetti.id=7680) per nome e CF header. Per B-4 quel record e storico: unita_immobiliari.id=658 ha ancora legacy_cond_id=47, che coincide con soggetti.old_id=47 (Leardini Alessandra). Le relazioni correnti dell unità sono invece Michele Barone proprietario e Claudia Francioni comproprietaria.
  • Fix applicato: in vista=unita la pagina non si limita piu all header ma, se l unità ha un dataset legacy autoritativo in rate_emissioni_dettaglio, costruisce direttamente righe, gruppi, riferimento proprietario e collegamenti soggetto da quel ramo. La testata espone quindi Barone Michele, CF BRNMHL69M11H501K, recordCondominoId=7682, mentre le righe 2024/25 usano numero_ricevuta come riferimento primario (52, 196, 268, 626, 697, 766) e conservano l avviso come avviso_legacy (202410, 202412, ...).
  • Stato: [U] validato via hydration diretta del ramo legacy su unita_id=658: header = Barone Michele / BRNMHL69M11H501K, Gestione 2024/25 · ricevuta n.52, dovuto = 177,00, recordCondominoId = 7682, incassi_count = 56.

Scheda unità 0016-B-4: Condomino di riferimento da condomin

  • Problema: nella scheda unità il blocco riepilogo poteva mostrare un nominativo derivato dal primo proprietario attivo non comproprietario, mentre per 0016-B-4 il riferimento richiesto doveva essere il dato corrente di gescon_import.condomin.
  • Causa tecnica: la Blade costruiva Condomino di riferimento solo da relazioniPerTipo['proprietari'], che e un insieme misto di diritti, relazioni attive, archivio unità e comproprietari legacy.
  • Fix applicato: UnitaImmobiliarePage espone ora getLegacyCondominoRiferimentoNome() e getLegacyCondominoRiferimentoCodiceFiscale(). La Blade usa quindi condomin.nom_cond e condomin.cond_cod_fisc prima delle relazioni, mentre il picker unità corrente forza la stessa anagrafica legacy autorevole.
  • Stato: [U] validato su unita_id=658 con output Barone Michele, CF BRNMHL69M11H501K, picker 0016-B-4 — Barone Michele.

Estratto 0016-B-4: i numeri 2024/25 correnti non coincidono col campione legacy operativo

  • Problema: il campione operativo fornito dall utente per GESTIONE ORDINARIA - Es.2024/25 - (Sc. B / Int. 4) usa importi/ricevute come 52 -> 177,00, 196 -> 177,00, 268 -> 177,00, pagamenti valorizzati (16 gen 25, 23 dic 25) e conguaglio finale -3,51. L estratto dominio corrente non riflette questi valori.
  • Evidenza tecnica: per rate_emesse dominio su unita_immobiliare_id=658 nel periodo 2024-10-01 -> 2025-09-30 risultano ancora righe spezzate come 55 -> 5,00, 56 -> 157,00, 199 -> 5,00, 200 -> 157,00, 629 -> 5,00, 630 -> 157,00, con importo_pagato = 0,00 sul soggetto storico 7680. La staging autoritativa rate_emissioni_dettaglio, se interrogata sul ramo corretto cod_cond=47, raggruppamento=99, anno_emissione=0913, coincide invece col campione operativo lato righe emesse: 52, 196, 268, 626, 697, 766 a 177,00 e 697 -> Conguaglio es.precedente -0,61.
  • Stato: [P] controllato e ristretto: il mismatch residuo e sul dominio rate_emesse e sulle viste che leggono ancora quel ramo, mentre la scheda unità legacy di 0016-B-4 ora usa il dataset staging autoritativo corretto.

Incassi 0016-B-4: bonifico legacy 1.285,70 non ancora importato nel ramo applicativo

  • Problema: il bonifico legacy descritto dall operatività (protocollo=1663, num_incasso=350, data_pag=14/01/25, id_condomino=47, sc_int=B/4, nome_condomino=Barone Michele, importo=1.285,70) deve diventare il punto di aggancio per la riconciliazione con il movimento banca Fucino del 16/01/2025, ma oggi non e ancora disponibile nella UI applicativa.
  • Evidenza tecnica: nella staging attuale non esiste ancora la tabella gescon_import.in_da_ec, quindi il protocollo legacy non e interrogabile in app; inoltre nella tabella applicativa incassi (condominio_id=17) non risultano ancora righe con importo_pagato_euro/importo_pagato = 1285,70.
  • Stato: [P] controllato in sessione. Il ramo incassi visibile oggi per 0016-B-4 e parziale (56 righe sull estratto legacy unità) ma non contiene ancora il pagamento cardine 1.285,70; il prossimo passo tecnico obbligato e importare/materializzare in_da_ec o un suo equivalente staging prima della riconciliazione banca.

HUB incassi 0016: staging in_da_ec, snapshot read-only e API interna per mini AI

  • Problema: l HUB admin-filament/contabilita/incassi mostrava solo il ramo dominio incassi, quindi non c era un punto unico per vedere i movimenti legacy da estratto conto e passare un payload in sola lettura alla macchina interna .202 / mini AI.
  • Causa tecnica: mancavano sia la tabella di staging gescon_import.in_da_ec sia una materializzazione read-only nel dominio; inoltre la page Filament non esponeva ancora un payload aggregato o un endpoint autenticato dedicato.
  • Fix applicato: LoadGesconMdbToStaging ora supporta in_da_ec con alias MDB (Inc_da_ec) e crea la tabella di staging se assente; ImportGesconFullPipeline precarica in_da_ec da generale_stabile.mdb e materializza le righe in incassi_estratto_conto con hash idempotente, gestione_id, pattern_scala/interno e metadati_gescon. IncassiArchivio espone una nuova sezione HUB read-only con payload JSON cumulativo e candidati incassi / movimenti_bancari, mentre GET api/v1/incassi/hub fornisce lo stesso snapshot via auth:sanctum.
  • Stato: [U] validato localmente a livello runtime e sintassi. php artisan route:list --path=api/v1/incassi/hub registra la rotta; IncassiHubReadService::forStabile(17, 2) risponde correttamente con source = gescon_import.in_da_ec e records_count = 0 finche lo staging non viene popolato dal MDB reale.

Mini AI .202: chiamata read-only su incassi reali da singolo_anno.mdb

  • Problema: per iniziare a lavorare su dati reali serve chiamare la macchina .202 senza ancora automatizzare la riconciliazione, usando come primo dataset gli incassi gia importati da singolo_anno.mdb.incassi e i movimenti Fucino in contabilita_movimenti_banca.
  • Causa tecnica: il primo payload HUB ripiegava solo su in_da_ec, oggi non popolata; inoltre il matching candidati guardava la vecchia tabella movimenti_bancari invece della tabella operativa usata dall import Fucino. Il primo click sul pulsante poteva inoltre fallire con QueryException per payload troppo grande salvato in ai_requests.request_text (TEXT, circa 64 KB).
  • Fix applicato: aggiunto MiniAiReconciliationClient, comando php artisan netgescon:mini-ai-incassi, configurazione services.mini_ai e pulsante Invia a mini AI nell HUB incassi. IncassiHubReadService ora usa come fallback netgescon.incassi e cerca candidati in contabilita_movimenti_banca; ogni chiamata salva richiesta e risposta in ai_requests con contesto incassi-hub-mini-ai. La migration 2026_06_07_130000_expand_ai_requests_text_columns.php porta request_text e response_text a LONGTEXT.
  • Stato: [U] validato localmente con dry-run su 0016: payload task=reconcile_incassi_movimenti_bancari, source=netgescon.incassi, records_count=2, incasso reale inc:11172 e candidati movimento da contabilita_movimenti_banca. Il percorso backend del pulsante salva ora una richiesta da 290163 caratteri in ai_requests senza QueryException. Collaudo reale verso .202 riuscito con ai_request_id=2, status=answered, risposta JSON valida e due suggerimenti review salvati.

Mini AI .202: riconoscimento alias presso/email e caso Caschetto B-18

  • Problema: il bonifico di 1.968,23 del 30/04/2026 arriva in banca come CURATOLA ANTONIO, senza scala/interno nella causale principale e senza nominativo Caschetto Lucia; il legame reale e solo nel legacy (presso = c/o Avv. Curatola, email curatola.antonio@...) della unità 0016-B-18.
  • Causa tecnica: il resolver del payload mini AI cercava solo nominativo diretto o scala/interno; non normalizzava alias distribuiti su presso ed email, quindi non riusciva ad attribuire il movimento a Caschetto Lucia.
  • Fix applicato: IncassiHubReadService ora estrae il nominativo banca da A VOSTRO FAVORE ... Data Regolamento e risolve il legacy cercando token normalizzati su nom_cond, proprietario_denominazione, presso, e_mail_condomino, senza cambiare il nominativo principale dell'unità. Aggiunto anche gescon:qa-rubrica-vuoti e pulsante Aggiorna vuoti da legacy nella scheda rubrica, che compila solo dati mancanti se il match legacy e sicuro.
  • Stato: [U] validato su movimento banca 15803: dry-run produce legacy_key=mov:15803, nominativo=Caschetto Lucia, scala=B, interno=18, candidate_rates=12, somma 1.968,23. Collaudo .202 riuscito con ai_request_id=5, confidence=0.98, allocations[] valorizzato con le 12 rate candidate.

QA smoke unità: perimetro esplicito obbligatorio

  • Problema: scripts/smoke_unita.php poteva scegliere automaticamente il primo stabile disponibile su filesystem o staging, producendo verifiche riuscite sul perimetro sbagliato in ambienti multi-stabile/multi-admin.
  • Causa tecnica: in assenza di argomenti lo script faceva auto-discovery del legacy_code dal primo archivio trovato o dal primo cod_stabile presente in staging.
  • Fix applicato: lo script ora richiede esplicitamente legacy_code e fallisce con usage chiaro se non viene passato; la verifica continua a funzionare se il codice stabile e l anno sono espliciti.
  • Stato: [U] validato localmente: senza argomenti restituisce usage; con php scripts/smoke_unita.php 0016 2021 1 esegue lo smoke sul solo stabile 0016.

Unita immobiliare / estratto soggetto 0026: conguaglio iniziale duplicato rispetto a rate emesse

  • Problema: nella scheda unità e nell estratto soggetto di D'EVOLI Luisa (unita_id=1012, tenant pulito stabile_id=32) il conguaglio 126,06 compariva due volte: una come Bilancio iniziale / esercizi precedenti da CONG.O e una come rate_emesse (Conguaglio es.precedente2025), portando il totale a 700,12 invece di 574,06.
  • Causa tecnica: le pagine sommano i CONG.* di dettaglio_importi_tabella senza escludere i casi gia materializzati in rate_emesse per la stessa unità, ruolo legacy e anno_emissione.
  • Fix applicato: in app/Filament/Pages/UnitaImmobiliarePage.php e app/Filament/Pages/Contabilita/EstrattoContoSoggetto.php i conguagli iniziali vengono soppressi quando esiste gia una rata emessa di conguaglio con stessa unità, ruolo C/I, anno_emissione legacy e importo.
  • Stato: [U] validato via hydration diretta pagina/estratto; unita_id=1012 torna a 574,06, il gruppo Bilancio iniziale sparisce e restano solo le tre rate emesse 224,00 + 224,00 + 126,06.

Unita immobiliare 0026-A-2A: inquilino mischiato ai proprietari e ruolo rate errato

  • Problema: nella scheda unità dei fratelli Zazzara (unita_id=1023) Pagliarini Andrea finiva nella stessa colonna dei proprietari e veniva letto come ruolo rate C, anche se nel dominio e nell import legacy e l inquilino della unità.
  • Causa tecnica: la pagina nuova considerava qualunque record in proprieta come proprietario, includendo anche tipo_diritto = locazione; inoltre la sezione Persone collegate dipendeva quasi solo da rubrica_ruoli, che in questo caso non copriva l inquilino pur avendo il dato corretto in persone_unita_relazioni.
  • Fix applicato: UnitaImmobiliarePage ora limita il bucket proprietari ai soli diritti reali (proprieta, comproprieta, usufrutto, ecc.), esclude locazione dall owner lookup delle rate e usa persone_unita_relazioni come fallback per popolare inquilini mantenendo ruolo_rate persistito (I).
  • Stato: [U] validato via hydration diretta pagina; Fratelli Zazzara resta unico proprietario/condomino con saldo -1780,92, Pagliarini Andrea compare in inquilini con ruolo_rate = I e le rate risultano separate (507,75 lato inquilino).

Supporto > Modifiche in memory exhaustion su log grandi

  • Problema: la pagina admin-filament/supporto/aggiornamento-nodo poteva andare in Allowed memory size exhausted durante loadRuntimeErrors() quando storage/logs/laravel.log diventava molto grande. Sul nodo staging il caso reale era un laravel.log da circa 278 MB.
  • Causa tecnica: appendFromNdjson() e appendFromLaravelLog() usavano file(...), quindi caricavano l intero file in RAM anche se poi la UI mostrava solo gli ultimi eventi utili.
  • Fix applicato: in app/Filament/Pages/Supporto/Modifiche.php i lettori sono stati sostituiti con una lettura tail limitata per linee e byte (readTailLines()), mantenendo il comportamento della UI ma senza allocare l intero log.
  • Stato: [U] riprodotto e corretto sul nodo locale /var/www/netgescon; validazione eseguita via reflection su loadRuntimeErrors() con laravel.log grande, picco memoria rimasto intorno a 89 MB e 39 righe BUG caricate correttamente.
  • Prevenzione: non usare aumento del memory_limit come rimedio principale; mantenere logrotate attivo e preferire sempre parsing incrementale o tail bounded per i file operativi letti dalla UI.

Supporto > Modifiche con ProgramAclService assente su nodo staging

  • Problema: la pagina admin-filament/supporto/aggiornamento-nodo poteva andare in BindingResolutionException con Target class [App\Services\ProgramAclService] does not exist durante canAccess().
  • Causa tecnica: sul nodo staging il checkout deployato non conteneva app/Services/ProgramAclService.php; la pagina supporto dipendeva in modo rigido da quel service anche per un semplice controllo accessi.
  • Fix applicato: Modifiche::canAccess() usa ProgramAclService solo se la classe esiste e si risolve correttamente; se manca, fa fallback ai ruoli amministrativi (super-admin, admin, amministratore) e non blocca la pagina tecnica.
  • Stato: [U] validato su /var/www/netgescon con service realmente assente; App\Filament\Pages\Supporto\Modifiche::canAccess() non genera piu eccezioni e ritorna correttamente true per un utente amministrativo.
  • Prevenzione: nelle pagine di supporto e deploy evitare dipendenze rigide da moduli opzionali o non ancora allineati sul nodo; il pannello di recupero deve sempre avere un percorso di fallback minimale.

Refresh nodo bloccato da permessi deploy su resources/views/errors

  • Problema: il launcher aggiornamento nodo restava a behind 1, la 503 compariva solo per un attimo e la UI del launcher restava visibile con polling e pulsanti, costringendo a refresh manuali.
  • Causa tecnica: netgescon:git-sync falliva nel passaggio rsync verso /var/www/netgescon con Permission denied su resources/views/errors/.503.blade.php; il repository sorgente arrivava al commit remoto ma il checkout applicativo non riceveva i file nuovi.
  • Fix applicato: permessi riallineati su /var/www/netgescon/resources/views/errors e 503.blade.php al gruppo www-data; il launcher ora forza anche una navigazione piena alla stessa URL quando parte il refresh con maintenance, cosi il browser mostra la 503 completa invece di restare nella UI Livewire.
  • Stato: [U] validato su staging locale; git-sync-last.json torna completed, commit deploy e remoto risultano allineati (cadb9a5 nel caso reale) e il nodo torna a ahead 0 / behind 0.
  • Prevenzione: le directory che devono ricevere file nuovi via deploy web devono restare group-writable per il gruppo del processo PHP/web (www-data qui); quando una directory viene creata manualmente sul nodo, impostare subito gruppo coerente e bit setgid.

Ripristino bootstrap pannello admin

  • Problema: AdminFilamentPanelProvider.php era stato corrotto da una modifica incompleta e impediva il bootstrap corretto.
  • Fix applicato: ripristino struttura PHP e riallineamento del provider.
  • Stato: [U] risolto localmente, bootstrap Laravel nuovamente valido.

Token CTI Panasonic e lettura configurazione piu robusta

  • Problema: il flusso staging poteva fallire per risoluzione non coerente del token CTI.
  • Fix applicato: PanasonicCstaController riallineato a config/cti.php con risoluzione piu robusta.
  • Stato: [P] implementato e verificato in locale; su staging resta da completare la validazione end-to-end del canale reale.

Mismatch stabile/anno in Ordinarie

  • Problema: la pagina gescon/ordinarie poteva mostrare dati non coerenti con stabile e anno scelti nella topbar.
  • Fix applicato: default anno dal contesto condiviso e centralizzazione risoluzione codice legacy stabile.
  • Stato: [P] implementato e validato a livello codice; da verificare sul caso reale staging con dati utente specifici.

Filtri acqua e servizi non coerenti con la gestione attiva

  • Problema: in condomini/servizi-utenze e archivio letture la selezione anno/stabile non era sempre rispettata in tutte le query.
  • Fix applicato: applicazione del filtro anno attivo e del contesto stabile ai blocchi acqua principali.
  • Stato: [P] implementato e testato sintatticamente; serve verifica funzionale con dati annuali reali su staging.

Tracciato tecnico SMDR e CSTA mescolato

  • Problema: una sola vista tecnica rendeva meno chiaro distinguere fallback SMDR da eventi CTI/CSTA ricchi.
  • Fix applicato: nuovi tab distinti in strumenti/post-it-gestione e vista click-to-call dedicata.
  • Stato: [U] implementato; da usare come base per test operativi PBX e future integrazioni provider-agnostic.

Validazioni eseguite nell ultimo ciclo

  • php artisan list eseguito con esito positivo dopo gli ultimi fix applicativi
  • controlli sintattici PHP sulle classi modificate senza errori
  • diagnostica editor senza errori sui file toccati
  • Supporto > Modifiche: validato il nuovo parsing tail-bounded dei log su nodo con laravel.log da 278 MB, senza esaurimento memoria

Validazioni ancora aperte

  • verificare su staging la nuova tab CTI / CSTA e Click-to-Call
  • verificare il caso reale di mismatch stabile/anno con dati staging
  • usare il filtro annuale acqua per l estrazione effettiva delle fatture e confermare il perimetro dati

Regola di aggiornamento

Ogni bug corretto va aggiornato qui in quattro righe:

  1. problema osservato
  2. fix applicato
  3. stato verifica locale
  4. stato verifica staging o nodi remoti