id(); $table->foreignId('source_id')->constrained()->cascadeOnDelete(); $table->jsonb('data'); // champs variables selon source_type $table->foreignId('created_by')->constrained('users')->restrictOnDelete(); $table->foreignId('updated_by')->constrained('users')->restrictOnDelete(); $table->timestamps(); }); // Colonnes générées stockées pour les champs les plus filtrés DB::statement("ALTER TABLE releves ADD COLUMN nom TEXT GENERATED ALWAYS AS (data->>'nom') STORED"); DB::statement("ALTER TABLE releves ADD COLUMN prenom TEXT GENERATED ALWAYS AS (data->>'prenom') STORED"); DB::statement("ALTER TABLE releves ADD COLUMN date_evenement TEXT GENERATED ALWAYS AS (data->'date_evenement'->>'valeur') STORED"); // Index pour les colonnes générées DB::statement('CREATE INDEX releves_nom_idx ON releves (nom)'); DB::statement('CREATE INDEX releves_prenom_idx ON releves (prenom)'); DB::statement('CREATE INDEX releves_date_evenement_idx ON releves (date_evenement)'); // Index GIN pour la recherche fulltext sur l'ensemble du JSONB DB::statement('CREATE INDEX releves_data_gin_idx ON releves USING gin (data)'); } public function down(): void { Schema::dropIfExists('releves'); } };