++ Primo Caricamento

This commit is contained in:
2026-03-30 19:15:13 +02:00
commit 663a68d59b
47 changed files with 3561 additions and 0 deletions

54
config/app.php Normal file
View File

@@ -0,0 +1,54 @@
<?php
// ─────────────────────────────────────────────────────────────────────────────
// config/app.php — Configurazione principale dell'applicazione
//
// Nota: la maggior parte dei valori viene letta dal .env tramite env().
// La funzione env('CHIAVE', 'default') legge la variabile di ambiente;
// se non esiste, usa il valore di default.
// ─────────────────────────────────────────────────────────────────────────────
return [
// ─── Identità ──────────────────────────────────────────────────────────
'name' => env('APP_NAME', 'Portale Clienti'),
'env' => env('APP_ENV', 'production'),
// debug=true mostra la stack trace completa in caso di errore.
// In produzione DEVE essere false!
'debug' => (bool) env('APP_DEBUG', false),
'url' => env('APP_URL', 'http://localhost'),
// ─── Localizzazione ───────────────────────────────────────────────────
// timezone: usato da Carbon (date/ore) e dai log
'timezone' => 'Europe/Rome',
// locale: lingua usata per traduzioni e formattazione
'locale' => 'it',
'fallback_locale' => 'en',
// faker_locale: usato nei seeder per generare dati finti in italiano
'faker_locale' => 'it_IT',
// ─── Ciclo di vita richiesta ───────────────────────────────────────────
'maintenance' => [
'driver' => 'file',
// 'store' => 'redis', // Alternativa: usa Redis per cluster multi-server
],
// ─── Cifratura ────────────────────────────────────────────────────────
// cipher: algoritmo usato per cifrare cookie e sessioni
'cipher' => 'AES-256-CBC',
// key: chiave segreta, generata da `php artisan key:generate`
// MAI condividere questa chiave!
'key' => env('APP_KEY'),
// previous_keys: chiavi precedenti (per rotazione senza invalidare sessioni)
'previous_keys' => [
...array_filter(
explode(',', env('APP_PREVIOUS_KEYS', ''))
),
],
];

84
config/database.php Normal file
View File

@@ -0,0 +1,84 @@
<?php
// ─────────────────────────────────────────────────────────────────────────────
// config/database.php — Configurazione database
//
// Supporta più connessioni contemporaneamente. Il default è MySQL.
// ─────────────────────────────────────────────────────────────────────────────
return [
// Connessione di default (usata da tutti i Model, a meno che non sia specificata)
'default' => env('DB_CONNECTION', 'mysql'),
'connections' => [
// ── SQLite: utile per test rapidi ────────────────────────────────────
'sqlite' => [
'driver' => 'sqlite',
'url' => env('DB_URL'),
'database' => env('DB_DATABASE', database_path('database.sqlite')),
'prefix' => '',
'foreign_key_constraints' => env('DB_FOREIGN_KEYS', true),
],
// ── MySQL: usato in questo progetto ──────────────────────────────────
'mysql' => [
'driver' => 'mysql',
'url' => env('DB_URL'),
// host: nel Docker è il nome del servizio nel docker-compose (es. "db")
'host' => env('DB_HOST', '127.0.0.1'),
'port' => env('DB_PORT', '3306'),
'database' => env('DB_DATABASE', 'laravel'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'charset' => env('DB_CHARSET', 'utf8mb4'),
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
'prefix' => '',
'prefix_indexes' => true,
'strict' => true,
'engine' => null,
// options TLS: scommentare in produzione con SSL
'options' => extension_loaded('pdo_mysql') ? array_filter([
PDO::MYSQL_ATTR_SSL_CA => env('MYSQL_ATTR_SSL_CA'),
]) : [],
],
],
// ─── Migrations ──────────────────────────────────────────────────────────
// Tabella che traccia quali migration sono già state eseguite
'migrations' => [
'table' => 'migrations',
'update_date_on_publish' => true,
],
// ─── Redis ────────────────────────────────────────────────────────────────
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', 'portale_'), // Prefisso chiavi
],
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_DB', '0'),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'username' => env('REDIS_USERNAME'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT', '6379'),
'database' => env('REDIS_CACHE_DB', '1'), // DB separato per la cache
],
],
];

90
config/settings.php Normal file
View File

@@ -0,0 +1,90 @@
<?php
// ─────────────────────────────────────────────────────────────────────────────
// config/settings.php — Impostazioni dinamiche dell'applicazione
//
// DIFFERENZA FONDAMENTALE rispetto al .env:
//
// .env / config/*.php → configurazione STATICA (infrastruttura, connessioni)
// Cambia raramente. Richiede restart del container.
//
// settings (questo file + tabella DB)
// → configurazione DINAMICA (business logic)
// Modificabile dall'admin via pannello web,
// senza restart. Cambia nel tempo.
//
// COME FUNZIONA:
// 1. I valori di default sono qui (fallback se la tabella DB è vuota)
// 2. Al primo avvio, il SettingSeeder popola la tabella `settings`
// 3. SettingService::get('chiave') legge dalla tabella (con cache Redis)
// 4. Il pannello Impostazioni permette di modificarli via web
//
// ESEMPIO D'USO in un Controller o View:
// $perPage = app(SettingService::class)->get('items_per_page');
// // oppure tramite helper globale (se definito):
// $valuta = setting('currency_symbol');
// ─────────────────────────────────────────────────────────────────────────────
return [
// ─── Valori di default ─────────────────────────────────────────────────
// Usati come fallback se la chiave non esiste nella tabella DB.
// Modificare questi valori richiede un deploy; per cambiamenti frequenti
// usa direttamente il pannello impostazioni.
'defaults' => [
'company_name' => 'La Mia Azienda',
'currency' => 'EUR',
'currency_symbol' => '€',
'date_format' => 'd/m/Y',
'items_per_page' => 15,
'welcome_message' => 'Benvenuto nel Portale Clienti!',
'allow_notes' => true,
'theme_color' => '#0d6efd',
'support_email' => 'supporto@example.com',
'max_file_size_mb' => 10,
],
// ─── Descrizioni leggibili ─────────────────────────────────────────────
// Visualizzate nel pannello impostazioni come label/tooltip.
'descriptions' => [
'company_name' => 'Nome della tua azienda (mostrato in header e report)',
'currency' => 'Codice valuta ISO 4217 (es. EUR, USD, GBP)',
'currency_symbol' => 'Simbolo valuta visualizzato nei prezzi (es. €, $)',
'date_format' => 'Formato date (sintassi PHP: d/m/Y, Y-m-d, ecc.)',
'items_per_page' => 'Numero di righe nelle tabelle paginate',
'welcome_message' => 'Messaggio mostrato nella dashboard',
'allow_notes' => 'Abilita il campo note nelle schede cliente',
'theme_color' => 'Colore principale dell\'interfaccia (hex, es. #0d6efd)',
'support_email' => 'Email mostrata ai clienti per richieste di supporto',
'max_file_size_mb' => 'Dimensione massima upload allegati (in MB)',
],
// ─── Tipi di dato ──────────────────────────────────────────────────────
// Usati da SettingService per convertire i valori al tipo corretto.
// La tabella DB salva tutto come stringa; il tipo definisce il cast.
'types' => [
'company_name' => 'string',
'currency' => 'string',
'currency_symbol' => 'string',
'date_format' => 'string',
'items_per_page' => 'integer',
'welcome_message' => 'text',
'allow_notes' => 'boolean',
'theme_color' => 'string',
'support_email' => 'string',
'max_file_size_mb' => 'integer',
],
// ─── Gruppi (per organizzare il pannello impostazioni) ─────────────────
'groups' => [
'Azienda' => ['company_name', 'support_email'],
'Visualizzazione' => ['currency', 'currency_symbol', 'date_format',
'items_per_page', 'theme_color', 'welcome_message'],
'Funzionalità' => ['allow_notes', 'max_file_size_mb'],
],
// ─── Cache ─────────────────────────────────────────────────────────────
// Durata cache (minuti). Le impostazioni vengono lette dal DB una volta
// e poi servite dalla cache per evitare query ad ogni richiesta.
'cache_ttl_minutes' => 60,
];