Craft Commerce hasStock not working?
Your product element criteria is using a condition param: hasVariants, but it should be hasVariant as per the docs: https://craftcommerce.com/docs/craft-commerce-products#hasvariant

That correctly only returns products (where a variant that belongs to that product) is in stock.