first(); if ($existingAdmin) { $this->command->info('⚠️ Amministratore test 00000000 già esistente'); return; } // 2. Verifica/crea ruolo admin if (!Role::where('name', 'admin')->exists()) { Role::create(['name' => 'admin', 'guard_name' => 'web']); } // 3. Crea utente per amministratore test $user = User::create([ 'name' => 'Amministratore Test', 'email' => 'admin.test@netgescon.local', 'password' => Hash::make('Test123!'), 'email_verified_at' => now(), ]); // 4. Assegna ruolo admin $user->assignRole('admin'); // 5. Crea record amministratore con codice fisso $amministratore = Amministratore::create([ 'user_id' => $user->id, 'nome' => 'Amministratore', 'cognome' => 'Test', 'denominazione_studio' => 'Studio Test NetGescon', 'partita_iva' => '00000000000', 'codice_fiscale_studio' => 'TSTNGS00A01H501X', 'indirizzo_studio' => 'Via Test 123', 'cap_studio' => '00100', 'citta_studio' => 'Test City', 'provincia_studio' => 'TC', 'telefono_studio' => '000-0000000', 'email_studio' => 'studio.test@netgescon.local', 'pec_studio' => 'pec.test@netgescon.pec.it', 'codice_univoco' => '00000000', ]); // 6. Crea database dedicato $this->createDedicatedDatabase($amministratore); // 7. Crea struttura cartelle avanzata $this->createAdvancedFolderStructure($amministratore); $this->command->info('✅ Amministratore test 00000000 creato con successo'); $this->command->info(" 👤 User ID: {$user->id}"); $this->command->info(" 🏢 Admin ID: {$amministratore->id}"); $this->command->info(" 📧 Email: {$user->email}"); $this->command->info(" 🗂️ Cartella: {$amministratore->getFolderPath()}"); $this->command->info(" 💾 Database: {$amministratore->getDatabaseName()}"); }); } /** * Crea database dedicato per amministratore */ private function createDedicatedDatabase(Amministratore $amministratore): void { $dbName = "netgescon_admin_{$amministratore->codice_univoco}"; try { // Crea database DB::statement("CREATE DATABASE IF NOT EXISTS `{$dbName}` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci"); // Aggiorna record amministratore $amministratore->update(['database_attivo' => $dbName]); $this->command->info(" 💾 Database {$dbName} creato"); // TODO: Popola con struttura base tabelle $this->populateBaseTables($dbName); } catch (\Exception $e) { $this->command->error(" ❌ Errore creazione database: " . $e->getMessage()); } } /** * Popola database con struttura base */ private function populateBaseTables(string $dbName): void { // Switch temporaneo al database dedicato $originalDb = DB::getDatabaseName(); try { config(['database.connections.mysql.database' => $dbName]); DB::purge('mysql'); DB::reconnect('mysql'); // Esegui migrazioni base per amministratore $baseTables = [ "CREATE TABLE IF NOT EXISTS stabili ( id bigint unsigned NOT NULL AUTO_INCREMENT, codice_stabile varchar(20) NOT NULL, denominazione varchar(255) NOT NULL, indirizzo varchar(255) NOT NULL, cap varchar(10) NOT NULL, citta varchar(100) NOT NULL, provincia varchar(5) NOT NULL, amministratore_id bigint unsigned NOT NULL, database_dedicato varchar(100) NULL, created_at timestamp NULL DEFAULT NULL, updated_at timestamp NULL DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY stabili_codice_unique (codice_stabile), KEY stabili_amministratore_idx (amministratore_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci", "CREATE TABLE IF NOT EXISTS condomini ( id bigint unsigned NOT NULL AUTO_INCREMENT, stabile_id bigint unsigned NOT NULL, codice_condominio varchar(20) NOT NULL, denominazione varchar(255) NOT NULL, numero_unita int DEFAULT 0, database_dedicato varchar(100) NULL, created_at timestamp NULL DEFAULT NULL, updated_at timestamp NULL DEFAULT NULL, PRIMARY KEY (id), UNIQUE KEY condomini_codice_unique (codice_condominio), KEY condomini_stabile_idx (stabile_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci", "CREATE TABLE IF NOT EXISTS unita ( id bigint unsigned NOT NULL AUTO_INCREMENT, condominio_id bigint unsigned NOT NULL, numero_unita varchar(10) NOT NULL, piano varchar(10) NULL, superficie decimal(8,2) NULL, millesimi decimal(8,3) NULL, proprietario_nome varchar(255) NULL, proprietario_cognome varchar(255) NULL, created_at timestamp NULL DEFAULT NULL, updated_at timestamp NULL DEFAULT NULL, PRIMARY KEY (id), KEY unita_condominio_idx (condominio_id) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci" ]; foreach ($baseTables as $sql) { DB::statement($sql); } $this->command->info(" 📋 Tabelle base create nel database dedicato"); } catch (\Exception $e) { $this->command->error(" ❌ Errore popolamento tabelle: " . $e->getMessage()); } finally { // Ripristina connessione originale config(['database.connections.mysql.database' => $originalDb]); DB::purge('mysql'); DB::reconnect('mysql'); } } /** * Crea struttura cartelle avanzata */ private function createAdvancedFolderStructure(Amministratore $amministratore): void { $basePath = "amministratori/{$amministratore->codice_univoco}"; // Struttura cartelle per amministratore $adminFolders = [ // Documenti amministratore 'documenti/studio/contratti', 'documenti/studio/certificazioni', 'documenti/studio/assicurazioni', 'documenti/studio/comunicazioni', // Database e backup 'database/backups/full', 'database/backups/incremental', 'database/migrations', 'database/exports', // Log e monitoring 'logs/sistema', 'logs/accessi', 'logs/operazioni', 'logs/errori', // File temporanei 'temp/uploads', 'temp/processing', 'temp/exports', 'temp/imports', // Reports e esportazioni 'reports/mensili', 'reports/annuali', 'reports/custom', // Archivi documenti 'archivio/per_anno', 'archivio/comunicazioni', 'archivio/assemblee', ]; foreach ($adminFolders as $folder) { Storage::disk('local')->makeDirectory("{$basePath}/{$folder}"); } // Crea file configurazione amministratore $config = [ 'amministratore' => [ 'codice' => $amministratore->codice_univoco, 'nome_completo' => $amministratore->nome_completo, 'denominazione_studio' => $amministratore->denominazione_studio, 'database_dedicato' => $amministratore->getDatabaseName(), 'created_at' => $amministratore->created_at->toISOString(), ], 'settings' => [ 'backup_automatico' => true, 'backup_frequency' => 'daily', 'retention_days' => 30, 'log_level' => 'info', 'max_file_size' => '50MB', ], 'paths' => [ 'database_backups' => 'database/backups', 'documents' => 'documenti', 'logs' => 'logs', 'temp' => 'temp', 'reports' => 'reports', 'archive' => 'archivio', ] ]; Storage::disk('local')->put( "{$basePath}/amministratore_config.json", json_encode($config, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE) ); // Crea README dettagliato $readme = $this->generateAdminReadme($amministratore); Storage::disk('local')->put("{$basePath}/README.md", $readme); $this->command->info(" 📁 Struttura cartelle avanzata creata"); } /** * Genera README per amministratore */ private function generateAdminReadme(Amministratore $amministratore): string { return "# 🏢 Amministratore: {$amministratore->nome_completo} ## 📋 Informazioni Generali - **Codice Univoco**: `{$amministratore->codice_univoco}` - **Denominazione Studio**: {$amministratore->denominazione_studio} - **Database Dedicato**: `{$amministratore->getDatabaseName()}` - **Creato**: {$amministratore->created_at->format('d/m/Y H:i')} ## 📁 Struttura Archivio ### 🏗️ Documenti Studio - `documenti/studio/` - Documenti dell'amministratore - `documenti/studio/contratti/` - Contratti di amministrazione - `documenti/studio/certificazioni/` - Certificazioni professionali - `documenti/studio/assicurazioni/` - Polizze assicurative ### 💾 Database e Backup - `database/backups/full/` - Backup completi database - `database/backups/incremental/` - Backup incrementali - `database/migrations/` - Script migrazione - `database/exports/` - Esportazioni dati ### 📊 Log e Monitoring - `logs/sistema/` - Log sistema - `logs/accessi/` - Log accessi utenti - `logs/operazioni/` - Log operazioni CRUD - `logs/errori/` - Log errori applicazione ### 🔄 File Temporanei - `temp/uploads/` - Upload temporanei - `temp/processing/` - Elaborazioni in corso - `temp/exports/` - Export temporanei - `temp/imports/` - Import temporanei ### 📈 Reports - `reports/mensili/` - Report mensili - `reports/annuali/` - Report annuali - `reports/custom/` - Report personalizzati ### 📚 Archivio - `archivio/per_anno/` - Archivio per anno - `archivio/comunicazioni/` - Comunicazioni archiviate - `archivio/assemblee/` - Verbali assemblee ## 🏘️ Struttura Stabili Ogni stabile amministrato avrà: - Database dedicato separato - Cartella fisica dedicata - Backup indipendenti - Log separati ## 🔧 Funzionalità Avanzate ### 📦 Migrazione/Trasferimento - Backup automatico completo - Archivio ZIP per trasferimento - Metadata per ricostruzione ambiente - Verifica integrità dati ### 🔄 Backup e Recovery - Backup automatici programmati - Backup incrementali - Recovery point-in-time - Test integrità automatici ### 📊 Monitoring - Utilizzo spazio disco - Performance database - Log errori centralizzati - Statistiche utilizzo --- *Generato automaticamente da NetGescon v2.1.0* *Ultimo aggiornamento: " . date('d/m/Y H:i') . "* "; } }