Where does this custom inventory data "live" at runtime?

If in your game you don’t have a world representation of an item then you should go with UObjects. Actor + Struct works great when you can pick up items, store them, drop and move around the world. If everything happens in the UI then you just need a blueprintable UObject which designers can derive from and create various items. Then you can have a TArray<TSubclassOf<UItem>> on your ‘bin’ object and designers can again populate it with items they want.