refactor(authorization): pass loaded user to audit can-audit check
Why
Final sweep of the hasPermission migration. Found by temporarily dropping string from the IAuthorization / wrapper signatures and letting the compiler flag every remaining string-arg call site (215), then classifying them.
Result: of the ~212 remaining string callers, ~192 hold only a bare user id (this.userId/uid/userId — no object, correctly left as strings) and 19 pass X._id from a partial user (message.u, subscription.u, deletingUser, roomAccessValidator's Pick<IUser,'_id'>, the integrations findOneByUsername projections, and Room.join's partial-user contract — all intentionally kept on the id path).
Exactly one genuine miss: ee/server/lib/audit/functions.ts. requireAuditor loads the full user with Users.findOneById(userId) (no projection → roles present), but the can-audit check was still passing user._id.
Change
Pass the loaded user object to hasPermissionAsync — skips the check's internal Users.findOneById, roles are already present at runtime.
The migration is otherwise complete: every other call site either has no user object in scope or holds a rolesless projection.