feat(admin/usuarios): agregar usuario globalmente desde admin
El admin global ahora puede crear usuarios directamente desde /admin/usuarios sin depender de que un owner los invite. Backend: - Nuevo endpoint POST /usuarios/global (controller + service) - Valida límite de usuarios del plan del tenant destino - Si el email ya existe, agrega membership al tenant destino - Si no existe, crea user con temp password + membership - Schema Zod: email, nombre, role, tenantId, supervisorUserId? Frontend: - Botón 'Agregar Usuario' en /admin/usuarios - Formulario con: nombre, email, rol, empresa - Hook useCreateUsuarioGlobal con invalidación de queries
This commit is contained in:
@@ -26,6 +26,14 @@ const updateGlobalSchema = z.object({
|
||||
tenantId: z.string().uuid().optional(),
|
||||
});
|
||||
|
||||
const createGlobalSchema = z.object({
|
||||
email: z.string().email('email inválido'),
|
||||
nombre: z.string().min(2).max(100),
|
||||
role: z.enum(['contador', 'visor', 'auxiliar', 'supervisor', 'cliente']),
|
||||
tenantId: z.string().uuid('tenantId inválido'),
|
||||
supervisorUserId: z.string().uuid().optional(),
|
||||
});
|
||||
|
||||
async function isGlobalAdmin(req: Request): Promise<boolean> {
|
||||
return checkGlobalAdmin(req.user!.tenantId, req.user!.role, req.user!.userId);
|
||||
}
|
||||
@@ -190,6 +198,35 @@ export async function deleteUsuario(req: Request, res: Response, next: NextFunct
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Crea un usuario globalmente (solo admin global)
|
||||
*/
|
||||
export async function createUsuarioGlobal(req: Request, res: Response, next: NextFunction) {
|
||||
try {
|
||||
if (!(await isGlobalAdmin(req))) {
|
||||
throw new AppError(403, 'Solo el administrador global puede crear usuarios');
|
||||
}
|
||||
|
||||
const data = createGlobalSchema.parse(req.body);
|
||||
|
||||
if (data.role === 'auxiliar' && !data.supervisorUserId) {
|
||||
throw new AppError(400, 'Debes asignar un supervisor al auxiliar');
|
||||
}
|
||||
|
||||
const usuario = await usuariosService.createUsuarioGlobal(data.tenantId, {
|
||||
email: data.email,
|
||||
nombre: data.nombre,
|
||||
role: data.role,
|
||||
supervisorUserId: data.supervisorUserId,
|
||||
});
|
||||
|
||||
res.status(201).json(usuario);
|
||||
} catch (error) {
|
||||
if (error instanceof z.ZodError) return next(new AppError(400, error.errors[0].message));
|
||||
next(error);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actualiza un usuario globalmente (puede cambiar de empresa)
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user