It depends, pull request reviews should be done before merging to master. If you are using CI/CD, that would occur as often as you can schedule releases. I prefer the fork and pull request workflow, keeping the base repository cleaner. The devs can organize how they choose on their ends in their forks as long as they are routinely fetching from the base master branch.
If a dev quits, no one wants to be confused by what he/she was working on, so there is a plus with fork and pull there as well. Likely the next guy will start over from the approved master branch anyway.
Integration tests happen after merge to master, then there are conditions that must be met prior to release within the CI/CD pipeline that if not met will break the build. Use the same branch for all environments, with environment variables if there are differences in environments. You can use labels or the merge requests themselves to describe what’s released. You don’t necessarily need feature branches. It just depends on the complexity of your project(s) and your team. More branches = more complicated from my perspective, particularly with dependencies on multiple repositories. Don’t tell the devs how to work, if you can avoid it, just set the requirements for approvals, rollbacks, and workflows necessary to guarantee you can report effectively to your management. Keep it simple. Good devs will figure out how to work together on their own.