Another solution you can use to protect you from yourself here is using a relatively mature framework, and keep to its conventions.
To underline -- the older, more stable, and more boring, the better!
What you have then is at least some well understood, well documented foundation for others to immediately understand the basic structure and flows of the code.
The hardest thing here is being disciplined about sticking to the conventions, even when they seem suboptimal for your 'special' usecase.
Really try hard to not do things like pulling in 'community plugins' and the like, using language features the framework was not designed to work with, or in the worst case forking the framework or going off on your own path with custom code that reimplements some of its features! Stay as boring as possible!
To underline -- the older, more stable, and more boring, the better!
What you have then is at least some well understood, well documented foundation for others to immediately understand the basic structure and flows of the code.
The hardest thing here is being disciplined about sticking to the conventions, even when they seem suboptimal for your 'special' usecase.
Really try hard to not do things like pulling in 'community plugins' and the like, using language features the framework was not designed to work with, or in the worst case forking the framework or going off on your own path with custom code that reimplements some of its features! Stay as boring as possible!