Elegir un solo BSUID por teléfono antes de escribir

57 números aparecen con dos identificadores (línea reciclada, o la persona
se registró de nuevo). El recorrido iba por BSUID, así que en esos casos los
dos escribían sobre el mismo usuario y el que quedaba dependía del orden:
cada ejecución dejaba un valor distinto y ninguna era más correcta. De ahí
los "110 reemplazos", que no eran 110 personas sino 57 escribiéndose dos
veces.

Ahora el empate se resuelve en memoria antes de tocar la base —gana el visto
más tarde, que es el vigente— y se escribe una sola vez por teléfono. La
corrida siguiente da 0 cambios y 0 conflictos, que es como debe comportarse
algo idempotente.

Estado final: 5.607 usuarios con su BSUID, sin duplicados, y ningún registro
con el identificador guardado en el campo de teléfono.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Lizandro Guarnizo
2026-08-11 21:54:21 -05:00
co-authored by Claude Opus 5
parent ffb8c3c934
commit cd087f65af
+15 -9
View File
@@ -122,14 +122,21 @@ exit(0);
printf(" equivalencias encontradas: %d\n", count($mapa));
printf(" personas que llegaron sin teléfono: %d\n", count($sinTelefono));
// --- 1b. ¿Hay teléfonos con más de un BSUID? ---
// Importa saberlo antes de escribir: si un mismo número aparece con dos
// identificadores es porque cambió de dueño, o porque la persona volvió a
// registrarse. Se queda el último visto, pero conviene que quede dicho.
// --- 1b. Un solo BSUID por teléfono ---
// Hay números que aparecen con dos identificadores: la línea cambió de dueño
// (reciclada) o la persona se registró de nuevo. Si se recorre el mapa tal cual,
// ambos escriben sobre el mismo usuario y el que queda depende del orden: cada
// ejecución dejaba un valor distinto. Se resuelve antes de tocar la base,
// quedándose con el visto más tarde, y se escribe una sola vez por teléfono.
$porTelefono = [];
foreach ($mapa as $b => $t) $porTelefono[$t][] = $b;
$elegido = [];
foreach ($mapa as $b => $t) {
$porTelefono[$t][] = $b;
$elegido[$t] = $b; // el orden del mapa es el de lectura: el último gana
}
$ambiguos = array_filter($porTelefono, fn($bs) => count($bs) > 1);
printf(" teléfonos con más de un BSUID: %d\n\n", count($ambiguos));
printf(" teléfonos distintos: %d\n", count($porTelefono));
printf(" teléfonos con más de un BSUID: %d (se toma el más reciente)\n\n", count($ambiguos));
foreach (array_slice($ambiguos, 0, 10, true) as $t => $bs) {
printf(" %s → %s\n", substr($t, 0, -4) . '****', implode(', ', $bs));
}
@@ -141,13 +148,12 @@ $db = Database::getInstance();
$marcados = 0; $noExisten = 0; $yaEstaban = 0; $conflictos = 0;
foreach ($mapa as $bsuid => $telefono) {
foreach ($elegido as $telefono => $bsuid) {
$u = $db->fetch("SELECT id, bsuid FROM users WHERE phone_number = :t", ['t' => $telefono]);
if (!$u) { $noExisten++; continue; }
if ($u['bsuid'] === $bsuid) { $yaEstaban++; continue; }
if (!empty($u['bsuid'])) {
// El BSUID se regenera si la persona cambia de número: gana el más reciente
printf(" aviso: %s tenía %s y ahora %s\n", $telefono, $u['bsuid'], $bsuid);
printf(" aviso: %s tenía %s y queda con %s\n", $telefono, $u['bsuid'], $bsuid);
$conflictos++;
}
if (!$simular) {