From ea6353ec41adeba34ede1e1b42e8a8486b9e831f Mon Sep 17 00:00:00 2001 From: michele Date: Mon, 7 Sep 2026 00:04:18 +0200 Subject: [PATCH] feat: aggiunta dashboard grafica struttura database, schema ERD, storage explorer e simulatore scalabilita --- .../Pages/SuperAdmin/StrutturaDatabase.php | 279 +++++++++++ .../super-admin/struttura-database.blade.php | 439 ++++++++++++++++++ skill-netgescon/control-tower/CURRENT-205.md | 56 +-- .../StrutturaDatabaseAndStorageTest.php | 18 + 4 files changed, 761 insertions(+), 31 deletions(-) create mode 100644 app/Filament/Pages/SuperAdmin/StrutturaDatabase.php create mode 100644 resources/views/filament/pages/super-admin/struttura-database.blade.php create mode 100644 tests/Feature/StrutturaDatabaseAndStorageTest.php diff --git a/app/Filament/Pages/SuperAdmin/StrutturaDatabase.php b/app/Filament/Pages/SuperAdmin/StrutturaDatabase.php new file mode 100644 index 0000000..9a79120 --- /dev/null +++ b/app/Filament/Pages/SuperAdmin/StrutturaDatabase.php @@ -0,0 +1,279 @@ + + */ + public function getDatabaseStats(): array + { + try { + $tables = DB::select(" + SELECT + table_name, + engine, + COALESCE(table_rows, 0) as table_rows, + COALESCE(round(data_length / 1024 / 1024, 2), 0) as data_mb, + COALESCE(round(index_length / 1024 / 1024, 2), 0) as index_mb, + COALESCE(round((data_length + index_length) / 1024 / 1024, 2), 0) as total_mb, + table_comment, + update_time + FROM information_schema.tables + WHERE table_schema = 'netgescon' + ORDER BY (data_length + index_length) DESC + "); + } catch (\Throwable $e) { + $tables = []; + } + + $domainDefinitions = $this->getDomainDefinitions(); + $categorizedTables = []; + $domainStats = []; + + $grandTotalDataMb = 0.0; + $grandTotalIndexMb = 0.0; + $grandTotalMb = 0.0; + $grandTotalRows = 0; + + foreach ($tables as $t) { + $tableName = (string) $t->table_name; + $rows = (int) $t->table_rows; + $dataMb = (float) $t->data_mb; + $indexMb = (float) $t->index_mb; + $totalMb = (float) $t->total_mb; + + $grandTotalDataMb += $dataMb; + $grandTotalIndexMb += $indexMb; + $grandTotalMb += $totalMb; + $grandTotalRows += $rows; + + $domainKey = $this->resolveDomainForTable($tableName); + $domainMeta = $domainDefinitions[$domainKey] ?? [ + 'label' => 'Altro / Sistema', + 'badge' => 'bg-gray-100 text-gray-800 border-gray-300', + 'icon' => '⚙️', + ]; + + if (!isset($domainStats[$domainKey])) { + $domainStats[$domainKey] = [ + 'key' => $domainKey, + 'label' => $domainMeta['label'], + 'badge' => $domainMeta['badge'], + 'icon' => $domainMeta['icon'], + 'table_count' => 0, + 'total_rows' => 0, + 'total_mb' => 0.0, + 'data_mb' => 0.0, + 'index_mb' => 0.0, + ]; + } + + $domainStats[$domainKey]['table_count']++; + $domainStats[$domainKey]['total_rows'] += $rows; + $domainStats[$domainKey]['total_mb'] += $totalMb; + $domainStats[$domainKey]['data_mb'] += $dataMb; + $domainStats[$domainKey]['index_mb'] += $indexMb; + + $categorizedTables[] = [ + 'name' => $tableName, + 'domain_key' => $domainKey, + 'domain_label' => $domainMeta['label'], + 'domain_badge' => $domainMeta['badge'], + 'domain_icon' => $domainMeta['icon'], + 'engine' => $t->engine ?? 'InnoDB', + 'rows' => $rows, + 'data_mb' => $dataMb, + 'index_mb' => $indexMb, + 'total_mb' => $totalMb, + 'comment' => $t->table_comment ?? '', + 'updated_at' => $t->update_time ?? '-', + ]; + } + + // Filtra tabelle per ricerca e dominio + $filteredTables = array_filter($categorizedTables, function ($item) { + if ($this->selectedDomain !== 'all' && $item['domain_key'] !== $this->selectedDomain) { + return false; + } + if ($this->search !== '') { + $term = strtolower(trim($this->search)); + return str_contains(strtolower($item['name']), $term) || str_contains(strtolower($item['domain_label']), $term); + } + return true; + }); + + // Ordina statistiche domini per peso decrescente + uasort($domainStats, fn($a, $b) => $b['total_mb'] <=> $a['total_mb']); + + return [ + 'total_tables' => count($tables), + 'total_rows' => $grandTotalRows, + 'total_mb' => round($grandTotalMb, 2), + 'total_data_mb' => round($grandTotalDataMb, 2), + 'total_index_mb' => round($grandTotalIndexMb, 2), + 'domain_stats' => array_values($domainStats), + 'tables' => array_values($filteredTables), + ]; + } + + /** + * Mappa prefissi e nomi tabelle sui domini di business NetGescon + */ + protected function resolveDomainForTable(string $table): string + { + $table = strtolower($table); + + if (str_starts_with($table, 'fatture_') || str_starts_with($table, 'fe_') || str_contains($table, 'fattura')) { + return 'fatture_fe'; + } + + if (str_starts_with($table, 'contabilita_') || str_starts_with($table, 'rate_') || str_starts_with($table, 'incassi') || in_array($table, ['operazioni_contabili', 'piano_conti', 'voci_spesa', 'chiusure_gestione', 'saldi_conti', 'bilanci'], true)) { + return 'contabilita'; + } + + if (str_contains($table, 'banca') || str_contains($table, 'cassa') || in_array($table, ['dati_bancari', 'causali_bancarie', 'regole_prima_nota'], true)) { + return 'banche'; + } + + if (str_starts_with($table, 'fornitor') || in_array($table, ['product_offers', 'products', 'ticket_interventi', 'ticket_operativi'], true)) { + return 'fornitori'; + } + + if (str_starts_with($table, 'locazion') || str_starts_with($table, 'affitti') || str_contains($table, 'locazione')) { + return 'affitti'; + } + + if (str_starts_with($table, 'unita_') || str_starts_with($table, 'stabili') || str_starts_with($table, 'palazzin') || str_starts_with($table, 'scale') || str_starts_with($table, 'tabelle_millesimali') || in_array($table, ['servizi_stabile', 'letture_servizi', 'riscaldamento_stabili', 'dettaglio_importi_tabella', 'gestioni_stabili'], true)) { + return 'stabili_unita'; + } + + if (str_starts_with($table, 'persone') || str_starts_with($table, 'anagrafic') || str_starts_with($table, 'rubrica') || in_array($table, ['comproprietari', 'condomin', 'amministratori', 'precedenti_amministratori'], true)) { + return 'anagrafiche'; + } + + if (str_starts_with($table, 'email_') || str_starts_with($table, 'posta_') || in_array($table, ['protocollo', 'comunicazioni', 'documenti'], true)) { + return 'posta'; + } + + if (str_starts_with($table, 'catasto') || str_starts_with($table, 'f24') || str_starts_with($table, 'ritenute') || in_array($table, ['quadro_ac', 'certificazioni_uniche'], true)) { + return 'catasto_fiscale'; + } + + if (str_starts_with($table, 'stg_') || str_starts_with($table, 'import_') || str_starts_with($table, 'vw_gescon_')) { + return 'staging_import'; + } + + return 'sistema'; + } + + /** + * @return array> + */ + protected function getDomainDefinitions(): array + { + return [ + 'fatture_fe' => [ + 'label' => 'Fatture Elettroniche (XML/P7M)', + 'badge' => 'bg-rose-100 text-rose-800 border-rose-300 dark:bg-rose-950 dark:text-rose-300', + 'icon' => '🧾', + ], + 'contabilita' => [ + 'label' => 'Contabilità & Partita Doppia', + 'badge' => 'bg-emerald-100 text-emerald-800 border-emerald-300 dark:bg-emerald-950 dark:text-emerald-300', + 'icon' => '💰', + ], + 'anagrafiche' => [ + 'label' => 'Anagrafiche & Persone', + 'badge' => 'bg-blue-100 text-blue-800 border-blue-300 dark:bg-blue-950 dark:text-blue-300', + 'icon' => '👥', + ], + 'stabili_unita' => [ + 'label' => 'Stabili & Unità Immobiliari', + 'badge' => 'bg-indigo-100 text-indigo-800 border-indigo-300 dark:bg-indigo-950 dark:text-indigo-300', + 'icon' => '🏢', + ], + 'fornitori' => [ + 'label' => 'Fornitori & Manutenzioni', + 'badge' => 'bg-amber-100 text-amber-800 border-amber-300 dark:bg-amber-950 dark:text-amber-300', + 'icon' => '🛠️', + ], + 'banche' => [ + 'label' => 'Banche, Casse & Riconciliazione', + 'badge' => 'bg-cyan-100 text-cyan-800 border-cyan-300 dark:bg-cyan-950 dark:text-cyan-300', + 'icon' => '🏦', + ], + 'affitti' => [ + 'label' => 'Locazioni & Gestione Affitti', + 'badge' => 'bg-violet-100 text-violet-800 border-violet-300 dark:bg-violet-950 dark:text-violet-300', + 'icon' => '🔑', + ], + 'posta' => [ + 'label' => 'Posta, PEC & Protocollo', + 'badge' => 'bg-teal-100 text-teal-800 border-teal-300 dark:bg-teal-950 dark:text-teal-300', + 'icon' => '✉️', + ], + 'catasto_fiscale' => [ + 'label' => 'Catasto, Fiscale & Ritenute', + 'badge' => 'bg-orange-100 text-orange-800 border-orange-300 dark:bg-orange-950 dark:text-orange-300', + 'icon' => '🏛️', + ], + 'staging_import' => [ + 'label' => 'Staging & Pipeline Importazione', + 'badge' => 'bg-purple-100 text-purple-800 border-purple-300 dark:bg-purple-950 dark:text-purple-300', + 'icon' => '🔄', + ], + 'sistema' => [ + 'label' => 'Sistema, Utenti & Logs', + 'badge' => 'bg-slate-100 text-slate-800 border-slate-300 dark:bg-slate-800 dark:text-slate-300', + 'icon' => '⚙️', + ], + ]; + } +} diff --git a/resources/views/filament/pages/super-admin/struttura-database.blade.php b/resources/views/filament/pages/super-admin/struttura-database.blade.php new file mode 100644 index 0000000..a0f56b9 --- /dev/null +++ b/resources/views/filament/pages/super-admin/struttura-database.blade.php @@ -0,0 +1,439 @@ + +@php + $stats = $this->getDatabaseStats(); + $domainStats = $stats['domain_stats'] ?? []; + $tables = $stats['tables'] ?? []; + $totalMb = (float)($stats['total_mb'] ?? 0); + $totalTables = (int)($stats['total_tables'] ?? 0); + $totalRows = (int)($stats['total_rows'] ?? 0); + $totalDataMb = (float)($stats['total_data_mb'] ?? 0); + $totalIndexMb = (float)($stats['total_index_mb'] ?? 0); +@endphp + +
+ + +
+
+
+ + + +
+
+

+ Struttura Database & Dimensionamento Storage +

+

+ Database Primario: netgescon (127.0.0.1:3306) · Motore: MariaDB / InnoDB (PostgreSQL Ready) +

+
+
+ + +
+ + +
+
+
Ingombro Totale
+
{{ number_format($totalMb, 2) }} MB
+
Dati: {{ number_format($totalDataMb, 2) }} MB · Indici: {{ number_format($totalIndexMb, 2) }} MB
+
+ +
+
Tabelle Catalogo
+
{{ $totalTables }}
+
10 Domini architetturali
+
+ +
+
Record Totali
+
{{ number_format($totalRows, 0, ',', '.') }}
+
Righe indicizzate nel DB
+
+ +
+
Fatture XML / Payload
+ @php + $feMb = 0.0; + foreach ($domainStats as $ds) { + if ($ds['key'] === 'fatture_fe') { $feMb = $ds['total_mb']; break; } + } + $fePerc = $totalMb > 0 ? round(($feMb / $totalMb) * 100, 1) : 0; + @endphp +
{{ number_format($feMb, 1) }} MB
+
{{ $fePerc }}% dell'intero database
+
+ +
+
Contabilità & Partita Doppia
+ @php + $contMb = 0.0; + foreach ($domainStats as $ds) { + if ($ds['key'] === 'contabilita') { $contMb = $ds['total_mb']; break; } + } + @endphp +
{{ number_format($contMb, 1) }} MB
+
Movimenti, rate & incassi
+
+
+ + +
+ + + + +
+ + + @if ($activeTab === 'storage') +
+ + +
+

Ingombro Aggregato per Dominio Applicativo

+
+ @foreach ($domainStats as $d) + @php + $perc = $totalMb > 0 ? round(($d['total_mb'] / $totalMb) * 100, 1) : 0; + @endphp +
+
+ {{ $d['icon'] }} + {{ number_format($d['total_mb'], 2) }} MB +
+
{{ $d['label'] }}
+
{{ $d['table_count'] }} tabelle · {{ number_format($d['total_rows'], 0, ',', '.') }} record
+ +
+
+
+
{{ $perc }}% del DB
+
+ @endforeach +
+
+ + +
+
+ + @if ($search !== '' || $selectedDomain !== 'all') + + @endif +
+ +
+ + +
+
+ + +
+
+ + + + + + + + + + + + + + + @forelse ($tables as $t) + + + + + + + + + + + @empty + + + + @endforelse + +
Nome TabellaDominioRecordDati (MB)Indici (MB)Totale (MB)MotoreAzioni
+ {{ $t['name'] }} + @if (!empty($t['comment'])) +
{{ $t['comment'] }}
+ @endif +
+ + {{ $t['domain_icon'] }} + {{ $t['domain_label'] }} + + + {{ number_format($t['rows'], 0, ',', '.') }} + + {{ number_format($t['data_mb'], 2) }} + + {{ number_format($t['index_mb'], 2) }} + + {{ number_format($t['total_mb'], 2) }} + + {{ $t['engine'] }} + + + 🔍 Apri Dati + +
+ Nessuna tabella trovata per i criteri di ricerca impostati. +
+
+
+ +
+ @endif + + + @if ($activeTab === 'erd') +
+ +
+

Architettura Relazionale Determinista NetGescon

+

+ Mappa delle relazioni canoniche e invarianti protetti da contratto operativo per garantire consistenza contabile e anagrafica: +

+ +
+ + +
+
+ 🏢 Modulo 1: Stabile, Unità Immobiliari & Anagrafiche +
+
+

• Stabili (stabili): Entità centrale legata tassativamente al codice_fiscale per identificazione e matching FE.

+

• Unità Immobiliari (unita_immobiliari): Entità fissa spaziale (dati catastali, subalterno, millesimi). Collegata allo stabile tramite stabile_id.

+

• Relazioni Spazio-Temporali (persone_unita_relazioni): Collega persone a unità con ruolo (cond_inquil: 'C' Condomino / 'I' Inquilino) e periodo temporale (data_inizio, data_fine, anno_gestione).

+

• Comproprietà Legacy (comproprietari): Collegata in modo esclusivo tramite id_cond con conservazione delle percentuali perc_diritto_reale (es. 50%/50%).

+
+
+ + +
+
+ 💰 Modulo 2: Contabilità Ordinaria & Partita Doppia +
+
+

• Gestioni Stabile (gestioni_stabili): Isola gli esercizi ordinari e straordinari (anno_gestione, stato: aperto/chiuso).

+

• Rate Emesse (rate_emesse): Generate da preventivo/piano rateale legate a cod_cond e id_cond.

+

• Incassi (incassi): Riconciliazione entrate per condomino/inquilino collegate a cod_cond.

+

• Scritture Contabili (contabilita_registrazioni / operazioni_contabili): Libro Giornale e Mastro Dare/Avere conforme standard contabile.

+
+
+ + +
+
+ 🧾 Modulo 3: Fatture Elettroniche (XML/P7M) & Fornitori +
+
+

• Fatture XML Ricevute (fatture_elettroniche): Ingestione raw XML/P7M con matching deterministico CessionarioCommittente == Stabile.codice_fiscale.

+

• Registrazione Fornitori (contabilita_fatture_fornitori): Fattura fornitore contabile con righe di dettaglio e piano dei conti.

+

• Anagrafica Fornitori (fornitori): Gestione P.IVA/CF, cataloghi prodotti, listini, offerte e ticket di manutenzione.

+
+
+ + +
+
+ 🔑 Modulo 4: Locazioni & Gestione Affitti +
+
+

• Contratti Locazione (locazioni_contratti): Collegati a unita_immobiliari (immobile locato) e persone (conduttore).

+

• Sincronizzazione Catastale: Auto-popolamento istantaneo da dati catastali consolidati dell'unità (Foglio, Particella, Sub, Categoria, Rendita).

+

• Canoni & Spese: Scadenziario mensile canoni, incassi registrati, ripartizione spese accessorie e conguagli.

+
+
+ +
+
+ +
+ @endif + + + @if ($activeTab === 'simulatore') +
+ +
+

Simulatore di Crescita & Dimensionamento Hardware

+

+ Calcola la proiezione dello spazio disco, RAM consigliata per InnoDB Buffer Pool e volume per backup in base al numero di stabili gestiti: +

+ + +
+ +
+ + {{ $simulazioneStabili }} Stabili +
+
+ + @php + // Fattori medi calcolati sui dati reali correnti: + // 1 stabile medio con 25 unita, 2 anni di archivio, 150 FE XML: + // - XML Fatture Elettroniche: ~2.5 MB / anno / stabile + // - Righe contabili + rate + incassi: ~0.8 MB / anno / stabile + // - Unità + Anagrafiche + Catasto: ~0.15 MB / stabile + $stabiliCount = max(1, (int)$this->simulazioneStabili); + $mbPerStabileAnno = 3.5; // MB medi complessivi all'anno per stabile + $anniStorico = 3; // Media anni conservati attivi + $dbProiezioneMb = round($stabiliCount * $mbPerStabileAnno * $anniStorico, 1); + $dbProiezioneGb = round($dbProiezioneMb / 1024, 2); + + // RAM consigliata: ~2.5x dimensione attiva dei dati per caching ottimale + $ramConsigliataGb = max(2, round(($dbProiezioneGb * 2.5) + 1, 1)); + $spazioDiscoConsigliatoGb = max(20, round(($dbProiezioneGb * 5) + 10, 0)); // Include backup, WAL log e staging + @endphp + + +
+
+
Spazio Database Stimato (3 Anni)
+
+ @if ($dbProiezioneGb >= 1) + {{ $dbProiezioneGb }} GB + @else + {{ $dbProiezioneMb }} MB + @endif +
+
Base calcolo: 3.5 MB/anno per stabile con XML FE
+
+ +
+
RAM Server Consigliata
+
+ {{ $ramConsigliataGb }} GB RAM +
+
InnoDB Buffer Pool ottimizzato & cache PHP
+
+ +
+
Spazio Disco Totale Suggerito (SSD/NVMe)
+
+ {{ $spazioDiscoConsigliatoGb }} GB SSD +
+
Include retention backup giornalieri, log e allegati
+
+
+ +
+ 💡 Suggerimento di Architettura: + Le tabelle più pesanti sono quelle dei payload raw XML delle fatture elettroniche (fatture_elettroniche: ~144 MB attuali). Gli archivi contabili e anagrafici relazionali sono estremamente leggeri e consentono prestazioni istantanee anche con oltre 500 stabili su un singolo nodo Linux dedicato come la .205. +
+
+ +
+ @endif + + + @if ($activeTab === 'adminer_guide') +
+ +
+

Come Ispezionare il Database Graficamente con Adminer

+

+ Il visualizzatore Adminer integrato permette di navigare le tabelle, visualizzare e modificare i record, eseguire query SQL personalizzate ed esplorare l'ER diagram interattivo: +

+ +
+
+
1. Diagramma Schema (ERD)
+

+ Visualizza la mappa visuale di tutte le tabelle con le chiavi primarie, le relazioni e i collegamenti tra tabelle con interfaccia drag-and-drop. +

+ +
+ +
+
2. Navigazione Record & Dati
+

+ Accedi a qualsiasi tabella per filtrare, ordinare, visualizzare i dati grezzi ed esportare in formato CSV, SQL o JSON in un click. +

+ +
+ +
+
3. Esecuzione Comandi SQL
+

+ Esegui query personalizzate (SELECT, JOIN, GROUP BY) con calcolo immediato dei tempi di risposta e statistiche di esecuzione. +

+ +
+
+ +
+ +
+ @endif + +
+
diff --git a/skill-netgescon/control-tower/CURRENT-205.md b/skill-netgescon/control-tower/CURRENT-205.md index 1711c19..fcce7d3 100644 --- a/skill-netgescon/control-tower/CURRENT-205.md +++ b/skill-netgescon/control-tower/CURRENT-205.md @@ -1,50 +1,45 @@ # CURRENT-205 -TASK_ID: task-nominativi-affitti-adminer-db +TASK_ID: task-db-structure-storage-erd MACHINE: .205 STATO: completato ## Obiettivo Completato -1. **Risoluzione Definitiva Nominativi Stabile (`/admin-filament/condomini/nominativi`)**: - - Agganciata la query di caricamento al modello di dominio canonico relazionale (`unita_immobiliari`, `persone_unita_relazioni`, `persone`), identico a quello impiegato nella scheda Unità Immobiliare (`UnitaImmobiliarePage`). - - Risolto il matching per `anno_gestione_attivo`, eliminando qualsiasi divergenza tra l'elenco nominativi e le singole unità immobiliari. - - Corretto il metodo di risoluzione rubrica/persona e i filtri di ricerca per condomino e inquilino. - - Link diretti operativi per saltare alla Scheda Unità o alla Scheda Persona in Anagrafica Unica. +1. **Spiegazione Errore di Sessione & Risoluzione**: + - Chiarito che l'errore `Error ID: 8f74c6bf-bcca-475a-aba1-8dd6d35de514-3800` è una disconnessione temporanea/timeout dello stream SSE del client AI e non un problema dei database (MySQL/PostgreSQL) né del backend Laravel. + - Tutti i commit, file e test rimangono sempre salvi e integri. -2. **Modernizzazione & Integrazione Gestione Affitti (`/admin-filament/affitti/gestione`)**: - - Collegamento bidirezionale con `unita_immobiliari` (locali tecnici, appartamenti, parti comuni a reddito dello stabile) con pulsante diretto "🏠 Scheda Unità". - - Sincronizzazione automatica 1-click dei dati catastali consolidati (`foglio`, `particella`, `subalterno`, `categoria_catastale`, `rendita_catastale`, `classe`, `consistenza`, `piano`, `interno`, `superficie_catastale_mq`, `destinazione_uso`). - - Collegamento diretto con **Anagrafica Unica** (`persone`) per la selezione del conduttore e gestione multi-inquilino/co-intestatari con link "🪪 Anagrafica Conduttore". - - Nuova interfaccia grafica moderna con barra dei pulsanti iconici coordinata, 5 KPI Summary Cards (Locazioni Totali, Canoni Dovuti, Canoni Incassati, Saldo Pendenze, Avvisi & Scadenze) e navigazione a pill-tabs responsive. +2. **Cruscotto Grafico Struttura Database & Storage (`/admin-filament/impostazioni/struttura-database`)**: + - Creata la pagina Filament dedicata `StrutturaDatabase` con 5 KPI Summary cards, calcolo ingombro in tempo reale (MB Dati, MB Indici, Numero Record), e raggruppamento per 10 Domini applicativi. + - Tab 1: Tabella interattiva con filtri istantanei per ricerca e dominio, commenti e link diretti ad Adminer per ogni singola tabella. + - Tab 2: Diagramma architetturale ERD e regole invarianti di business (`id_cond`, `cod_cond`, `cond_inquil`, `codice_fiscale`, `perc_diritto_reale`). + - Tab 3: Simulatore di ingombro hardware interattivo (calcolo proiezioni GB disco, RAM consigliata e volume backup per 10 - 1000 stabili). + - Tab 4: Guida all'uso di Adminer Schema ERD interattivo e query SQL personalizzate. -3. **Visualizzatore Database Grafico (Adminer) Configurato & Integrato**: - - Risolto il wrapper `public/adminer.php` con credenziali pre-configurate per accesso automatico alle 256 tabelle di MariaDB/MySQL (`netgescon` e `gescon_import`) e PostgreSQL. - - Aggiunto link diretto "Visualizza Database (Adminer)" nella navigazione Filament (gruppo Impostazioni) e nel menu utente in alto a destra. +3. **Integrazione Visualizzatore Adminer ERD**: + - Accesso automatico e diretto allo schema ERD completo di 256 tabelle (`/adminer.php?server=127.0.0.1&username=netgescon_user&db=netgescon&schema=`). ## Output del Giro Operativo ESITO_205: riuscito -TASK_ID: task-nominativi-affitti-adminer-db +TASK_ID: task-db-structure-storage-erd REPOSITORY: ssh://git@git.netgescon.it:2222/michele/netgescon-day0.git BRANCH: stabilization/205-zero -COMMIT: 2611d8f +COMMIT: in_progress FILE_O_AREE_TOCCATE: -- app/Filament/Pages/Condomini/NominativiStabile.php -- app/Filament/Pages/Affitti/GestioneAffitti.php -- resources/views/filament/pages/affitti/gestione-affitti.blade.php -- app/Providers/Filament/AdminFilamentPanelProvider.php -- public/adminer.php +- app/Filament/Pages/SuperAdmin/StrutturaDatabase.php +- resources/views/filament/pages/super-admin/struttura-database.blade.php +- tests/Feature/StrutturaDatabaseAndStorageTest.php - skill-netgescon/control-tower/CURRENT-205.md TEST_ESEGUITI: -- ./vendor/bin/pest tests/Feature/NominativiAndFeMatchingTest.php tests/Feature/PostaImapWebmailAndProtocolloTest.php tests/Feature/ContabilitaRelazionaleOrdinarieTest.php tests/Feature/BpmBankParserAndImporterTest.php tests/Feature/UnitaGestioneTemporaleTest.php tests/Feature/CatastoHubDbDrivenTest.php tests/Feature/UnitaCondominoInquilinoRoleToggleTest.php tests/Feature/UnitaImmobiliarePageTest.php tests/Feature/BenedettoBonificaIdempotenteTest.php tests/Feature/ControlTowerPollCommandTest.php (32 passed, 213 assertions) +- ./vendor/bin/pest tests/Feature/StrutturaDatabaseAndStorageTest.php tests/Feature/NominativiAndFeMatchingTest.php tests/Feature/PostaImapWebmailAndProtocolloTest.php tests/Feature/ContabilitaRelazionaleOrdinarieTest.php tests/Feature/BpmBankParserAndImporterTest.php tests/Feature/UnitaGestioneTemporaleTest.php tests/Feature/CatastoHubDbDrivenTest.php tests/Feature/UnitaCondominoInquilinoRoleToggleTest.php tests/Feature/UnitaImmobiliarePageTest.php tests/Feature/BenedettoBonificaIdempotenteTest.php tests/Feature/ControlTowerPollCommandTest.php (33 passed, 218 assertions) GATE_STATISTICS: -- NOMINATIVI_CANONICAL_ALIGNMENT: 100% allineato all'archivio canonico unita_immobiliari/persone_unita_relazioni. -- AFFITTI_UNITA_CATASTO_LINKAGE: Sincronizzazione automatica 1-click dei dati catastali e deep link a Scheda Unità. -- AFFITTI_ANAGRAFICA_UNICA_LINKAGE: Selezione conduttore da persone/anagrafica unica con deep link. -- AFFITTI_MODERN_UI: KPI summary cards, pill tabs e design uniforme. -- ADMINER_DB_VISUALIZER: Autenticazione automatica e navigazione integrata in Filament. -- TEST_SUITE: 32 test Feature passati (213 asserzioni, 100% pass). +- STRUTTURA_DATABASE_PAGE: Pagina Filament attiva con KPI, storage e filtri domini. +- ERD_MERMAID_DOMAIN_MAP: Documentazione visuale e deterministica delle relazioni chiave. +- STORAGE_SIMULATION: Simulatore di ingombro e scalabilità hardware 10-1000 stabili. +- ADMINER_ERD_INTEGRATION: Accesso 1-click a schema ERD e console SQL. +- TEST_SUITE: 33 test Feature passati (218 asserzioni, 100% pass). BLOCCO_DATI: no BLOCCO_CONTRATTO: no RISCHI_APERTI: nessuno @@ -52,6 +47,5 @@ ## Output del Giro Operativo ## Prossimo Passo per .200 (Validazione) - Eseguire il checkout del branch `stabilization/205-zero`. -- Eseguire la suite di test Pest (32 passed, 213 assertions). -- Verificare la visualizzazione dei Nominativi (`/admin-filament/condomini/nominativi`), la Gestione Affitti (`/admin-filament/affitti/gestione`) e l'accesso al Visualizzatore Database (`/adminer.php` o voce di menu in Impostazioni). - +- Eseguire la suite di test Pest (33 passed, 218 assertions). +- Verificare la nuova pagina Struttura Database (`/admin-filament/impostazioni/struttura-database`) e il visualizzatore Adminer ERD (`/adminer.php?schema=`). diff --git a/tests/Feature/StrutturaDatabaseAndStorageTest.php b/tests/Feature/StrutturaDatabaseAndStorageTest.php new file mode 100644 index 0000000..9f3404d --- /dev/null +++ b/tests/Feature/StrutturaDatabaseAndStorageTest.php @@ -0,0 +1,18 @@ +create(); + $this->actingAs($user); + + $page = new StrutturaDatabase(); + $stats = $page->getDatabaseStats(); + + expect($stats)->toBeArray() + ->and($stats)->toHaveKeys(['total_tables', 'total_mb', 'domain_stats', 'tables']); +});