Alta de usuario → activación por email
Objetivo
Que un usuario recién creado pueda fijar su propia contraseña sin que nadie (ni el staff que lo dio de alta) llegue a conocer una temporal.
Cómo empieza
Dos entradas posibles, mismo final:
- Staff crea un usuario desde
petid-crm→POST /users(rol clínica) o/superadmin/tenants(alta de tenant+admin). - Owner hace
POST /auth/register(self-signup, si aplica).
Pasos principales
RegisterUseCase/ProvisionTenantUseCasegeneran una password congenerateTempPassword()— se hashea y se guarda, pero nunca se devuelve en ninguna respuesta ni se muestra en ningún panel. Solo existe para no dejar el hash vacío.- Se emite
UserRegisteredEvent→SendEmailVerificationUseCase→EmailVerificationRequestedEvent→ email con codewelcome,verifyUrl: {baseUrl}/activate?token=.... baseUrlFor(role)decide el dominio:Role.USER(dueño de mascota) →petid-landing; cualquier rol de staff →petid-crm. Cada app tiene su propia ruta/activate.- El usuario abre el link → formulario web →
POST /auth/activate { token, password }. ActivateAccountUseCasereutiliza el mismo JWT de verificación de email como prueba de activación (no genera un token nuevo), fija la contraseña real y marcaemailVerifiedAten el mismo paso.
Reglas de negocio
- El token de activación se invalida solo: la verificación firma el JWT incluyendo el estado actual de
emailVerifiedAt("unverified"o el ISO string), así que una vez usado, el estado cambia y el mismo token ya no vuelve a validar. - No existe “admin resetea contraseña de un usuario existente” —
UpdateUserUseCaseno tocapassword. La única vía de fijar/cambiar contraseña de otro es este flujo de alta o el propioforgot-password.
Interacciones
petid-api → notification-api (email welcome) → el usuario abre petid-landing o petid-crm → POST /auth/activate de vuelta a petid-api.
Dónde seguir mirando
petid-api/src/application/auth/register.use-case.ts,activate-account.use-case.ts,send-email-verification.use-case.tspetid-api/src/infrastructure/email/email-service-sender.ts(sendEmailVerification,baseUrlFor)petid-landing/src/pages/api/activate.ts(relay server-side al backend)
Casos especiales
mustChangePasswordya no existe (eliminado 2026-09-02 depetid-client/petid-api). Existió como mecanismo “forzar cambio de contraseña en el primer login móvil”, pero nunca tenía disparador real: para cuando el usuario abre la app, ya activó por email. Si ves referencias sueltas a esto en commits viejos, es historia muerta — no lo reintroduzcas.- El link de “verificación” de email y el de “activación” de cuenta son el mismo link — no hay una pantalla separada de “solo confirmar email”.