netgescon-day0/app/Filament/Pages/SuperAdmin/StrutturaDatabase.php

280 lines
11 KiB
PHP

<?php
namespace App\Filament\Pages\SuperAdmin;
use App\Models\User;
use BackedEnum;
use Filament\Pages\Page;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;
use UnitEnum;
/**
* NetGescon Database Architecture & Storage Footprint Explorer
*
* Fornisce una visualizzazione completa, grafica e deterministica:
* 1. Dello schema e dell'ingombro disco (MB Dati, MB Indici, Numero Record) di tutte le tabelle.
* 2. Del raggruppamento per domini di business (Stabili, Anagrafiche, Contabilità, Fornitori, Banche, Affitti, Posta, Catasto).
* 3. Delle relazioni chiave di dominio (ERD Mermaid) tra unità, persone, movimenti contabili e fatture.
* 4. Dell'integrazione diretta con il visualizzatore Adminer per l'esplorazione SQL e diagrammi interattivi.
*/
class StrutturaDatabase extends Page
{
protected static ?string $navigationLabel = 'Struttura Database (ERD & Storage)';
protected static ?string $title = 'Struttura Database & Dimensionamento Storage';
protected static BackedEnum|string|null $navigationIcon = 'heroicon-o-circle-stack';
protected static UnitEnum|string|null $navigationGroup = 'Impostazioni';
protected static ?int $navigationSort = 95;
protected static ?string $slug = 'impostazioni/struttura-database';
protected string $view = 'filament.pages.super-admin.struttura-database';
public string $activeTab = 'storage';
public string $search = '';
public string $selectedDomain = 'all';
public int $simulazioneStabili = 100;
public function mount(): void
{
// Default initializations
}
/**
* Calcola le statistiche e l'elenco delle tabelle con l'ingombro reale
*
* @return array<string, mixed>
*/
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<string, array<string, string>>
*/
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' => '⚙️',
],
];
}
}