<?php
declare(strict_types=1);
namespace DoctrineMigrations;
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;
/**
* Migration para Sistema de Rate Limiting por IP
*
* Crea las tablas:
* - tipo_seccion: Catálogo de endpoints protegidos
* - rate_limit: Configuración de límites por endpoint
* - blacklist: Registro de IPs, intentos y bloqueos
*/
final class Version20251002095927 extends AbstractMigration
{
public function getDescription(): string
{
return 'Crea tablas para sistema de Rate Limiting por IP: tipo_seccion, rate_limit y blacklist';
}
public function up(Schema $schema): void
{
// Tabla tipo_seccion
$this->addSql('CREATE TABLE tipo_seccion (
id INT AUTO_INCREMENT NOT NULL,
endpoint VARCHAR(255) NOT NULL,
nombre VARCHAR(100) NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
deleted_at DATETIME DEFAULT NULL,
UNIQUE INDEX UNIQ_TIPO_SECCION_ENDPOINT (endpoint),
INDEX IDX_ENDPOINT (endpoint),
PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
// Tabla rate_limit
$this->addSql('CREATE TABLE rate_limit (
id INT AUTO_INCREMENT NOT NULL,
tipo_seccion_id INT NOT NULL,
intentos INT NOT NULL,
ventana INT NOT NULL,
bloqueos INT NOT NULL,
tiempo_bloqueo INT NOT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
UNIQUE INDEX UNIQ_RATE_LIMIT_TIPO_SECCION (tipo_seccion_id),
PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
// Tabla blacklist
$this->addSql('CREATE TABLE blacklist (
id INT AUTO_INCREMENT NOT NULL,
rate_limit_id INT NOT NULL,
ip VARCHAR(45) NOT NULL,
fecha_primer_intento DATETIME NOT NULL,
fecha_ultimo_intento DATETIME NOT NULL,
nro_intento INT NOT NULL DEFAULT 0,
contador_bloqueos INT NOT NULL DEFAULT 0,
estado VARCHAR(20) DEFAULT NULL,
fecha_bloqueo DATETIME DEFAULT NULL,
fecha_desbloqueo DATETIME DEFAULT NULL,
created_at DATETIME NOT NULL,
updated_at DATETIME NOT NULL,
INDEX IDX_IP_ESTADO (ip, estado),
INDEX IDX_FECHA_PRIMER_INTENTO (fecha_primer_intento),
INDEX IDX_RATE_LIMIT (rate_limit_id),
UNIQUE INDEX UNIQUE_IP_RATE_LIMIT (ip, rate_limit_id),
PRIMARY KEY(id)
) DEFAULT CHARACTER SET utf8mb4 COLLATE `utf8mb4_unicode_ci` ENGINE = InnoDB');
// Foreign Keys
$this->addSql('ALTER TABLE rate_limit
ADD CONSTRAINT FK_RATE_LIMIT_TIPO_SECCION
FOREIGN KEY (tipo_seccion_id)
REFERENCES tipo_seccion (id)
ON DELETE CASCADE');
$this->addSql('ALTER TABLE blacklist
ADD CONSTRAINT FK_BLACKLIST_RATE_LIMIT
FOREIGN KEY (rate_limit_id)
REFERENCES rate_limit (id)
ON DELETE CASCADE');
}
public function down(Schema $schema): void
{
// Eliminar tablas en orden inverso (primero las dependientes)
$this->addSql('ALTER TABLE blacklist DROP FOREIGN KEY FK_BLACKLIST_RATE_LIMIT');
$this->addSql('ALTER TABLE rate_limit DROP FOREIGN KEY FK_RATE_LIMIT_TIPO_SECCION');
$this->addSql('DROP TABLE blacklist');
$this->addSql('DROP TABLE rate_limit');
$this->addSql('DROP TABLE tipo_seccion');
}
}