280 lines
11 KiB
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' => '⚙️',
|
|
],
|
|
];
|
|
}
|
|
}
|