<?php

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

/**
 * A register of what this installation has sent, and to whom.
 *
 * Until now the only record of a mail was that some model somewhere had a
 * `sent_at` on it, one per feature and only for the features that thought to
 * keep one. So "did the customer ever get their credentials?" was answered by
 * looking in the mail server's log — a different machine, a different program,
 * and nothing an operator can put in front of a customer who says they never
 * received anything.
 *
 * Deliberately NOT the message body in full detail: this is a delivery
 * register, not a copy of the mailbox. Subject, recipient, when, and which
 * mailable — enough to answer "what went out and when", not enough to turn a
 * database backup into a leak of everything anybody was ever told.
 *
 * The exception is `body`, which is filled only where the operator wrote the
 * message themselves in the console: they typed it, they should be able to read
 * back what they sent.
 */
return new class extends Migration
{
    public function up(): void
    {
        Schema::create('sent_mails', function (Blueprint $table) {
            $table->id();
            $table->uuid()->unique();

            // Nullable, because not every mail has a customer behind it: a
            // password reset can be triggered for an address that never bought
            // anything, and an operator invitation is not a customer at all.
            $table->foreignId('customer_id')->nullable()->constrained()->nullOnDelete();

            $table->string('to');
            $table->string('subject');
            // The mailable class, so a filter can say "every invoice mail"
            // without matching on a subject line that changes with the wording.
            $table->string('mailable')->nullable();
            // Written by a person in the console rather than by the system.
            $table->boolean('from_operator')->default(false);
            $table->text('body')->nullable();

            // Recorded on MessageSent — i.e. the transport accepted it. That is
            // the strongest thing an application can honestly claim; what the
            // receiving server did with it afterwards is not ours to know.
            $table->timestamp('sent_at');
            $table->timestamps();

            $table->index(['customer_id', 'sent_at']);
            $table->index('sent_at');
        });
    }

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