I think the most correct answer is “whatever works best for your team”. Everyone has different workflows and skills on a team which will require different things.
That being said, the way we do it is, we build core frameworks in C++ and then build Blueprints for the LDs to use. For example, we created a spawn point. I wrote the whole thing in C++ and exposed all the properties that were needed to spawn various amounts of enemies and types. Then I created a BP that inherits from the C++ class for our LDs to use when they are putting levels together. Now, they can just drop that in a level and tell it what they want to spawn and how many.
We have done the same thing for our pawns as well but that is a bit more complicated.
The reason we did this is because I (as the primary developer) find C++ easier to maintain when there is a lot of stuff going on, esp when it comes to math. So I write everything in C++ and expose what needs to be exposed via the Blueprints. This allows our LD or Artists to add what they want via Blueprints and the core functionality stays in C++.
Another way to look at the way we did it is all of the functionality is in C++ and the UI layer of all of the objects is in BPs. That is a firm rule we stick to. I don’t do any UI dev in C++, the workflow is simply too slow and I like the feel of doing it in BPs as well. Obviously things like spawn points are not UI, this is in addition to that.
As an indie dev studio we have found that making things as modular as possible and empowering non-programmers to add functionality is very important to the dev cycle. This workflow allows that while keeping a programmers workflow smooth.