netgescon-master/docs/MANUALE-TECNICO-RISOLUZIONE-PROBLEMI.md

13 KiB
Raw Blame History

🛠️ MANUALE TECNICO NETGESCON - RISOLUZIONE PROBLEMI E BEST PRACTICES

Data Aggiornamento: 21 Luglio 2025
Versione: 2.1.0
Autore: GitHub Copilot + Team NetGescon

📋 INDICE RAPIDO

  1. Problemi Risolti Oggi
  2. Errori Comuni e Soluzioni
  3. Best Practices Blade Templates
  4. Sistema Tab Unificato
  5. Gestione Relazioni Database
  6. Debug e Testing
  7. Checklist Pre-Deploy

PROBLEMI RISOLTI OGGI

1. Errore Sintassi PHP - Carattere Unicode

ERRORE: syntax error, unexpected identifier "×", expecting ")" 
FILE: resources/views/admin/stabili/show.blade.php :169

CAUSA: Uso di carattere moltiplicazione Unicode × invece dell'operatore PHP *

SOLUZIONE:

// ❌ ERRATO
{{ ($palazzina->numero_scale ?? 1) × ($palazzina->numero_piani ?? 3) }}

// ✅ CORRETTO  
{{ ($palazzina->numero_scale ?? 1) * ($palazzina->numero_piani ?? 3) }}

PREVENZIONE: Usare sempre operatori PHP standard, non caratteri speciali Unicode

2. Errore Relazioni Null

ERRORE: Call to a member function count() on null
FILE: resources/views/admin/stabili/show.blade.php :121

CAUSA: Chiamata metodi su relazioni non caricate o null

SOLUZIONE:

// ❌ ERRATO - Può causare errore se relazione è null
{{ $stabile->palazzine->count() }}

// ✅ CORRETTO - Usa nullsafe operator
{{ $stabile->palazzine?->count() ?? 0 }}

// ✅ ALTERNATIVA - Verifica esistenza
{{ ($stabile->palazzine && $stabile->palazzine->count()) ? $stabile->palazzine->count() : 0 }}

PREVENZIONE: Usare sempre ?-> per relazioni che potrebbero essere null

3. Rotte Non Definite

ERRORE: Route [admin.unita_immobiliari.index] not defined
FILE: resources/views/admin/stabili/tabs/dati-generali.blade.php :214

CAUSA: Riferimento a rotte non esistenti nel sistema di routing

SOLUZIONE:

// ✅ Verifica esistenza rotta prima di usarla
@if(Route::has('admin.unita_immobiliari.index'))
    <a href="{{ route('admin.unita_immobiliari.index') }}">
@else
    <a href="#" onclick="alert('Funzionalità in sviluppo')">
@endif

4. Metodi Controller Mancanti

ERRORE: Method App\Http\Controllers\Admin\StabileController::authorize does not exist
FILE: app/Http/Controllers/Admin/StabileController.php :76

CAUSA: Chiamata a metodi non implementati nel controller

SOLUZIONE: Implementare il metodo o rimuovere la chiamata


🔧 ERRORI COMUNI E SOLUZIONI

A. Errori Blade Template

1. Variabili Non Definite

// ❌ ERRATO
{{ $variabile->proprieta }}

// ✅ CORRETTO
{{ $variabile->proprieta ?? 'Valore Default' }}
{{ isset($variabile) ? $variabile->proprieta : 'Default' }}

2. Include Files Mancanti

// ❌ ERRATO
@include('admin.stabili.tabs.non-esistente')

// ✅ CORRETTO - Verifica esistenza
@if(view()->exists('admin.stabili.tabs.tab-name'))
    @include('admin.stabili.tabs.tab-name')
@else
    <p>Contenuto in sviluppo</p>
@endif

3. Loop su Collezioni Null

// ❌ ERRATO
@foreach($stabile->palazzine as $palazzina)

// ✅ CORRETTO
@forelse($stabile->palazzine ?? [] as $palazzina)
    // Contenuto
@empty
    <p>Nessun elemento trovato</p>
@endforelse

B. Errori JavaScript

1. Selezione Elementi DOM

// ❌ ERRATO - Può essere null
const element = document.getElementById('tab-content');
element.classList.add('active');

// ✅ CORRETTO - Verifica esistenza
const element = document.getElementById('tab-content');
if (element) {
    element.classList.add('active');
}

2. Event Listeners

// ✅ BEST PRACTICE - Usa delegazione eventi
document.addEventListener('DOMContentLoaded', function() {
    // Inizializzazione sicura
    const buttons = document.querySelectorAll('.netgescon-tab-btn');
    buttons.forEach(button => {
        if (button) {
            button.addEventListener('click', handleTabClick);
        }
    });
});

🎨 BEST PRACTICES BLADE TEMPLATES

1. Struttura Standardizzata Tab

<!-- Tab Navigation -->
<nav class="-mb-px flex space-x-8" aria-label="Tabs" role="tablist">
    <button class="netgescon-tab-btn active" 
            data-tab="nome-tab" 
            type="button" 
            role="tab">
        <i class="fas fa-icon mr-2"></i>
        Nome Tab
    </button>
</nav>

<!-- Tab Content -->
<div id="nome-tab" class="netgescon-tab-content active">
    @include('path.to.tab-content', ['parametri' => $variabili])
</div>

2. Gestione Sicura Dati

<!-- Sempre usare nullsafe e default values -->
<p>{{ $oggetto?->proprieta ?? 'N/D' }}</p>

<!-- Per collezioni -->
<div>Totale: {{ $oggetto?->collezione?->count() ?? 0 }}</div>

<!-- Per date -->
<time>{{ $oggetto?->created_at?->format('d/m/Y') ?? 'N/D' }}</time>

3. Classi CSS Standardizzate

/* Mantenere consistenza classi */
.netgescon-tab-btn { /* Stili tab button */ }
.netgescon-tab-content { /* Stili contenuto tab */ }
.netgescon-btn { /* Stili bottoni */ }
.netgescon-card { /* Stili card */ }

🔄 SISTEMA TAB UNIFICATO

Implementazione JavaScript Standard

// File: resources/js/netgescon-tabs.js
class NetGesconTabs {
    constructor() {
        this.init();
    }
    
    init() {
        document.addEventListener('DOMContentLoaded', () => {
            this.bindEvents();
        });
    }
    
    bindEvents() {
        const tabButtons = document.querySelectorAll('.netgescon-tab-btn');
        tabButtons.forEach(button => {
            button.addEventListener('click', (e) => this.handleTabClick(e));
        });
    }
    
    handleTabClick(event) {
        const button = event.currentTarget;
        const targetTab = button.dataset.tab;
        
        if (!targetTab) return;
        
        // Reset tutti i tab
        this.resetAllTabs();
        
        // Attiva tab selezionato
        this.activateTab(button, targetTab);
        
        // Carica contenuto dinamico se necessario
        this.loadDynamicContent(targetTab);
    }
    
    resetAllTabs() {
        document.querySelectorAll('.netgescon-tab-btn').forEach(btn => {
            btn.classList.remove('active');
        });
        
        document.querySelectorAll('.netgescon-tab-content').forEach(content => {
            content.classList.remove('active');
            content.classList.add('hidden');
        });
    }
    
    activateTab(button, targetTab) {
        button.classList.add('active');
        
        const targetContent = document.getElementById(targetTab);
        if (targetContent) {
            targetContent.classList.add('active');
            targetContent.classList.remove('hidden');
        }
    }
    
    loadDynamicContent(tabName) {
        // Implementazione specifica per tab che richiedono caricamento dinamico
        const dynamicTabs = ['unita-immobiliari', 'documenti-collegati'];
        
        if (dynamicTabs.includes(tabName)) {
            const container = document.getElementById(`${tabName}-content`);
            if (container && !container.dataset.loaded) {
                this.fetchTabContent(tabName, container);
            }
        }
    }
    
    async fetchTabContent(tabName, container) {
        try {
            const stabileId = window.stabileId || container.dataset.stabileId;
            const response = await fetch(`/admin/stabili/${stabileId}/${tabName}`, {
                headers: {
                    'X-Requested-With': 'XMLHttpRequest',
                    'Accept': 'application/json',
                    'X-CSRF-TOKEN': document.querySelector('meta[name="csrf-token"]').getAttribute('content')
                }
            });
            
            const data = await response.json();
            
            if (data.success) {
                container.innerHTML = data.html;
                container.dataset.loaded = 'true';
            } else {
                this.showError(container, 'Errore nel caricamento dei dati');
            }
        } catch (error) {
            console.error('Errore caricamento tab:', error);
            this.showError(container, 'Errore di connessione');
        }
    }
    
    showError(container, message) {
        container.innerHTML = `
            <div class="text-center py-8">
                <div class="text-red-600">
                    <i class="fas fa-exclamation-triangle text-2xl mb-2"></i>
                    <p>${message}</p>
                </div>
            </div>
        `;
    }
}

// Inizializza sistema tab
new NetGesconTabs();

🗄️ GESTIONE RELAZIONI DATABASE

Caricamento Sicuro Relazioni

// Nel Controller
public function show(Stabile $stabile)
{
    // Carica relazioni in modo esplicito
    $stabile->load([
        'palazzine' => function($query) {
            $query->orderBy('codice');
        },
        'unitaImmobiliari',
        'datiBancari.contatto',
        'tabelleMillesimali' => function($query) {
            $query->orderBy('tipologia')->orderBy('anno', 'desc');
        },
        'documenti' => function($query) {
            $query->orderBy('created_at', 'desc');
        }
    ]);
    
    return view('admin.stabili.show', compact('stabile'));
}

Validazione Dati Blade

<!-- Template sicuro per relazioni -->
@if($stabile && $stabile->relationLoaded('palazzine'))
    @forelse($stabile->palazzine as $palazzina)
        <!-- Contenuto -->
    @empty
        <!-- Messaggio vuoto -->
    @endforelse
@else
    <!-- Loading o messaggio alternativo -->
@endif

🐛 DEBUG E TESTING

1. Debug Veloce

// In Blade template - Solo per sviluppo
@if(config('app.debug'))
    <div class="bg-yellow-100 p-2 text-xs">
        Debug: {{ json_encode($stabile->palazzine?->count()) }}
    </div>
@endif

2. Log Errori

// Nel Controller
try {
    $data = $this->processData();
} catch (\Exception $e) {
    \Log::error('Errore processamento dati: ' . $e->getMessage(), [
        'file' => $e->getFile(),
        'line' => $e->getLine(),
        'stabile_id' => $stabile->id ?? null
    ]);
    
    return back()->with('error', 'Errore nel caricamento dei dati');
}

3. Comandi Artisan Utili

# Pulizia cache
php artisan config:clear
php artisan view:clear
php artisan route:clear

# Debug rotte
php artisan route:list | grep stabili

# Test sintassi PHP
php -l resources/views/admin/stabili/show.blade.php

# Verifica database
php artisan migrate:status

CHECKLIST PRE-DEPLOY

File da Controllare Sempre

  • Sintassi PHP: find . -name "*.php" -exec php -l {} \;
  • Blade Templates: Verificare tutti gli @include esistono
  • Relazioni Database: Controllare ?-> per relazioni nullable
  • Rotte: Verificare tutte le route() sono definite
  • JavaScript: Controllare selezione DOM e event listener
  • CSS: Verificare classi standardizzate
  • Immagini/Asset: Controllare percorsi file

Test Funzionalità

  • Tab Navigation: Tutti i tab si aprono correttamente
  • Form Submission: Creazione e modifica stabili
  • AJAX Loading: Caricamento dinamico contenuti
  • Error Handling: Gestione errori 404/500
  • Mobile Responsive: Test su dispositivi mobili

Performance

  • Query Optimization: Eager loading relazioni
  • Cache: Configurazione cache attiva
  • Assets: Minificazione CSS/JS
  • Database: Indici su colonne utilizzate

📝 TEMPLATE COMMENTI CODICE

Blade Templates

{{-- 
    NETGESCON TAB: [Nome Tab]
    Descrizione: [Descrizione funzionalità]
    Dipendenze: [Liste dipendenze]
    Autore: GitHub Copilot
    Data: 21/07/2025
--}}

{{-- Header Tab con controlli --}}
<div class="flex justify-between items-center">
    {{-- Titolo e descrizione --}}
    <div>
        <h4 class="text-xl font-semibold text-gray-900">
            <i class="fas fa-icon mr-2 text-color"></i>
            Titolo Tab
        </h4>
        <p class="text-sm text-gray-600 mt-1">
            Descrizione funzionalità tab
        </p>
    </div>
    
    {{-- Pulsanti azione --}}
    <div class="space-x-2">
        <!-- Pulsanti azione -->
    </div>
</div>

JavaScript

/**
 * NETGESCON: [Nome Funzione]
 * Descrizione: [Descrizione funzionalità]
 * 
 * @param {type} parametro - Descrizione parametro
 * @returns {type} Descrizione return
 * 
 * @author GitHub Copilot
 * @date 21/07/2025
 * @version 1.0.0
 */
function nomeFunction(parametro) {
    // Implementazione
}

🎯 PROSSIMI PASSI

  1. Implementare Sistema Seeder per dati demo persistenti
  2. Creare Test Automatici per prevenire regressioni
  3. Ottimizzare Performance con eager loading
  4. Documentare API per integrazioni future
  5. Setup CI/CD per deploy automatici

📞 SUPPORTO TECNICO
Per problemi urgenti, consultare sempre questo manuale prima di procedere con modifiche al codice.

🔄 AGGIORNAMENTI
Questo manuale verrà aggiornato ad ogni sessione di sviluppo con nuovi problemi risolti e best practices.