# Identidad por email y rol Cada cuenta activa se identifica por `LOWER(email)` + `rol_codigo`, globalmente, sin incluir el tenant. Un mismo correo puede tener una cuenta `user`, otra `adminapp`, otra `scanner` y otra `admin`. Dos cuentas activas del mismo rol no pueden compartir correo, incluso si pertenecen a distintos tenants. La base lo garantiza con el índice único `(active_email, rol_codigo)`. `active_email` es una columna generada: vale `LOWER(email)` cuando `deleted_at` es NULL y NULL para cuentas eliminadas. El soft delete libera el correo para ese rol; registrarlo nuevamente crea una cuenta independiente. Registro, perfil, administradores y staff validan el correo normalizado contra el rol de destino. Cambiar de rol o restaurar una cuenta también queda sujeto al índice único de la base. Login y recuperación seleccionan la identidad de la aplicación: - Tienda y Google: `user`. - AdminApp: `adminapp`. - Scanner: `scanner`. Sólo las identidades con ese rol pueden autenticarse y consumir los endpoints del scanner. - Verificación administrativa de plataforma: `admin`. Los endpoints de validación de código y cambio de contraseña toman el rol de la ruta, nunca del cuerpo enviado por el cliente. Los intentos y cambios de contraseña pertenecen a una cuenta concreta, aunque otra comparta su email. Aplicar `php artisan migrate` antes de habilitar correos compartidos por rol. Para revertir esta migración hay que resolver primero los correos compartidos entre cuentas activas: el índice global anterior no los admite.