<?php
 use Illuminate\Database\Migrations\Migration; use Illuminate\Database\Schema\Blueprint; use Illuminate\Support\Facades\Schema; return new class extends Migration { public function up(): void { Schema::create('email_campaign_recipients', function (Blueprint $t) { $t->id(); $t->unsignedBigInteger('campaign_id'); $t->unsignedBigInteger('subscriber_id')->nullable(); $t->string('email_snapshot', 255); $t->string('name_snapshot', 255)->nullable(); $t->enum('status', ['queued','sent','failed','bounced'])->default('queued'); $t->char('recipient_token', 32); $t->timestamp('sent_at')->nullable(); $t->timestamp('opened_at')->nullable(); $t->unsignedInteger('opened_count')->default(0); $t->timestamp('clicked_at')->nullable(); $t->unsignedInteger('click_count')->default(0); $t->timestamp('unsubscribed_at')->nullable(); $t->text('last_error')->nullable(); $t->unsignedTinyInteger('retry_count')->default(0); $t->timestamp('created_at')->nullable(); $t->timestamp('updated_at')->nullable(); $t->index('subscriber_id', 'email_campaign_recipients_subscriber_id_foreign'); $t->index(['campaign_id', 'status'], 'eml_camp_recip_status_idx'); $t->unique('recipient_token', 'eml_camp_recip_token_uq'); $t->foreign('campaign_id', 'email_campaign_recipients_campaign_id_foreign')->references('id')->on('email_campaigns')->onDelete('cascade'); $t->foreign('subscriber_id', 'email_campaign_recipients_subscriber_id_foreign')->references('id')->on('email_marketing_subscribers')->onDelete('set null'); }); } public function down(): void { Schema::dropIfExists('email_campaign_recipients'); } }; 