InviteService was directly injecting AppUserRepository, UserGroupRepository,
and PasswordEncoder — crossing domain boundaries that UserService owns.
- Add UserService.createUser() with duplicate-email guard
- Add UserService.findGroupsByIds() delegation method
- InviteService now only injects UserService (not user repositories)
- generateCode() now throws INTERNAL_ERROR after 10 failed attempts
instead of looping indefinitely
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>