Awesome Reviewers

When changing or adding security-sensitive functionality, keep authorization semantics stable and use project-wide shared validation/auth plumbing.

Apply this standard: 1) Preserve existing access contracts

Example pattern (authorization contract + validation) inspired by the discussions:

// Preserve legacy behavior by only validating/applying role when role_id exists.
roleID := invitationRow.RoleID
if roleID != nil {
    if _, err := client.Role.Query().Where(
        role.IDEQ(*roleID),
        role.ProjectIDEQ(invitationRow.ProjectID),
    ).Only(ctx); err != nil {
        return fmt.Errorf("invitation role is no longer available")
    }
}
// Otherwise: keep null/legacy semantics to avoid privilege escalation.

Net effect: fewer privilege-escalation surprises, fewer auth-header mismatches, and consistent security behavior across the codebase.