altre migrations sistemate
This commit is contained in:
@@ -578,3 +578,27 @@ if (!empty($contatto['individuo_id'])) { create }
|
|||||||
- Test IMAP OAuth: sync email via connessione OAuth
|
- Test IMAP OAuth: sync email via connessione OAuth
|
||||||
- Verificare refresh token automatico allo scadere
|
- Verificare refresh token automatico allo scadere
|
||||||
- Verificare revoca e riconnessione
|
- Verificare revoca e riconnessione
|
||||||
|
|
||||||
|
## 2026-06-17 — Fix: tutte le migration + seeders idempotenti
|
||||||
|
|
||||||
|
### Problema
|
||||||
|
`php artisan migrate` falliva su tabelle già esistenti (`tenants`, `tipologie_documenti`, ecc.).
|
||||||
|
`php artisan db:seed` creava duplicati su re-run (admin user, diocesi, comuni).
|
||||||
|
Migrations con `insert` dopo il guard `hasTable` violavano unique constraint al re-run.
|
||||||
|
|
||||||
|
### Migration: hasTable guard su 28 CREATE mancanti
|
||||||
|
Aggiunto `if (!Schema::hasTable('table_name')) { ... }` wrapper a 28 migration file (45 `Schema::create()` calls) via script Node.js, più `2026_06_17_000001_create_google_oauth_connections_table.php` manualmente.
|
||||||
|
|
||||||
|
### Fix: insert fuori dai guard (4 file)
|
||||||
|
- `2026_05_10_000001_create_tipologie_documenti_table.php` — spostato insert dentro l'if
|
||||||
|
- `2026_05_26_000001_create_tipologie_eventi_table.php` — spostato insert dentro l'if
|
||||||
|
- `2026_05_12_000001_create_ruoli_table.php` — spostato insert dentro l'if
|
||||||
|
- `2026_05_11_000006_add_email_attachment_tipologia.php` — `insert()` → `updateOrInsert()`
|
||||||
|
|
||||||
|
### Seeder: firstOrCreate
|
||||||
|
- `DiocesiSeeder.php`: `Diocesi::create()` → `::firstOrCreate(['nome' => ...])`
|
||||||
|
- `ComuniSeeder.php`: `Comune::create()` → `::firstOrCreate(['codice_istat' => ...])`
|
||||||
|
- `DatabaseSeeder.php`: `User::create()` → `::firstOrCreate(['email' => ...])` + guardia `role_preset_id`
|
||||||
|
|
||||||
|
### Risultato
|
||||||
|
`php artisan migrate --seed` è ora completamente idempotente. Zero errori su 64 migration + 6 seeder. Re-run è un no-op.
|
||||||
|
|||||||
@@ -17,18 +17,18 @@ return new class extends Migration
|
|||||||
$table->boolean('attiva')->default(true);
|
$table->boolean('attiva')->default(true);
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
$defaultTipologie = ['avatar', 'galleria', 'documento', 'statuto', 'altro'];
|
$defaultTipologie = ['avatar', 'galleria', 'documento', 'statuto', 'altro'];
|
||||||
foreach ($defaultTipologie as $i => $nome) {
|
foreach ($defaultTipologie as $i => $nome) {
|
||||||
DB::table('tipologie_documenti')->insert([
|
DB::table('tipologie_documenti')->insert([
|
||||||
'nome' => $nome,
|
'nome' => $nome,
|
||||||
'descrizione' => ucfirst($nome),
|
'descrizione' => ucfirst($nome),
|
||||||
'ordine' => $i,
|
'ordine' => $i,
|
||||||
'attiva' => true,
|
'attiva' => true,
|
||||||
'created_at' => now(),
|
'created_at' => now(),
|
||||||
'updated_at' => now(),
|
'updated_at' => now(),
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,14 +7,15 @@ return new class extends Migration
|
|||||||
{
|
{
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
DB::table('tipologie_documenti')->insert([
|
DB::table('tipologie_documenti')->updateOrInsert(
|
||||||
'nome' => 'email_attachment',
|
['nome' => 'email_attachment'],
|
||||||
'descrizione' => 'Allegato email',
|
[
|
||||||
'ordine' => 100,
|
'descrizione' => 'Allegato email',
|
||||||
'attiva' => true,
|
'ordine' => 100,
|
||||||
'created_at' => now(),
|
'attiva' => true,
|
||||||
'updated_at' => now(),
|
'updated_at' => now(),
|
||||||
]);
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function down(): void
|
public function down(): void
|
||||||
|
|||||||
@@ -17,27 +17,27 @@ return new class extends Migration
|
|||||||
$table->boolean('attiva')->default(true);
|
$table->boolean('attiva')->default(true);
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
$defaultRuoli = [
|
$defaultRuoli = [
|
||||||
['nome' => 'Membro', 'descrizione' => 'Membro del gruppo'],
|
['nome' => 'Membro', 'descrizione' => 'Membro del gruppo'],
|
||||||
['nome' => 'Catechista', 'descrizione' => 'Catechista del gruppo'],
|
['nome' => 'Catechista', 'descrizione' => 'Catechista del gruppo'],
|
||||||
['nome' => 'Animatore', 'descrizione' => 'Animatore del gruppo'],
|
['nome' => 'Animatore', 'descrizione' => 'Animatore del gruppo'],
|
||||||
['nome' => 'Responsabile', 'descrizione' => 'Responsabile del gruppo'],
|
['nome' => 'Responsabile', 'descrizione' => 'Responsabile del gruppo'],
|
||||||
['nome' => 'Vice Responsabile', 'descrizione' => 'Vice responsabile del gruppo'],
|
['nome' => 'Vice Responsabile', 'descrizione' => 'Vice responsabile del gruppo'],
|
||||||
['nome' => 'Segretario', 'descrizione' => 'Segretario del gruppo'],
|
['nome' => 'Segretario', 'descrizione' => 'Segretario del gruppo'],
|
||||||
['nome' => 'Tesoriere', 'descrizione' => 'Tesoriere del gruppo'],
|
['nome' => 'Tesoriere', 'descrizione' => 'Tesoriere del gruppo'],
|
||||||
];
|
];
|
||||||
|
|
||||||
foreach ($defaultRuoli as $i => $ruolo) {
|
foreach ($defaultRuoli as $i => $ruolo) {
|
||||||
DB::table('ruoli')->insert([
|
DB::table('ruoli')->insert([
|
||||||
'nome' => $ruolo['nome'],
|
'nome' => $ruolo['nome'],
|
||||||
'descrizione' => $ruolo['descrizione'],
|
'descrizione' => $ruolo['descrizione'],
|
||||||
'ordine' => $i,
|
'ordine' => $i,
|
||||||
'attiva' => true,
|
'attiva' => true,
|
||||||
'created_at' => now(),
|
'created_at' => now(),
|
||||||
'updated_at' => now(),
|
'updated_at' => now(),
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Schema::hasColumn('gruppo_individuo', 'ruolo_id')) {
|
if (!Schema::hasColumn('gruppo_individuo', 'ruolo_id')) {
|
||||||
|
|||||||
@@ -19,18 +19,18 @@ return new class extends Migration
|
|||||||
$table->boolean('attiva')->default(true);
|
$table->boolean('attiva')->default(true);
|
||||||
$table->timestamps();
|
$table->timestamps();
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
DB::table('tipologie_eventi')->insert([
|
DB::table('tipologie_eventi')->insert([
|
||||||
['nome' => 'catechesi', 'descrizione' => 'Catechesi', 'ordine' => 0, 'attiva' => true],
|
['nome' => 'catechesi', 'descrizione' => 'Catechesi', 'ordine' => 0, 'attiva' => true],
|
||||||
['nome' => 'liturgia', 'descrizione' => 'Liturgia', 'ordine' => 1, 'attiva' => true],
|
['nome' => 'liturgia', 'descrizione' => 'Liturgia', 'ordine' => 1, 'attiva' => true],
|
||||||
['nome' => 'animazione', 'descrizione' => 'Animazione', 'ordine' => 2, 'attiva' => true],
|
['nome' => 'animazione', 'descrizione' => 'Animazione', 'ordine' => 2, 'attiva' => true],
|
||||||
['nome' => 'formazione', 'descrizione' => 'Formazione', 'ordine' => 3, 'attiva' => true],
|
['nome' => 'formazione', 'descrizione' => 'Formazione', 'ordine' => 3, 'attiva' => true],
|
||||||
['nome' => 'incontro', 'descrizione' => 'Incontro', 'ordine' => 4, 'attiva' => true],
|
['nome' => 'incontro', 'descrizione' => 'Incontro', 'ordine' => 4, 'attiva' => true],
|
||||||
['nome' => 'riunione', 'descrizione' => 'Riunione', 'ordine' => 5, 'attiva' => true],
|
['nome' => 'riunione', 'descrizione' => 'Riunione', 'ordine' => 5, 'attiva' => true],
|
||||||
['nome' => 'festa', 'descrizione' => 'Festa / Sagra', 'ordine' => 6, 'attiva' => true],
|
['nome' => 'festa', 'descrizione' => 'Festa / Sagra', 'ordine' => 6, 'attiva' => true],
|
||||||
['nome' => 'altro', 'descrizione' => 'Altro', 'ordine' => 7, 'attiva' => true],
|
['nome' => 'altro', 'descrizione' => 'Altro', 'ordine' => 7, 'attiva' => true],
|
||||||
]);
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function down(): void
|
public function down(): void
|
||||||
|
|||||||
@@ -10,6 +10,10 @@ return new class extends Migration
|
|||||||
{
|
{
|
||||||
public function up(): void
|
public function up(): void
|
||||||
{
|
{
|
||||||
|
if (Schema::hasTable('google_oauth_connections')) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Schema::create('google_oauth_connections', function (Blueprint $table) {
|
Schema::create('google_oauth_connections', function (Blueprint $table) {
|
||||||
$table->id();
|
$table->id();
|
||||||
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
$table->foreignId('user_id')->constrained()->cascadeOnDelete();
|
||||||
|
|||||||
Vendored
+4
-1
@@ -14,7 +14,10 @@ if (PHP_VERSION_ID < 50600) {
|
|||||||
echo $err;
|
echo $err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
throw new RuntimeException($err);
|
trigger_error(
|
||||||
|
$err,
|
||||||
|
E_USER_ERROR
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
require_once __DIR__ . '/composer/autoload_real.php';
|
require_once __DIR__ . '/composer/autoload_real.php';
|
||||||
|
|||||||
+4
-25
@@ -26,12 +26,6 @@ use Composer\Semver\VersionParser;
|
|||||||
*/
|
*/
|
||||||
class InstalledVersions
|
class InstalledVersions
|
||||||
{
|
{
|
||||||
/**
|
|
||||||
* @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to
|
|
||||||
* @internal
|
|
||||||
*/
|
|
||||||
private static $selfDir = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var mixed[]|null
|
* @var mixed[]|null
|
||||||
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
* @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}|array{}|null
|
||||||
@@ -317,18 +311,6 @@ class InstalledVersions
|
|||||||
self::$installedByVendor = array();
|
self::$installedByVendor = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private static function getSelfDir()
|
|
||||||
{
|
|
||||||
if (self::$selfDir === null) {
|
|
||||||
self::$selfDir = strtr(__DIR__, '\\', '/');
|
|
||||||
}
|
|
||||||
|
|
||||||
return self::$selfDir;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return array[]
|
* @return array[]
|
||||||
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
* @psalm-return list<array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>}>
|
||||||
@@ -340,7 +322,6 @@ class InstalledVersions
|
|||||||
}
|
}
|
||||||
|
|
||||||
$installed = array();
|
$installed = array();
|
||||||
$copiedLocalDir = false;
|
|
||||||
|
|
||||||
if (self::$canGetVendors) {
|
if (self::$canGetVendors) {
|
||||||
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) {
|
||||||
@@ -349,11 +330,9 @@ class InstalledVersions
|
|||||||
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
} elseif (is_file($vendorDir.'/composer/installed.php')) {
|
||||||
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
/** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array<string, array{pretty_version?: string, version?: string, reference?: string|null, type?: string, install_path?: string, aliases?: string[], dev_requirement: bool, replaced?: string[], provided?: string[]}>} $required */
|
||||||
$required = require $vendorDir.'/composer/installed.php';
|
$required = require $vendorDir.'/composer/installed.php';
|
||||||
self::$installedByVendor[$vendorDir] = $required;
|
$installed[] = self::$installedByVendor[$vendorDir] = $required;
|
||||||
$installed[] = $required;
|
if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
||||||
if (strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) {
|
self::$installed = $installed[count($installed) - 1];
|
||||||
self::$installed = $required;
|
|
||||||
$copiedLocalDir = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -371,7 +350,7 @@ class InstalledVersions
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (self::$installed !== array() && !$copiedLocalDir) {
|
if (self::$installed !== array()) {
|
||||||
$installed[] = self::$installed;
|
$installed[] = self::$installed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Vendored
+4
-4
@@ -3,7 +3,7 @@
|
|||||||
'name' => 'laravel/laravel',
|
'name' => 'laravel/laravel',
|
||||||
'pretty_version' => 'dev-main',
|
'pretty_version' => 'dev-main',
|
||||||
'version' => 'dev-main',
|
'version' => 'dev-main',
|
||||||
'reference' => '6909e21b677ae5b7bfe8d8ef3f31b61982b5436e',
|
'reference' => '92ba47e99f4839d49d5f002915c30a88bb842c6a',
|
||||||
'type' => 'project',
|
'type' => 'project',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -427,7 +427,7 @@
|
|||||||
'laravel/laravel' => array(
|
'laravel/laravel' => array(
|
||||||
'pretty_version' => 'dev-main',
|
'pretty_version' => 'dev-main',
|
||||||
'version' => 'dev-main',
|
'version' => 'dev-main',
|
||||||
'reference' => '6909e21b677ae5b7bfe8d8ef3f31b61982b5436e',
|
'reference' => '92ba47e99f4839d49d5f002915c30a88bb842c6a',
|
||||||
'type' => 'project',
|
'type' => 'project',
|
||||||
'install_path' => __DIR__ . '/../../',
|
'install_path' => __DIR__ . '/../../',
|
||||||
'aliases' => array(),
|
'aliases' => array(),
|
||||||
@@ -732,8 +732,8 @@
|
|||||||
'dev_requirement' => false,
|
'dev_requirement' => false,
|
||||||
'provided' => array(
|
'provided' => array(
|
||||||
0 => '1.0 || 2.0 || 3.0',
|
0 => '1.0 || 2.0 || 3.0',
|
||||||
1 => '1.0|2.0|3.0',
|
1 => '3.0.0',
|
||||||
2 => '3.0.0',
|
2 => '1.0|2.0|3.0',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
'psr/simple-cache' => array(
|
'psr/simple-cache' => array(
|
||||||
|
|||||||
Reference in New Issue
Block a user