<?php

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

/**
 * Marcar una petición como vista.
 *
 * **Para qué.** Un error del visor no siempre es algo que haya que arreglar aquí: un
 * `2002` puede estar esperando a que el cliente termine el alta, y un `5xx` puede ser un
 * incidente ya cerrado. Sin forma de decir «esto ya lo he mirado», la lista de errores no
 * se puede ir vaciando, y una lista que no se vacía se deja de mirar —el mismo
 * razonamiento de `norma-cero-errores.md`—.
 *
 * **Se marca la petición y no el tipo de error.** Es una decisión de producto tomada
 * expresamente: lo que se registra es «he mirado esta fila». Tiene una consecuencia que
 * conviene tener presente y no está escondida en el código: **un error que se repite cada
 * hora genera filas nuevas sin marcar**, así que marcar no reduce el problema de mañana.
 * Para eso haría falta marcar la clase de error —sitio + acción + plugin + código—, que
 * está descartado por ahora.
 *
 * **Dos avisos sobre la tabla:**
 *
 * 1. `api_request_logs` es **la que más crece del sistema**. Las dos columnas van al final
 *    y son nulables, que en MariaDB es un `ALTER` casi instantáneo; con valor por defecto
 *    o en medio de la tabla sería una copia entera.
 * 2. **`reviewed_by` no lleva clave ajena a propósito.** Añadir una fuerza a MariaDB a
 *    copiar la tabla entera, que aquí es exactamente lo que hay que evitar. El precio es
 *    que si se borra un usuario queda su id sin resolver: la pantalla dice «usuario
 *    borrado», que es la verdad y no cuesta una ventana de mantenimiento.
 */
return new class extends Migration
{
    public function up(): void
    {
        if (Schema::hasColumn('api_request_logs', 'reviewed_at')) {
            return;
        }

        Schema::table('api_request_logs', function (Blueprint $table) {
            $table->timestamp('reviewed_at')->nullable();
            $table->unsignedBigInteger('reviewed_by')->nullable();

            // El filtro que justifica todo esto es «errores sin revisar», y va siempre
            // acotado por fecha. El índice compuesto sirve a esa consulta y no a otra:
            // sin él, marcar como visto no cambiaría nada del coste de la pantalla.
            $table->index(['severity', 'reviewed_at', 'started_at'], 'api_logs_revision_idx');
        });
    }

    public function down(): void
    {
        Schema::table('api_request_logs', function (Blueprint $table) {
            $table->dropIndex('api_logs_revision_idx');
            $table->dropColumn(['reviewed_at', 'reviewed_by']);
        });
    }
};
