Realized this is a somewhat older after writing up, but hey, maybe this will help someone.
In what I've worked on so far, I found it's much better to split out blocks of functionality into their "logical pieces". In this example, I suppose there would be a top level node/class which is the inventory manager. It would have the level of data and fields that are macro, like the max size of the inventory and would be the one who processes requests to add or remove things from the inventory, or even "clear all" or similar such functions. This manager could also be the one to define/react to "signals" to do with inventory management, so that way not every aspect of your game has to have easy access to its core inner workings to connect with it.
Then, you likely would want another node/class for an inventory-item. It could be itself generic and even potentially exhibit different behaviors (stacks? responding to being dragged around? Responding to clicks in general?). Operations that are inherently linked to a single item can then logically be placed in this script/class (even if it's the inventory manager itself who is making the calls to make these changes). You could potentially even have an intermediate class called item-slot, which itself could be empty or have an item/stack attached to it.
Splitting up code into logical parts helps keep things structured - and if you are consistent, it's quick to find code later when the project grows ("hm I need to edit dropping a stack... ah, because that has to do with one item-slot, it must be in the items code which does with operations on a single item/stack at a time!)