23-01-2026

This commit is contained in:
Kevin Adametz 2026-01-23 17:34:40 +01:00
parent 8fd1f4d451
commit 389d5d1820
59 changed files with 9642 additions and 883 deletions

View file

@ -0,0 +1,86 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateNewsletterContactsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('newsletter_contacts', function (Blueprint $table) {
$table->id();
// Kontaktdaten
$table->string('email')->index();
$table->string('firstname')->nullable();
$table->string('lastname')->nullable();
// Newsletter-Gruppen (kann mehrere sein)
$table->boolean('group_kulturreisen')->default(false)->index();
$table->boolean('group_ferienwohnungen')->default(false)->index();
// Status & Herkunft
$table->enum('source', [
'booking_kulturreisen',
'booking_ferienwohnungen',
'newsletter_signup',
'manual',
'import'
])->index();
$table->enum('status', [
'active',
'inactive',
'unsubscribed',
'bounced'
])->default('active')->index();
// Tracking-Informationen
$table->timestamp('subscribed_at')->nullable();
$table->timestamp('unsubscribed_at')->nullable();
$table->timestamp('last_booking_at')->nullable();
// Statistiken
$table->integer('total_bookings_kulturreisen')->default(0);
$table->integer('total_bookings_ferienwohnungen')->default(0);
// Referenzen zu Originaldaten
$table->integer('customer_id')->nullable()->index()->comment('Referenz zu customer Tabelle für Kulturreisen');
$table->integer('travel_user_id')->nullable()->index()->comment('Referenz zu travel_users Tabelle für Ferienwohnungen');
// Sync-Informationen
$table->timestamp('last_synced_at')->nullable();
$table->string('sync_hash')->nullable()->comment('Hash für Duplikat-Erkennung');
// Notizen & Zusatzinformationen
$table->text('notes')->nullable();
$table->timestamps();
$table->softDeletes();
// Unique Index auf E-Mail (nur für nicht gelöschte Einträge)
$table->unique(['email', 'deleted_at'], 'newsletter_email_unique');
// Composite Index für häufige Abfragen mit kürzeren Namen
$table->index(['status', 'group_kulturreisen', 'group_ferienwohnungen'], 'newsletter_status_groups_idx');
$table->index(['source', 'status'], 'newsletter_source_status_idx');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('newsletter_contacts');
}
}

View file

@ -0,0 +1,51 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateNewsletterLogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('newsletter_logs', function (Blueprint $table) {
$table->id();
$table->foreignId('newsletter_contact_id')->constrained()->onDelete('cascade');
$table->enum('action', [
'subscribed',
'unsubscribed',
'booking_added',
'status_changed',
'group_changed',
'email_sent',
'bounced'
]);
$table->string('description')->nullable();
$table->json('metadata')->nullable();
$table->integer('user_id')->nullable()->comment('Admin-User der die Aktion ausgeführt hat');
$table->timestamps();
$table->index(['newsletter_contact_id', 'created_at']);
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('newsletter_logs');
}
}

View file

@ -0,0 +1,32 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddLastTravelEndDateToNewsletterContactsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('newsletter_contacts', function (Blueprint $table) {
$table->dateTime('last_travel_end_date')->nullable()->after('last_booking_at');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('newsletter_contacts', function (Blueprint $table) {
$table->dropColumn('last_travel_end_date');
});
}
}