Initializing upgraded contracts

Hey all, so I would like to make sure I understand the UUPS upgrade concept correctly.

According to the tests I've done, when using the hardhat-upgrades package and using the deployProxy function this function also calls initialize on both the implementation and proxy contracts. Is this understanding correct? My V1 initializer looks like this:

  function initialize(address creator) public virtual override initializer {
        OtherContract.initialize(creator);
        __Ownable_init();
        __ReentrancyGuard_init();
    }

My main concern now is when I upgrade to V2 using the upgradeProxy function. Do I also have to have a new initialize function in this second implementation which calls V1.initialize(address)? My tests reveal that this is not the case, that if V1 was initialized then it should propagate through upgrades still but I would like to make sure I'm not missing anything.

Edit: I have realized the deployProxy function DOES NOT call the initialize function on the implementation, hence I added a constructor with _disableInitializers(); to my base contract. This seems to work and block further initializations. My questions regarding future upgrading remain though. Should the upgraded contracts have some kind of initialize function or have additional protection of some kind?

I have realized the deployProxy function DOES NOT call the initialize function on the implementation, hence I added a constructor with _disableInitializers(); to my base contract.

This is correct.

Should the upgraded contracts have some kind of initialize function or have additional protection of some kind?

It depends on your contract. An upgrade does maintain the state of your proxy, but if you want some sort of migration or additional initialization during an upgrade, then see Initializable's reinitializers.