<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

/**
 * Billing events that arrived before the contract they are about.
 *
 * Stripe does not guarantee delivery order, and a checkout takes a moment to
 * become a contract on our side. In that window an `invoice.paid` or a
 * `customer.subscription.deleted` can land for a subscription we cannot match
 * yet — and answering 2xx would drop it for good, because Stripe has no reason
 * to send it again. A cancellation lost that way means we keep serving someone
 * who has left.
 *
 * So an unmatched event is kept, and replayed the moment the contract appears.
 * Most rows here will never be replayed: Stripe also delivers events for
 * subscriptions belonging to other environments pointed at this endpoint, and
 * for objects made by hand in the dashboard. Those are pruned by age.
 */
return new class extends Migration
{
    public function up(): void
    {
        Schema::create('stripe_pending_events', function (Blueprint $table) {
            $table->id();
            // Stripe's event id, so a retried delivery does not queue it twice.
            $table->string('stripe_event_id')->unique();
            $table->string('stripe_subscription_id')->index();
            $table->string('type');
            $table->timestamp('raised_at')->nullable();
            $table->json('payload');
            $table->timestamps();
        });
    }

    public function down(): void
    {
        Schema::dropIfExists('stripe_pending_events');
    }
};
