# πŸ“‹ GUIDA COMPLETA SVILUPPO MODULI NETGESCON **Versione: 1.0 - Data: 31 Luglio 2025** --- ## 🎯 **INTRODUZIONE** NetGescon utilizza un sistema modulare avanzato che permette di sviluppare, installare e monetizzare moduli aggiuntivi. Ogni modulo Γ¨ completamente autonomo e puΓ² essere distribuito come prodotto commerciale. ### **πŸ—οΈ ARCHITETTURA MODULARE** ``` NetGescon/ β”œβ”€β”€ app/ β”‚ β”œβ”€β”€ Services/ β”‚ β”‚ β”œβ”€β”€ ModuleManager.php # Gestione moduli β”‚ β”‚ └── HookManager.php # Sistema eventi β”‚ └── Modules/ β”‚ └── [NomeModulo]/ β”‚ β”œβ”€β”€ module.json # Configurazione modulo β”‚ β”œβ”€β”€ Controllers/ # Controller Laravel β”‚ β”œβ”€β”€ Routes/ # File route β”‚ β”œβ”€β”€ Migrations/ # Migrazioni database β”‚ β”œβ”€β”€ Seeders/ # Dati iniziali β”‚ β”œβ”€β”€ Views/ # Template Blade β”‚ └── Assets/ # CSS/JS specifici ``` --- ## πŸ”§ **STRUTTURA MODULO STANDARD** ### **1. Configurazione Base (module.json)** ```json { "name": "NomeModulo", "display_name": "Nome Visualizzato", "version": "1.0.0", "description": "Descrizione del modulo", "author": "Nome Sviluppatore", "email": "email@sviluppatore.com", "license": "commercial", "price": 99.00, "currency": "EUR", "billing": "yearly", "requirements": { "laravel": ">=10.0", "php": ">=8.1", "netgescon": ">=1.0" }, "dependencies": [], "permissions": { "modulo_view": "Visualizzare il modulo", "modulo_create": "Creare elementi", "modulo_edit": "Modificare elementi", "modulo_delete": "Eliminare elementi", "modulo_admin": "Amministrazione completa" }, "menu_items": [ { "title": "Dashboard Modulo", "route": "modulo.index", "icon": "fa-dashboard", "permission": "modulo_view", "order": 1 } ], "hooks": [ "modulo.before_create", "modulo.after_create", "modulo.before_update", "modulo.after_update", "modulo.before_delete", "modulo.after_delete" ], "config": { "auto_install_routes": true, "auto_install_migrations": true, "cache_enabled": true, "api_enabled": true } } ``` ### **2. Controller Base** ```php middleware('auth'); // Middleware permessi specifici del modulo $this->middleware('permission:modulo_view')->only(['index', 'show']); $this->middleware('permission:modulo_create')->only(['create', 'store']); $this->middleware('permission:modulo_edit')->only(['edit', 'update']); $this->middleware('permission:modulo_delete')->only(['destroy']); $this->hookManager = app(HookManager::class); } public function index(Request $request) { try { // Hook pre-azione $this->hookManager->execute('modulo.before_index', [$request]); // Logica del controller $data = DB::table('modulo_table')->paginate(20); // Hook post-azione $this->hookManager->execute('modulo.after_index', [$data]); return view('modules.nome-modulo.index', compact('data')); } catch (\Exception $e) { Log::error("Errore modulo: " . $e->getMessage()); return back()->with('error', 'Errore: ' . $e->getMessage()); } } // Altri metodi CRUD... } ``` ### **3. Routes (web.php)** ```php group(function () { // Route principali Route::prefix('nome-modulo')->name('modulo.')->group(function () { Route::get('/', [NomeModuloController::class, 'index'])->name('index'); Route::get('/create', [NomeModuloController::class, 'create'])->name('create'); Route::post('/', [NomeModuloController::class, 'store'])->name('store'); Route::get('/{id}', [NomeModuloController::class, 'show'])->name('show'); Route::get('/{id}/edit', [NomeModuloController::class, 'edit'])->name('edit'); Route::put('/{id}', [NomeModuloController::class, 'update'])->name('update'); Route::delete('/{id}', [NomeModuloController::class, 'destroy'])->name('destroy'); }); // Route API per AJAX Route::prefix('api/nome-modulo')->name('api.modulo.')->group(function () { Route::get('/data', [NomeModuloController::class, 'getData'])->name('data'); Route::post('/action', [NomeModuloController::class, 'action'])->name('action'); }); }); ``` ### **4. Migration Standard** ```php id(); $table->string('nome'); $table->text('descrizione')->nullable(); $table->enum('status', ['attivo', 'inattivo'])->default('attivo'); $table->json('config')->nullable(); // Audit fields standard $table->unsignedBigInteger('created_by')->nullable(); $table->unsignedBigInteger('updated_by')->nullable(); $table->timestamps(); $table->softDeletes(); // Indici per performance $table->index(['status', 'created_at']); $table->index('nome'); // Foreign keys $table->foreign('created_by')->references('id')->on('users')->onDelete('set null'); $table->foreign('updated_by')->references('id')->on('users')->onDelete('set null'); }); // Tabella log/cronologia Schema::create('modulo_history', function (Blueprint $table) { $table->id(); $table->unsignedBigInteger('record_id'); $table->string('action'); $table->json('old_data')->nullable(); $table->json('new_data')->nullable(); $table->unsignedBigInteger('user_id')->nullable(); $table->timestamp('created_at'); $table->index(['record_id', 'created_at']); $table->foreign('record_id')->references('id')->on('modulo_table')->onDelete('cascade'); $table->foreign('user_id')->references('id')->on('users')->onDelete('set null'); }); } public function down(): void { Schema::dropIfExists('modulo_history'); Schema::dropIfExists('modulo_table'); } }; ``` ### **5. Seeder con Dati Base** ```php 'modulo.default_setting', 'valore' => 'valore_default', 'descrizione' => 'Impostazione di default', 'created_at' => now(), 'updated_at' => now() ] ]; foreach ($configs as $config) { DB::table('modulo_config')->insert($config); } // Dati di esempio (solo in development) if (app()->environment('local', 'development')) { $esempi = [ [ 'nome' => 'Esempio 1', 'descrizione' => 'Dato di esempio', 'status' => 'attivo', 'created_by' => 1, 'created_at' => now(), 'updated_at' => now() ] ]; foreach ($esempi as $esempio) { DB::table('modulo_table')->insert($esempio); } } echo "βœ… Seeder NomeModulo completato\n"; } } ``` --- ## πŸ”Œ **SISTEMA HOOK E EVENTI** ### **Hook Disponibili nel Sistema** ```php // Hook di sistema core 'app.boot' // All'avvio dell'applicazione 'app.before_request' // Prima di ogni richiesta 'app.after_request' // Dopo ogni richiesta // Hook moduli 'module.before_install' // Prima installazione modulo 'module.after_install' // Dopo installazione modulo 'module.before_uninstall' // Prima disinstallazione 'module.after_uninstall' // Dopo disinstallazione // Hook utenti 'user.before_login' // Prima del login 'user.after_login' // Dopo il login 'user.before_logout' // Prima del logout // Hook del tuo modulo 'modulo.before_create' // Prima della creazione 'modulo.after_create' // Dopo la creazione 'modulo.before_update' // Prima dell'aggiornamento 'modulo.after_update' // Dopo l'aggiornamento 'modulo.before_delete' // Prima dell'eliminazione 'modulo.after_delete' // Dopo l'eliminazione ``` ### **Utilizzo Hook nel Modulo** ```php // Nel controller $this->hookManager->execute('modulo.before_create', [$data]); // Registrazione hook listener (nel boot del modulo) $this->hookManager->register('modulo.after_create', function($data) { // Logica eseguita dopo la creazione Log::info('Nuovo elemento creato: ' . $data['nome']); }); ``` --- ## πŸ’Ύ **DATABASE E PERFORMANCE** ### **Best Practices Database** 1. **Nomi Tabelle**: Sempre prefisso modulo (`modulo_tabella`) 2. **Indici**: Su campi piΓΉ interrogati (`status`, `created_at`, ecc.) 3. **Foreign Keys**: Sempre con `onDelete('set null')` o `cascade` 4. **Soft Deletes**: Per dati importanti 5. **JSON Fields**: Per configurazioni flessibili 6. **Audit Trail**: Campi `created_by`, `updated_by`, `deleted_by` ### **Ottimizzazioni Consigliate** ```php // Uso di scope nei Model public function scopeAttivo($query) { return $query->where('status', 'attivo'); } // Cache per query pesanti $data = Cache::tags(['modulo_data'])->remember('modulo_list', 3600, function() { return DB::table('modulo_table')->where('status', 'attivo')->get(); }); // Query Builder ottimizzate $risultati = DB::table('modulo_table') ->select(['id', 'nome', 'status']) // Solo campi necessari ->where('status', 'attivo') ->orderBy('created_at', 'desc') ->limit(20) ->get(); ``` --- ## πŸ” **SICUREZZA E PERMESSI** ### **Sistema Permessi** ```php // Definizione permessi nel module.json "permissions": { "modulo_view": "Visualizzare elementi del modulo", "modulo_create": "Creare nuovi elementi", "modulo_edit": "Modificare elementi esistenti", "modulo_delete": "Eliminare elementi", "modulo_export": "Esportare dati", "modulo_admin": "Amministrazione completa modulo" } // Uso nei controller $this->middleware('permission:modulo_view')->only(['index', 'show']); $this->middleware('permission:modulo_create')->only(['create', 'store']); // Controllo nei template Blade @can('modulo_create') Nuovo @endcan ``` ### **Validazione Input** ```php // Nel controller public function store(Request $request) { $validated = $request->validate([ 'nome' => 'required|string|max:255|unique:modulo_table', 'email' => 'required|email', 'importo' => 'required|numeric|min:0', 'data' => 'required|date|after:today' ]); // Sanitizzazione aggiuntiva $validated['nome'] = strip_tags($validated['nome']); // Creazione record... } ``` --- ## πŸ“¦ **INSTALLAZIONE E DISTRIBUZIONE** ### **Processo di Installazione** 1. **Preparazione ZIP**: ``` NomeModulo.zip β”œβ”€β”€ module.json β”œβ”€β”€ Controllers/ β”œβ”€β”€ Routes/ β”œβ”€β”€ Migrations/ β”œβ”€β”€ Seeders/ └── Views/ ``` 2. **Installazione via ModuleManager**: ```php $moduleManager = app(ModuleManager::class); $result = $moduleManager->installModule('NomeModulo', $zipPath); ``` 3. **Registrazione Automatica**: - Route caricate automaticamente - Migration eseguite - Permessi registrati - Menu integrato ### **Command Artisan per Installazione** ```php // app/Console/Commands/InstallModule.php class InstallModule extends Command { protected $signature = 'module:install {name} {--zip=}'; public function handle() { $name = $this->argument('name'); $zipPath = $this->option('zip'); $moduleManager = app(ModuleManager::class); try { $result = $moduleManager->installModule($name, $zipPath); $this->info("βœ… Modulo {$name} installato con successo!"); } catch (\Exception $e) { $this->error("❌ Errore installazione: " . $e->getMessage()); } } } ``` --- ## 🎨 **FRONTEND E UX** ### **Template Blade Base** ```blade {{-- resources/views/modules/nome-modulo/index.blade.php --}} @extends('layouts.app') @section('title', 'Nome Modulo') @section('content')

Nome Modulo

@can('modulo_create') Nuovo @endcan
{{-- Filtri di ricerca --}}
{{-- Tabella dati --}}
@forelse($data as $item) @empty @endforelse
Nome Status Data Creazione Azioni
{{ $item->nome }} {{ ucfirst($item->status) }} {{ $item->created_at->format('d/m/Y H:i') }} @can('modulo_view') @endcan @can('modulo_edit') @endcan @can('modulo_delete')
@csrf @method('DELETE')
@endcan
Nessun elemento trovato
{{-- Paginazione --}} {{ $data->links() }}
@endsection ``` ### **CSS/JS Specifici del Modulo** ```css /* public/css/modules/nome-modulo.css */ .modulo-card { border-radius: 10px; box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1); } .modulo-stats { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; border-radius: 8px; padding: 20px; } ``` --- ## πŸ§ͺ **TESTING E DEBUG** ### **Unit Test Base** ```php create(); $user->givePermissionTo('modulo_view'); $response = $this->actingAs($user)->get(route('modulo.index')); $response->assertStatus(200); $response->assertViewIs('modules.nome-modulo.index'); } public function test_create_requires_permission() { $user = User::factory()->create(); $response = $this->actingAs($user)->get(route('modulo.create')); $response->assertStatus(403); } public function test_store_validates_input() { $user = User::factory()->create(); $user->givePermissionTo('modulo_create'); $response = $this->actingAs($user)->post(route('modulo.store'), []); $response->assertSessionHasErrors(['nome', 'email']); } } ``` ### **Logging e Debug** ```php // Nel controller use Illuminate\Support\Facades\Log; public function action() { Log::info('Modulo: Inizio azione', ['user' => auth()->id()]); try { // Logica Log::debug('Modulo: Dati elaborati', ['data' => $processedData]); } catch (\Exception $e) { Log::error('Modulo: Errore azione', [ 'error' => $e->getMessage(), 'trace' => $e->getTraceAsString(), 'user' => auth()->id() ]); } } ``` --- ## πŸ’° **MODELLO BUSINESS E PRICING** ### **Categorie di Moduli** 1. **Gratuiti** (€0): - Moduli base/community - FunzionalitΓ  essenziali 2. **Standard** (€49-99/anno): - Moduli specializzati - FunzionalitΓ  avanzate 3. **Premium** (€199-299/anno): - Moduli complessi - Integrazione esterna - Support prioritario 4. **Enterprise** (€499+/anno): - Moduli mission-critical - Customizzazione - SLA garantiti ### **Licenze e Distribuzione** ```json { "license": "commercial", "price": 99.00, "currency": "EUR", "billing": "yearly", "trial_days": 30, "support_included": true, "updates_included": true, "installation_limit": 1 } ``` --- ## πŸš€ **DEPLOYMENT E MANUTENZIONE** ### **Checklist Pre-Release** - [ ] Test su ambiente locale - [ ] Validazione sicurezza - [ ] Performance test - [ ] Documentazione completa - [ ] Screenshot/demo - [ ] Pricing definito - [ ] Support plan ### **Processo di Aggiornamento** ```php // Migration di aggiornamento public function up(): void { // Verifica versione precedente $currentVersion = DB::table('modules') ->where('name', 'NomeModulo') ->value('version'); if (version_compare($currentVersion, '1.1.0', '<')) { // Modifiche per v1.1.0 Schema::table('modulo_table', function (Blueprint $table) { $table->string('nuovo_campo')->nullable(); }); } } ``` --- ## πŸ“š **RISORSE E SUPPORTO** ### **Documentazione Obbligatoria** 1. **README.md** - Panoramica e installazione 2. **CHANGELOG.md** - Log delle modifiche 3. **API.md** - Documentazione API se presente 4. **HELP.md** - Guida utente ### **Support e Community** - Forum sviluppatori NetGescon - Documentation wiki - Code repository template - Issue tracking system --- ## βœ… **CHECKLIST MODULO COMPLETO** ### **Files Essenziali** - [ ] `module.json` configurato - [ ] Controller con CRUD base - [ ] Route definitions - [ ] Migration database - [ ] Seeder con dati base - [ ] Template Blade base - [ ] Middleware permessi - [ ] Hook integration - [ ] Unit tests - [ ] Documentazione ### **FunzionalitΓ  Base** - [ ] Autenticazione/Autorizzazione - [ ] CRUD operations - [ ] Ricerca e filtri - [ ] Paginazione - [ ] Export dati - [ ] Logging attivitΓ  - [ ] Cache optimization - [ ] Error handling - [ ] Input validation - [ ] API endpoints ### **QualitΓ  Codice** - [ ] PSR-4 compliance - [ ] Commenti e documentation - [ ] Error handling robusto - [ ] Security best practices - [ ] Performance optimization - [ ] Mobile responsive UI - [ ] Cross-browser compatibility - [ ] Accessibility standards --- **🎯 CONCLUSIONE** Questa guida fornisce tutto il necessario per sviluppare moduli professionali per NetGescon. Il sistema modulare Γ¨ progettato per essere: - **Scalabile**: Supporta crescita dell'applicazione - **Sicuro**: Permessi granulari e validazione - **Performante**: Cache e ottimizzazioni database - **Manutenibile**: Codice pulito e documentato - **Commerciale**: Modello business integrato Utilizzando questa specifica, puoi sviluppare moduli che si integrano perfettamente con NetGescon e possono essere distribuiti come prodotti commerciali. --- **πŸ“ž CONTATTI SVILUPPO** - Team NetGescon - Email: dev@netgescon.com - Repository: https://github.com/netgescon/modules