netgescon-day0/app/Console/Commands/CreateAmministratoreStructure.php

385 lines
13 KiB
PHP
Executable File

<?php
namespace App\Console\Commands;
use App\Models\Amministratore;
use App\Services\DatabaseManagerService;
use App\Services\TenantArchivePathService;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\Storage;
class CreateAmministratoreStructure extends Command
{
protected $signature = 'netgescon:create-admin-structure {codice : Codice amministratore} {--force : Forza ricreazione se esiste}';
protected $description = 'Crea struttura completa per amministratore (database + cartelle)';
protected DatabaseManagerService $dbManager;
protected TenantArchivePathService $tenantArchivePath;
public function __construct(DatabaseManagerService $dbManager, TenantArchivePathService $tenantArchivePath)
{
parent::__construct();
$this->dbManager = $dbManager;
$this->tenantArchivePath = $tenantArchivePath;
}
public function handle(): int
{
$codice = $this->argument('codice');
$force = $this->option('force');
$this->info("🚀 Creazione struttura per amministratore: {$codice}");
// Trova amministratore per codice_amministratore o codice_univoco
$amministratore = Amministratore::where('codice_amministratore', $codice)
->orWhere('codice_univoco', $codice)
->first();
if (! $amministratore) {
$this->error("❌ Amministratore {$codice} non trovato");
return 1;
}
// Verifica se struttura esiste già
if ($amministratore->hasDedicatedDatabase() && ! $force) {
$this->warn("⚠️ Struttura già esistente. Usa --force per ricreare");
return 0;
}
// 1. Crea subito la struttura cartelle necessaria (prima del DB) così i file config/credentials possono essere scritti
$this->info("📁 Creazione struttura cartelle...");
$this->createAdvancedFolderStructure($amministratore);
// 2. Crea database dedicato (ora che le cartelle esistono)
$this->info("📦 Creazione database dedicato...");
$dbResult = $this->dbManager->createAmministratoreDatabase($amministratore);
if (! $dbResult['success']) {
$this->error("❌ Errore creazione database: " . $dbResult['error']);
return 1;
}
$this->info("✅ Database creato: " . $dbResult['database_name']);
// 3. Crea configurazioni
$this->info("⚙️ Creazione configurazioni...");
$this->createConfigurations($amministratore);
return 0;
}
private function createAdvancedFolderStructure(Amministratore $amministratore): void
{
$basePath = $this->tenantArchivePath->amministratoreRelativePath($amministratore);
$folders = [
// Documenti studio
'documenti/studio/contratti',
'documenti/studio/certificazioni',
'documenti/studio/assicurazioni',
'documenti/studio/comunicazioni',
'documenti/studio/fatturazione',
// Database e backup
'database/backups/daily',
'database/backups/weekly',
'database/backups/monthly',
'database/exports',
'database/migrations',
'database/scripts',
// Stabili (placeholder)
'stabili/.gitkeep',
// Log sistema
'logs/sistema',
'logs/accessi',
'logs/operazioni',
'logs/errori',
'logs/backup',
// Reports
'reports/mensili',
'reports/annuali',
'reports/custom',
// File temporanei
'temp/uploads',
'temp/processing',
'temp/exports',
'temp/imports',
'temp/migrations',
// Archivio
'archivio/per_anno',
'archivio/comunicazioni',
'archivio/assemblee',
'archivio/contratti_scaduti',
];
foreach ($folders as $folder) {
Storage::disk('local')->makeDirectory("{$basePath}/{$folder}");
}
// File .gitkeep per cartelle vuote
Storage::disk('local')->put("{$basePath}/stabili/.gitkeep", "# Cartella per database stabili amministrati\n");
}
private function createConfigurations(Amministratore $amministratore): void
{
$basePath = $this->tenantArchivePath->amministratoreRelativePath($amministratore);
// 1. Configurazione principale
$mainConfig = [
'amministratore' => [
'codice_amministratore' => $amministratore->codice_amministratore,
'nome_completo' => $amministratore->nome_completo,
'denominazione_studio' => $amministratore->denominazione_studio,
'database_principale' => $amministratore->getDatabaseName(),
'created_at' => $amministratore->created_at->toISOString(),
'version' => '2.1.0',
],
'database' => [
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => $amministratore->getDatabaseName(),
'backup_path' => 'database/backups',
'retention_days' => 90,
],
'backup' => [
'enabled' => true,
'frequency' => 'daily',
'time' => '02:00',
'retention_days' => 30,
'include_files' => true,
'include_database' => true,
'compress' => true,
],
'folders' => [
'documenti' => 'documenti',
'database' => 'database',
'stabili' => 'stabili',
'reports' => 'reports',
'temp' => 'temp',
'archivio' => 'archivio',
],
'security' => [
'log_level' => 'info',
'max_file_size' => '50MB',
'allowed_extensions' => ['pdf', 'doc', 'docx', 'xls', 'xlsx', 'jpg', 'png'],
'encryption' => false,
],
];
Storage::disk('local')->put(
"{$basePath}/config.json",
json_encode($mainConfig, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE)
);
// 2. README amministratore
$readme = $this->generateAdminReadme($amministratore);
Storage::disk('local')->put("{$basePath}/README.md", $readme);
// 3. Script di manutenzione
$maintenanceScript = $this->generateMaintenanceScript($amministratore);
Storage::disk('local')->put("{$basePath}/scripts/maintenance.sh", $maintenanceScript);
// 4. File di log iniziale
$logEntry = date('Y-m-d H:i:s') . " - Struttura amministratore {$amministratore->codice_amministratore} creata\n";
Storage::disk('local')->put("{$basePath}/logs/sistema/creation.log", $logEntry);
}
private function generateAdminReadme(Amministratore $amministratore): string
{
return "# 🏢 Amministratore: {$amministratore->nome_completo}
## 📋 Informazioni Generali
- **Codice Univoco**: `{$amministratore->codice_univoco}`
- **Denominazione Studio**: {$amministratore->denominazione_studio}
- **Database Principale**: `{$amministratore->getDatabaseName()}`
- **Creato**: {$amministratore->created_at->format('d/m/Y H:i')}
- **Versione NetGescon**: 2.1.0
## 📁 Struttura Archivio
### 🏗️ Documenti Studio
- `documenti/studio/contratti/` - Contratti di amministrazione
- `documenti/studio/certificazioni/` - Certificazioni professionali
- `documenti/studio/assicurazioni/` - Polizze assicurative
- `documenti/studio/comunicazioni/` - Comunicazioni ufficiali
- `documenti/studio/fatturazione/` - Fatture emesse
### 💾 Database e Backup
- `database/backups/daily/` - Backup giornalieri
- `database/backups/weekly/` - Backup settimanali
- `database/backups/monthly/` - Backup mensili
- `database/exports/` - Esportazioni dati
- `database/migrations/` - Script migrazione
- `database/scripts/` - Script personalizzati
- `stabili/[codice_stabile]/` - Cartella per ogni stabile
- Ogni stabile ha database e cartelle dedicati
- Backup indipendenti per ogni stabile
### 📊 Log e Monitoring
- `logs/sistema/` - Log operazioni sistema
- `logs/accessi/` - Log accessi utenti
- `logs/operazioni/` - Log CRUD operations
- `logs/errori/` - Log errori applicazione
- `logs/backup/` - Log operazioni backup
### 📈 Reports
- `reports/mensili/` - Report mensili automatici
- `reports/annuali/` - Report annuali
- `reports/custom/` - Report personalizzati
- `reports/amministratore/` - Report specifici studio
### 🔄 File Temporanei
- `temp/uploads/` - Upload temporanei
- `temp/processing/` - Elaborazioni in corso
- `temp/exports/` - Export temporanei
- `temp/imports/` - Import temporanei
- `temp/migrations/` - Migrazioni temporanee
### 📚 Archivio
- `archivio/per_anno/[YYYY]/` - Archivio annuale
- `archivio/comunicazioni/` - Comunicazioni archiviate
- `archivio/assemblee/` - Verbali assemblee
- `archivio/contratti_scaduti/` - Contratti scaduti
## 🔧 Funzionalità
### 📦 Gestione Database
- Database principale amministratore
- Database separati per ogni stabile
- Backup automatici programmati
- Export/import selettivi
### 📁 Gestione File
- Struttura gerarchica organizzata
- Upload sicuri con validazione
- Archiviazione automatica
- Ricerca avanzata documenti
### 🚚 Migrazione/Trasferimento
- Package completi per migrazione
- Script automatici restore
- Verifica integrità dati
- Trasferimento tra server
### 📊 Backup e Recovery
- Backup automatici multipli livelli
- Recovery point-in-time
- Backup incrementali
- Test integrità automatici
## ⚙️ Configurazioni
### 🔄 Backup Automatici
- **Frequenza**: Giornaliera alle 02:00
- **Retention**: 30 giorni
- **Includes**: Database + Files
- **Compressione**: Abilitata
### 🔐 Sicurezza
- Log accessi completi
- Validazione file upload
- Permessi filesystem controllati
- Audit trail operazioni
### 📈 Monitoring
- Utilizzo spazio disco
- Performance database
- Log errori centralizzati
- Statistiche utilizzo
## 🚀 Comandi Utili
### Backup Manuale
```bash
php artisan netgescon:backup-admin {$amministratore->codice_amministratore}
```
### Migrazione Completa
```bash
php artisan netgescon:migrate-admin {$amministratore->codice_amministratore}
```
### Verifica Integrità
```bash
php artisan netgescon:verify-admin {$amministratore->codice_amministratore}
```
### Pulizia File Temporanei
```bash
bash stabili/{$amministratore->codice_amministratore}/scripts/maintenance.sh
```
---
*Struttura generata automaticamente da NetGescon v2.1.0*
*Ultimo aggiornamento: " . date('d/m/Y H:i') . "*
*Amministratore: {$amministratore->nome_completo}*
";
}
private function generateMaintenanceScript(Amministratore $amministratore): string
{
return "#!/bin/bash
# Script manutenzione amministratore {$amministratore->codice_amministratore}
# Generato automaticamente da NetGescon
ADMIN_CODE=\"{$amministratore->codice_amministratore}\"
BASE_PATH=\"/var/www/netgescon/storage/app/amministratori/\$ADMIN_CODE\"
LOG_FILE=\"\$BASE_PATH/logs/sistema/maintenance.log\"
echo \"🧹 Avvio manutenzione amministratore \$ADMIN_CODE\" | tee -a \$LOG_FILE
# Pulizia file temporanei vecchi (> 7 giorni)
echo \"🗑️ Pulizia file temporanei...\" | tee -a \$LOG_FILE
find \"\$BASE_PATH/temp\" -type f -mtime +7 -delete 2>/dev/null
find \"\$BASE_PATH/temp\" -type d -empty -delete 2>/dev/null
# Pulizia log vecchi (> 90 giorni)
echo \"📝 Pulizia log vecchi...\" | tee -a \$LOG_FILE
find \"\$BASE_PATH/logs\" -name \"*.log\" -mtime +90 -delete 2>/dev/null
# Pulizia backup vecchi (> 30 giorni)
echo \"💾 Pulizia backup vecchi...\" | tee -a \$LOG_FILE
find \"\$BASE_PATH/database/backups\" -name \"*.sql\" -mtime +30 -delete 2>/dev/null
# Verifica integrità filesystem
echo \"🔍 Verifica integrità filesystem...\" | tee -a \$LOG_FILE
MISSING_DIRS=0
REQUIRED_DIRS=(\"documenti\" \"database\" \"logs\" \"reports\" \"temp\" \"archivio\")
for dir in \"\${REQUIRED_DIRS[@]}\"; do
if [ ! -d \"\$BASE_PATH/\$dir\" ]; then
echo \"⚠️ Directory mancante: \$dir\" | tee -a \$LOG_FILE
mkdir -p \"\$BASE_PATH/\$dir\"
MISSING_DIRS=\$((MISSING_DIRS + 1))
fi
done
# Calcola statistiche
TOTAL_SIZE=\$(du -sh \"\$BASE_PATH\" | cut -f1)
FILE_COUNT=\$(find \"\$BASE_PATH\" -type f | wc -l)
DIR_COUNT=\$(find \"\$BASE_PATH\" -type d | wc -l)
echo \"📊 Statistiche:\" | tee -a \$LOG_FILE
echo \" 📁 Directory: \$DIR_COUNT\" | tee -a \$LOG_FILE
echo \" 📄 File: \$FILE_COUNT\" | tee -a \$LOG_FILE
echo \" 💽 Spazio: \$TOTAL_SIZE\" | tee -a \$LOG_FILE
echo \" 🔧 Directory riparate: \$MISSING_DIRS\" | tee -a \$LOG_FILE
# Verifica permessi
echo \"🔐 Verifica permessi...\" | tee -a \$LOG_FILE
find \"\$BASE_PATH\" -type d -not -perm 755 -exec chmod 755 {} \\; 2>/dev/null
find \"\$BASE_PATH\" -type f -not -perm 644 -exec chmod 644 {} \\; 2>/dev/null
echo \"✅ Manutenzione completata: \$(date)\" | tee -a \$LOG_FILE
echo \"\" >> \$LOG_FILE
";
}
}