Suche: Volltext-Index + Fix fuer doppelte Alpine-Instanz

Archiv-Suche lief auf grossen Datenbestaenden langsam und war im Browser
komplett tot: app.js startete ein eigenes Alpine, Livewire injizierte
zusaetzlich seins - der DOM-Morph brach mit "Alpine.transaction is not a
function" ab (keine Rubrik klickbar, Suchbegriff nicht aenderbar).

- app.js buendelt jetzt Livewire + Alpine aus livewire.esm,
  @livewireScriptConfig im Web-Layout stoppt die Auto-Injektion
- MySQL-Volltext-Index (Boolean-Mode, +wort*) statt LIKE ueber alles;
  LIKE-Fallback fuer SQLite-Tests und kurze Tokens
- Firmen-/Rubrik-Treffer als ID-Listen statt orWhereHas (OR + EXISTS
  hebelte den Volltext-Index aus)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Kevin Adametz 2026-07-07 13:03:14 +00:00
parent b3780e0fea
commit db65c2ed7d
6 changed files with 178 additions and 16 deletions

View file

@ -0,0 +1,44 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Schema;
/**
* Volltext-Index für die öffentliche Archiv-Suche (title, subtitle, text,
* keywords). Ergänzt den schmaleren Admin-Index (title, keywords) um die
* inhaltstragenden Spalten, damit die Suche nicht mehr über ein
* nicht-indexierbares LIKE '%…%' auf dem MediumText laufen muss.
* SQLite (Tests) unterstützt keine Fulltext-Indizes → dort No-Op,
* die Suche fällt zur Laufzeit auf LIKE zurück.
*/
return new class extends Migration
{
public function up(): void
{
if (! $this->supportsFullTextIndexes()) {
return;
}
Schema::table('press_releases', function (Blueprint $table): void {
$table->fullText(['title', 'subtitle', 'text', 'keywords'], 'press_releases_web_search_fulltext');
});
}
public function down(): void
{
if (! $this->supportsFullTextIndexes()) {
return;
}
Schema::table('press_releases', function (Blueprint $table): void {
$table->dropFullText('press_releases_web_search_fulltext');
});
}
private function supportsFullTextIndexes(): bool
{
return in_array(DB::connection()->getDriverName(), ['mysql', 'pgsql'], true);
}
};