Upgradeable contracts best practices/ design patterns?

Something I am thinking about now that I am about to make my contracts upgradeable; what are the best practices when writing upgradeable code? E.g., is there any particular way the codebase should be structured, is it ultimately worth it to make upgradeable contracts (that is, how has been the success of the projects that did use upgradeable contracts) etc.?

Also, I would highly appreciate any resources (books, articles etc.) on Solidity design patterns, particularly in case of upgradeable contracts; it feels as if there is no guidance on this at the moment.

There is some documentation here for writing the upgradable contracts: https://docs.openzeppelin.com/upgrades-plugins/1.x/writing-upgradeable

On whether you should make your contract upgradeable, it really depends on your scenario and weighing the pros and cons in terms of the ability to upgrade vs. having an immutable contract.

Thanks for this, Eric. I had already gone through the material available on the website and was wondering if there were any detailed solidity design pattern guides I could use.