# NetGesCon - Sistema Aggiornamenti Automatici ## 🎯 Panoramica Sistema Il sistema di aggiornamenti automatici NetGesCon permette: - **Registrazione utenti** con codici 8 caratteri univoci - **Download automatico** aggiornamenti via API - **Backup pre-aggiornamento** automatico - **Rollback** in caso di errori - **Gestione versioni** (stable/development) - **Sistema licenze** basato su livello servizio ## 🏗️ Architettura Sistema ``` NetGesCon Master Server (update.netgescon.com) ├── API Registrazione Utenti ├── API Download Aggiornamenti ├── Database Utenti/Licenze ├── Repository Versioni └── Sistema Notifiche NetGesCon Client (Installazione Locale) ├── Update Service ├── Backup Manager ├── Version Manager └── License Validator ``` ## 📊 Database Schema ### Tabella: `registered_users` ```sql CREATE TABLE registered_users ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, codice_utente VARCHAR(8) UNIQUE NOT NULL, -- es: "USR12345" email VARCHAR(255) UNIQUE NOT NULL, nome VARCHAR(100) NOT NULL, cognome VARCHAR(100) NOT NULL, azienda VARCHAR(200), telefono VARCHAR(20), -- Licenza e Servizi livello_servizio ENUM('basic', 'professional', 'enterprise') DEFAULT 'basic', data_scadenza DATE, max_amministratori INT DEFAULT 5, max_stabili INT DEFAULT 50, features_abilitate JSON, -- {"multi_db": true, "audit": false, "api": true} -- Sicurezza api_key VARCHAR(64) UNIQUE, api_secret VARCHAR(128), ultimo_accesso TIMESTAMP NULL, ip_autorizzati TEXT, -- JSON array IP -- Sistema stato ENUM('attivo', 'sospeso', 'scaduto') DEFAULT 'attivo', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, deleted_at TIMESTAMP NULL ); ``` ### Tabella: `system_versions` ```sql CREATE TABLE system_versions ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, versione VARCHAR(20) NOT NULL, -- "2.1.0" tipo_release ENUM('stable', 'development', 'hotfix') DEFAULT 'stable', -- Files download_url VARCHAR(500), checksum_sha256 VARCHAR(64), dimensione_mb DECIMAL(8,2), -- Compatibilità versione_php_min VARCHAR(10), -- "8.2" versione_laravel_min VARCHAR(10), -- "10.0" versione_mysql_min VARCHAR(10), -- "8.0" -- Descrizione titolo VARCHAR(200), descrizione TEXT, changelog TEXT, breaking_changes TEXT, -- Controllo richiede_backup BOOLEAN DEFAULT true, richiede_downtime BOOLEAN DEFAULT false, compatibile_rollback BOOLEAN DEFAULT true, -- Metadata data_rilascio TIMESTAMP, stato ENUM('draft', 'testing', 'published', 'deprecated') DEFAULT 'draft', created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); ``` ### Tabella: `update_logs` ```sql CREATE TABLE update_logs ( id BIGINT UNSIGNED PRIMARY KEY AUTO_INCREMENT, codice_utente VARCHAR(8), versione_da VARCHAR(20), versione_a VARCHAR(20), -- Processo stato ENUM('started', 'downloading', 'backing_up', 'installing', 'completed', 'failed', 'rolled_back'), percentuale_completamento TINYINT DEFAULT 0, -- Dettagli log_output TEXT, errore_dettaglio TEXT, backup_path VARCHAR(500), tempo_inizio TIMESTAMP, tempo_fine TIMESTAMP, -- Sistema ip_client VARCHAR(45), user_agent TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP ); ``` ## 🔌 API Endpoints ### 1. Registrazione Utente ```http POST /api/v1/register Content-Type: application/json { "email": "admin@condominio.it", "nome": "Mario", "cognome": "Rossi", "azienda": "Amministrazioni Rossi SRL", "telefono": "+39 123 456 7890", "livello_servizio": "professional" } Response: { "success": true, "data": { "codice_utente": "USR12345", "api_key": "a1b2c3d4e5f6...", "api_secret": "secret_hash...", "scadenza": "2026-07-07", "features": { "multi_db": true, "audit": true, "api": true } } } ``` ### 2. Verifica Licenza ```http GET /api/v1/license/verify Authorization: Bearer {api_key} X-API-Secret: {api_secret} Response: { "valid": true, "scadenza": "2026-07-07", "giorni_rimanenti": 365, "livello": "professional", "limiti": { "amministratori": 20, "stabili": 200 }, "features": ["multi_db", "audit", "api"] } ``` ### 3. Check Aggiornamenti ```http GET /api/v1/updates/check Authorization: Bearer {api_key} X-Client-Version: 2.0.5 X-Release-Channel: stable Response: { "update_available": true, "latest_version": "2.1.0", "download_url": "https://update.netgescon.com/releases/2.1.0/netgescon-2.1.0.zip", "checksum": "sha256:a1b2c3...", "size_mb": 45.2, "changelog": "- Fix bug contabilità\n- Nuova UI dashboard...", "breaking_changes": false, "requires_backup": true } ``` ### 4. Download Aggiornamento ```http GET /api/v1/updates/download/{version} Authorization: Bearer {api_key} X-API-Secret: {api_secret} Response: [Binary ZIP file with update] ``` ## 💻 Client Update Service ### Comando Artisan: `update:check` ```php info('🔍 Controllo aggiornamenti NetGesCon...'); $channel = $this->option('channel'); $force = $this->option('force'); $result = $updateService->checkUpdates($channel, $force); if ($result['update_available']) { $this->info("✅ Aggiornamento disponibile:"); $this->table(['Campo', 'Valore'], [ ['Versione attuale', $result['current_version']], ['Nuova versione', $result['latest_version']], ['Tipo release', $result['release_type']], ['Dimensione', $result['size_mb'] . ' MB'], ['Richiede backup', $result['requires_backup'] ? 'Sì' : 'No'] ]); if ($this->confirm('Vuoi procedere con il download?')) { $this->call('update:download', ['version' => $result['latest_version']]); } } else { $this->info('✅ Sistema aggiornato alla versione più recente'); } } } ``` ### Comando Artisan: `update:install` ```php argument('version'); $skipBackup = $this->option('skip-backup'); $autoRollback = $this->option('rollback-on-error'); $this->info("🚀 Installazione NetGesCon v{$version}"); // 1. Validazione pre-installazione $this->info('📋 Validazione sistema...'); if (!$updateService->validateSystem($version)) { $this->error('❌ Sistema non compatibile con questa versione'); return 1; } // 2. Backup automatico if (!$skipBackup) { $this->info('💾 Creazione backup pre-aggiornamento...'); $backupPath = $backupService->createPreUpdateBackup($version); $this->info("Backup salvato: {$backupPath}"); } // 3. Download se necessario if (!$updateService->isVersionDownloaded($version)) { $this->info('⬇️ Download aggiornamento...'); $updateService->downloadVersion($version, function($progress) { $this->output->write("\r📦 Download: {$progress}%"); }); $this->newLine(); } // 4. Installazione $this->info('⚙️ Installazione in corso...'); try { $updateService->installVersion($version, function($step, $progress) { $this->output->write("\r🔧 {$step}: {$progress}%"); }); $this->newLine(); $this->info('✅ Aggiornamento completato con successo!'); $this->info("NetGesCon aggiornato alla versione {$version}"); } catch (\Exception $e) { $this->error("❌ Errore durante l'installazione: " . $e->getMessage()); if ($autoRollback && !$skipBackup) { $this->warn('🔄 Avvio rollback automatico...'); if ($backupService->restore($backupPath)) { $this->info('✅ Rollback completato'); } else { $this->error('❌ Errore durante il rollback'); } } return 1; } return 0; } } ``` ## 🔧 UpdateService Implementation ```php apiBaseUrl = config('netgescon.update.api_url'); $this->apiKey = config('netgescon.update.api_key'); $this->apiSecret = config('netgescon.update.api_secret'); $this->currentVersion = config('netgescon.version'); } public function checkUpdates(string $channel = 'stable', bool $force = false): array { // Cache del controllo (evita troppe chiamate API) $cacheKey = "updates_check_{$channel}"; if (!$force && cache()->has($cacheKey)) { return cache($cacheKey); } try { $response = Http::withHeaders([ 'Authorization' => "Bearer {$this->apiKey}", 'X-Client-Version' => $this->currentVersion, 'X-Release-Channel' => $channel ])->get("{$this->apiBaseUrl}/api/v1/updates/check"); if ($response->successful()) { $data = $response->json(); // Cache per 1 ora cache([$cacheKey => $data], 3600); return $data; } throw new \Exception('API non raggiungibile: ' . $response->status()); } catch (\Exception $e) { Log::error("Errore controllo aggiornamenti: " . $e->getMessage()); return [ 'update_available' => false, 'current_version' => $this->currentVersion, 'error' => $e->getMessage() ]; } } public function downloadVersion(string $version, $progressCallback = null): string { $downloadPath = storage_path("app/updates/{$version}"); $zipPath = "{$downloadPath}/netgescon-{$version}.zip"; if (!File::exists($downloadPath)) { File::makeDirectory($downloadPath, 0755, true); } $response = Http::withHeaders([ 'Authorization' => "Bearer {$this->apiKey}", 'X-API-Secret' => $this->apiSecret ])->withOptions([ 'sink' => $zipPath, 'progress' => function($downloadTotal, $downloadedBytes) use ($progressCallback) { if ($downloadTotal > 0 && $progressCallback) { $progress = round(($downloadedBytes / $downloadTotal) * 100); $progressCallback($progress); } } ])->get("{$this->apiBaseUrl}/api/v1/updates/download/{$version}"); if (!$response->successful()) { throw new \Exception("Errore download versione {$version}"); } // Verifica checksum $this->verifyChecksum($zipPath, $version); return $zipPath; } public function installVersion(string $version, $progressCallback = null): void { $zipPath = storage_path("app/updates/{$version}/netgescon-{$version}.zip"); $extractPath = storage_path("app/updates/{$version}/extracted"); if (!File::exists($zipPath)) { throw new \Exception("File aggiornamento non trovato: {$zipPath}"); } // 1. Estrazione $progressCallback && $progressCallback('Estrazione files', 10); $this->extractUpdate($zipPath, $extractPath); // 2. Backup configurazioni attuali $progressCallback && $progressCallback('Backup configurazioni', 20); $this->backupConfigurations(); // 3. Manutenzione mode $progressCallback && $progressCallback('Attivazione modalità manutenzione', 30); \Artisan::call('down'); try { // 4. Aggiornamento files $progressCallback && $progressCallback('Aggiornamento files applicazione', 40); $this->updateApplicationFiles($extractPath); // 5. Composer install $progressCallback && $progressCallback('Installazione dipendenze', 60); $this->runComposerInstall(); // 6. Database migrations $progressCallback && $progressCallback('Aggiornamento database', 75); \Artisan::call('migrate', ['--force' => true]); // 7. Cache refresh $progressCallback && $progressCallback('Aggiornamento cache', 85); $this->refreshCache(); // 8. NPM build $progressCallback && $progressCallback('Build assets', 95); $this->buildAssets(); } finally { // 9. Disattivazione manutenzione $progressCallback && $progressCallback('Riattivazione applicazione', 100); \Artisan::call('up'); } // 10. Aggiornamento versione $this->updateVersionFile($version); // 11. Cleanup $this->cleanupUpdateFiles($version); } private function extractUpdate(string $zipPath, string $extractPath): void { $zip = new \ZipArchive(); if ($zip->open($zipPath) === TRUE) { $zip->extractTo($extractPath); $zip->close(); } else { throw new \Exception("Impossibile estrarre {$zipPath}"); } } private function updateApplicationFiles(string $extractPath): void { // Lista files da NON sovrascrivere $preserveFiles = [ '.env', 'storage/app/*', 'storage/logs/*', 'storage/framework/cache/*', 'storage/framework/sessions/*', 'storage/framework/views/*' ]; // Copia files (eccetto quelli da preservare) File::copyDirectory($extractPath, base_path(), function($path) use ($preserveFiles) { foreach ($preserveFiles as $preserve) { if (fnmatch($preserve, $path)) { return false; // Non copiare } } return true; // Copia }); } private function verifyChecksum(string $filePath, string $version): void { // Ottieni checksum atteso dall'API $response = Http::withHeaders([ 'Authorization' => "Bearer {$this->apiKey}" ])->get("{$this->apiBaseUrl}/api/v1/updates/checksum/{$version}"); $expectedChecksum = $response->json()['checksum']; $actualChecksum = hash_file('sha256', $filePath); if ($expectedChecksum !== $actualChecksum) { throw new \Exception("Checksum non valido per versione {$version}"); } } } ``` ## ⚙️ Configurazione Client ### Config: `config/netgescon.php` ```php env('NETGESCON_VERSION', '2.0.0'), 'update' => [ 'api_url' => env('NETGESCON_UPDATE_API_URL', 'https://update.netgescon.com'), 'api_key' => env('NETGESCON_UPDATE_API_KEY'), 'api_secret' => env('NETGESCON_UPDATE_API_SECRET'), 'check_interval' => env('NETGESCON_UPDATE_CHECK_INTERVAL', 24), // ore 'auto_backup' => env('NETGESCON_UPDATE_AUTO_BACKUP', true), 'release_channel' => env('NETGESCON_RELEASE_CHANNEL', 'stable'), // stable|development ], 'license' => [ 'codice_utente' => env('NETGESCON_LICENSE_CODE'), 'livello_servizio' => env('NETGESCON_LICENSE_LEVEL', 'basic'), 'scadenza' => env('NETGESCON_LICENSE_EXPIRES'), ], ]; ``` ### Environment Variables (`.env`) ```env # NetGesCon Update System NETGESCON_VERSION=2.0.0 NETGESCON_UPDATE_API_URL=https://update.netgescon.com NETGESCON_UPDATE_API_KEY=your_api_key_here NETGESCON_UPDATE_API_SECRET=your_api_secret_here NETGESCON_UPDATE_CHECK_INTERVAL=24 NETGESCON_UPDATE_AUTO_BACKUP=true NETGESCON_RELEASE_CHANNEL=stable # License NETGESCON_LICENSE_CODE=USR12345 NETGESCON_LICENSE_LEVEL=professional NETGESCON_LICENSE_EXPIRES=2026-07-07 ``` ## 🕒 Scheduling Automatico ### `app/Console/Kernel.php` ```php protected function schedule(Schedule $schedule) { // Check aggiornamenti automatico (ogni 6 ore) $schedule->command('update:check --channel=stable') ->everySixHours() ->runInBackground() ->sendOutputTo(storage_path('logs/update-check.log')); // Verifica licenza (ogni giorno) $schedule->command('license:verify') ->daily() ->at('02:00'); // Cleanup update files (ogni settimana) $schedule->command('update:cleanup') ->weekly() ->sundays() ->at('03:00'); } ``` ## 🔔 Sistema Notifiche ### Notifica Aggiornamento Disponibile ```php updateInfo = $updateInfo; } public function via($notifiable) { return ['mail', 'database']; } public function toMail($notifiable) { return (new MailMessage) ->subject('NetGesCon: Aggiornamento Disponibile') ->greeting('Ciao ' . $notifiable->name) ->line("È disponibile una nuova versione di NetGesCon: {$this->updateInfo['latest_version']}") ->line("Versione attuale: {$this->updateInfo['current_version']}") ->line("Novità principali:") ->line($this->updateInfo['changelog']) ->action('Aggiorna Ora', url('/admin/updates')) ->line('Ti consigliamo di aggiornare per avere le ultime funzionalità e correzioni.'); } } ``` ## 📱 Frontend Update Manager ### Update Status Component (Vue.js) ```vue 🎉 Aggiornamento Disponibile! NetGesCon v{{ latestVersion }} è pronto per l'installazione Versione attuale: v{{ currentVersion }} 📋 Novità ⬆️ Aggiorna Ora ⚙️ Aggiornamento in corso... {{ currentStep }} ({{ progress }}%) {{ line }} ``` ## 🔒 Sicurezza e Validazione ### Validazione Checksum ```php private function validateDownload(string $filePath, string $expectedChecksum): bool { $actualChecksum = hash_file('sha256', $filePath); return hash_equals($expectedChecksum, $actualChecksum); } ``` ### Signature Verification (GPG) ```php private function verifySignature(string $filePath, string $signaturePath): bool { $publicKey = file_get_contents(resource_path('keys/netgescon-public.key')); // Implementa verifica GPG signature // ... return $isValid; } ``` ### Rate Limiting API ```php // routes/api.php Route::middleware(['throttle:10,1'])->group(function () { Route::get('/updates/check', [UpdateController::class, 'check']); Route::post('/updates/download', [UpdateController::class, 'download']); }); ``` ## 📊 Monitoring e Analytics ### Log Update Events ```php class UpdateEventLogger { public static function logUpdateStart(string $version): void { Log::info('Update started', [ 'version_from' => config('netgescon.version'), 'version_to' => $version, 'timestamp' => now(), 'user_ip' => request()->ip() ]); } public static function logUpdateComplete(string $version, int $duration): void { Log::info('Update completed', [ 'version' => $version, 'duration_seconds' => $duration, 'timestamp' => now() ]); } } ``` ### Metriche Sistema - Tempo medio aggiornamento - Tasso successo/fallimento - Versioni più utilizzate - Problemi comuni durante update --- ## 🎯 Roadmap Implementazione ### Fase 1: Foundation (Week 1-2) - ✅ Database schema design - ✅ API endpoints base - ⏳ UpdateService implementation - ⏳ Basic Artisan commands ### Fase 2: Core Features (Week 3-4) - ⏳ Download e installazione automatica - ⏳ Sistema backup/rollback - ⏳ Frontend update manager - ⏳ Notifiche sistema ### Fase 3: Advanced (Week 5-6) - ⏳ Gestione licenze - ⏳ Release channels - ⏳ Security features - ⏳ Monitoring e analytics ### Fase 4: Testing & Deployment (Week 7-8) - ⏳ Testing completo - ⏳ Documentation - ⏳ Production deployment - ⏳ User onboarding --- *Ultima modifica: 7 Luglio 2025*
NetGesCon v{{ latestVersion }} è pronto per l'installazione
{{ currentStep }} ({{ progress }}%)
{{ line }}