-- =============================================================================
--  inv_solicitud — CANDADO ESTRUCTURAL contra la SOLICITUD duplicada por réplica
-- =============================================================================
--  Base de datos : asturias_api  (servidor PÚBLICO, CL032BACK)
--  Archivo       : database/sql/inv_solicitud_unique_replica.sql
--  Fecha         : 2026-08-17
--  Equivale a    : database/migrations/2026_08_17_120100_add_unique_replica_to_inv_solicitud.php
--
--  MOTIVO
--  ------
--  Es el hermano de inv_invitado_unique_replica.sql, un nivel más arriba, donde el daño
--  es peor: dos réplicas simultáneas de una solicitud que el Portal todavía no conoce
--  hacen que las dos entren por el camino de alta y creen DOS solicitudes, cada una con
--  su juego completo de invitados. El socio ve la misma estancia dos veces, y
--  localizarSolicitud() —que resuelve con ORDER BY idSolicitud LIMIT 1— se queda con la
--  primera para siempre: la segunda queda huérfana, ninguna réplica posterior la
--  actualiza ni la cancela, y no hay nada que la limpie.
--
--  ⚠️ ESTO REVIERTE UNA DECISIÓN DOCUMENTADA, a conciencia.
--  inv_solicitud_add_replica_tlalpan.sql dice: «Sin UNIQUE en el puntero […]: un payload
--  mal formado debe producir un rechazo controlado y bitacorado, no un 500 por violación
--  de índice». Ese razonamiento SIGUE VIGENTE para un payload mal formado: los punteros
--  cruzados, la membresía discrepante y la solicitud ajena se siguen rechazando con 422
--  y su motivo ANTES de escribir nada. Este índice no los toca.
--
--  Lo que aquel comentario no contemplaba es la CARRERA, que no es un payload malo sino
--  dos payloads buenos llegando a la vez. Ahí no existe el "rechazo controlado": sin
--  índice las dos escrituras tienen éxito y el duplicado queda asentado en silencio, que
--  es el único desenlace verdaderamente inaceptable. El 500 que produce el índice es el
--  desenlace BUENO — Tlalpan lo clasifica como transitorio, reintenta, encuentra la
--  solicitud ya creada y la actualiza.
--
--  Tlalpan tiene desde el principio el índice simétrico (uq_solicitud_portal UNIQUE
--  sobre idSolicitudPortal), que impide que una solicitud del socio se importe dos
--  veces. Esto es la otra mitad del mismo candado.
--
--  ⚠️ NULL NO ESTORBA: las solicitudes que el socio todavía no ha transferido tienen
--  idSolicitudTlalpan = NULL, y MySQL admite tantos NULL como quiera en un UNIQUE.
-- =============================================================================

-- -----------------------------------------------------------------------------
--  PASO 1 — VERIFICAR ANTES DE ALTERAR. Debe devolver 0 filas.
--  Si devuelve alguna, NO la resuelvas a ciegas: revisa cuál de las solicitudes tiene
--  reservación viva (rsv_reservacion.idSolicitud) antes de decidir cuál se retira.
-- -----------------------------------------------------------------------------
SELECT idSolicitudTlalpan, COUNT(*) AS n,
       GROUP_CONCAT(idSolicitud ORDER BY idSolicitud) AS filas
  FROM inv_solicitud
 WHERE idSolicitudTlalpan IS NOT NULL
 GROUP BY idSolicitudTlalpan
HAVING COUNT(*) > 1;

-- -----------------------------------------------------------------------------
--  PASO 2 — EL CANDADO
-- -----------------------------------------------------------------------------
ALTER TABLE `inv_solicitud`
  ADD UNIQUE KEY `uq_solicitud_tlalpan` (`idSolicitudTlalpan`);

-- -----------------------------------------------------------------------------
--  REVERSA
-- -----------------------------------------------------------------------------
-- ALTER TABLE `inv_solicitud` DROP INDEX `uq_solicitud_tlalpan`;
