projects.visibility_level condition should be an OR condition instead of a sub-query in a UNION
Currently the query used to grab all projects a user has access to includes the following snippet:
... UNION SELECT projects.id FROM projects WHERE projects.visibility_level IN (20, 10) ...
This bit produces a rather long list of projects in a sub-query. It's possible using an "OR" condition is faster, e.g:
SELECT * FROM projects WHERE id IN ( ... ) OR visibility_level IN (20, 10)