Yea, it can be tricky. My rule of thumb is in general anything that you see in the game should have a blueprint. If you want to implement it in C++, then make it a blueprint that inherits from a custom C++ class. If it’s not actually visible in the game, you kind of have to guess. If the class leans heavily on engine functionality over your own implementation, I’d probably make a blueprint for it though.
On our project we tend to do a lot of Blueprint inheriting from a C++ base class to keep as much functionality as possible in C++. That’s mostly just for consistency. I think if I were starting fresh I’d probably try 100% blueprints and only do C++ implementation when there were either performance or functionality reasons to. It’s always easy to convert blueprint to C++ later because they’re almost 1:1 as far as general flow goes.