I assumed the code review commits would be squashed before the merge. But you raise a valid point about the code review process being lost. One way to get around that is to keep the feature branches (or maybe just tags) forever and do all the squashing on the integration branch. This does require some kind of convention that records on which branch/tag the code review for a particular feature can be found.
The advantage of this kind of approach is it doesn't require any special tooling, but could certainly be made easier with special tooling.
Or just don't squash. There's no need. In fact, if you're doing a review process like this, it would be active vandalism to to squash, since there is a big difference between "code said x, commented on by reviewer, changed to y" vs "code says y".
If you don't squash then you're essentially dedicating the history to code reviews because it won't be much use for anything else. If you leave broken commits on the main branch then it becomes really hard to bisect to find regressions. And that's the only reason for keeping history really.
The advantage of this kind of approach is it doesn't require any special tooling, but could certainly be made easier with special tooling.