Skip to content

Commit 7f6f8e6

Browse files
authored
AYS-516 | User Update Flow and User-Role Relations Have Been Optimized for Working Less Queries (#393)
1 parent 899a0a2 commit 7f6f8e6

File tree

4 files changed

+80
-37
lines changed

4 files changed

+80
-37
lines changed

src/main/java/org/ays/auth/model/AysUser.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515

1616
import java.time.LocalDateTime;
1717
import java.util.List;
18+
import java.util.Set;
19+
import java.util.stream.Collectors;
1820

1921
/**
2022
* Domain model representing a user entity for data transfer between the service layer and controller.
@@ -70,6 +72,37 @@ public boolean isDeleted() {
7072
}
7173

7274

75+
/**
76+
* Updates the user information with the specified details.
77+
* </p>
78+
*
79+
* @param emailAddress the email address of the user
80+
* @param firstName the first name of the user
81+
* @param lastName the last name of the user
82+
* @param phoneNumber the {@link AysPhoneNumber} containing the user's phone information
83+
* @param city the city where the user is located
84+
* @param roleIds the set of role IDs assigned to the user
85+
* @param updatedUser the identifier of the user who performed the update
86+
*/
87+
public void update(final String emailAddress,
88+
final String firstName,
89+
final String lastName,
90+
final AysPhoneNumber phoneNumber,
91+
final String city,
92+
final Set<String> roleIds,
93+
final String updatedUser) {
94+
95+
this.emailAddress = emailAddress;
96+
this.firstName = firstName;
97+
this.lastName = lastName;
98+
this.phoneNumber = phoneNumber;
99+
this.city = city;
100+
this.roles = roleIds.stream()
101+
.map(roleId -> AysRole.builder().id(roleId).build())
102+
.collect(Collectors.toList());
103+
this.updatedUser = updatedUser;
104+
}
105+
73106
/**
74107
* Sets the user's status to {@link AysUserStatus#ACTIVE}, marking the user as active.
75108
*/

src/main/java/org/ays/auth/model/entity/AysUserEntity.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
import org.ays.institution.model.entity.InstitutionEntity;
2525

2626
import java.time.LocalDateTime;
27-
import java.util.List;
27+
import java.util.Set;
2828

2929
/**
3030
* Represents a user entity in the application, extending from {@link BaseEntity}.
@@ -94,7 +94,7 @@ public class AysUserEntity extends BaseEntity {
9494
joinColumns = @JoinColumn(name = "USER_ID"),
9595
inverseJoinColumns = @JoinColumn(name = "ROLE_ID")
9696
)
97-
private List<AysRoleEntity> roles;
97+
private Set<AysRoleEntity> roles;
9898

9999

100100
/**

src/main/java/org/ays/auth/service/impl/AysUserUpdateServiceImpl.java

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
import java.util.List;
2626
import java.util.Set;
27+
import java.util.stream.Collectors;
2728

2829
/**
2930
* Service implementation for updating users.
@@ -56,7 +57,7 @@ public void update(final String id,
5657
final AysUser user = userReadPort.findById(id)
5758
.orElseThrow(() -> new AysUserNotExistByIdException(id));
5859

59-
String institutionId = identity.getInstitutionId();
60+
final String institutionId = identity.getInstitutionId();
6061
if (!institutionId.equals(user.getInstitution().getId())) {
6162
throw new AysUserNotExistByIdException(id);
6263
}
@@ -70,23 +71,33 @@ public void update(final String id,
7071
.lineNumber(updateRequest.getPhoneNumber().getLineNumber())
7172
.build();
7273

73-
if (!user.getPhoneNumber().equals(phoneNumber)) {
74+
final boolean isPhoneNumberChanged = !user.getPhoneNumber().equals(phoneNumber);
75+
if (isPhoneNumberChanged) {
7476
this.validatePhoneNumber(user, phoneNumber);
75-
user.setPhoneNumber(phoneNumber);
7677
}
7778

78-
if (!user.getEmailAddress().equals(updateRequest.getEmailAddress())) {
79+
final boolean isEmailChanged = !user.getEmailAddress().equals(updateRequest.getEmailAddress());
80+
if (isEmailChanged) {
7981
this.validateEmailAddress(user, updateRequest.getEmailAddress());
80-
user.setEmailAddress(updateRequest.getEmailAddress());
8182
}
8283

83-
this.validateRolesAndSet(user, updateRequest.getRoleIds(), institutionId);
84-
85-
user.setFirstName(updateRequest.getFirstName());
86-
user.setLastName(updateRequest.getLastName());
87-
user.setCity(updateRequest.getCity());
88-
user.setUpdatedUser(identity.getUserId());
84+
final Set<String> existingRoleIds = user.getRoles().stream()
85+
.map(AysRole::getId)
86+
.collect(Collectors.toSet());
87+
final boolean isRoleChanged = !existingRoleIds.equals(updateRequest.getRoleIds());
88+
if (isRoleChanged) {
89+
this.validateRoles(updateRequest.getRoleIds(), institutionId);
90+
}
8991

92+
user.update(
93+
updateRequest.getEmailAddress(),
94+
updateRequest.getFirstName(),
95+
updateRequest.getLastName(),
96+
phoneNumber,
97+
updateRequest.getCity(),
98+
updateRequest.getRoleIds(),
99+
identity.getUserId()
100+
);
90101
userSavePort.save(user);
91102
}
92103

@@ -212,36 +223,33 @@ private void validateEmailAddress(AysUser user, String emailAddress) {
212223

213224

214225
/**
215-
* Checks the existence of roles by their IDs and returns the corresponding role entities.
226+
* Validates if all specified roles exist and are active within the given institution.
227+
* <p>
228+
* This method checks if each role ID corresponds to an active role in the specified institution.
229+
* If any role is not found or not active, an exception is thrown with the list of invalid role IDs.
230+
* </p>
216231
*
217-
* @param user The user being updated.
218-
* @param roleIds The set of role IDs to be checked and retrieved.
219-
* @throws AysRolesNotExistException if any of the provided role IDs do not exist.
232+
* @param roleIds the set of role IDs to validate
233+
* @param institutionId the ID of the institution where the roles should exist
234+
* @throws AysRolesNotExistException if any of the specified roles do not exist or are not valid for the institution
220235
*/
221-
private void validateRolesAndSet(final AysUser user, final Set<String> roleIds, final String institutionId) {
222-
223-
boolean isRoleNotChanged = user.getRoles().stream()
224-
.allMatch(role -> roleIds.contains(role.getId()));
225-
if (isRoleNotChanged) {
226-
return;
227-
}
236+
private void validateRoles(final Set<String> roleIds, final String institutionId) {
228237

229238
final List<AysRole> roles = roleReadPort.findAllByIds(roleIds).stream()
230239
.filter(AysRole::isActive)
231240
.filter(role -> institutionId.equals(role.getInstitution().getId()))
232241
.toList();
233242

234-
if (roles.size() == roleIds.size()) {
235-
user.setRoles(roles);
236-
return;
237-
}
243+
if (roles.size() != roleIds.size()) {
238244

239-
final List<String> notExistsRoleIds = roleIds.stream()
240-
.filter(roleId -> roles.stream()
241-
.noneMatch(roleEntity -> roleEntity.getId().equals(roleId)))
242-
.toList();
245+
final List<String> notExistsRoleIds = roleIds.stream()
246+
.filter(roleId -> roles.stream()
247+
.noneMatch(roleEntity -> roleEntity.getId().equals(roleId)))
248+
.toList();
249+
250+
throw new AysRolesNotExistException(notExistsRoleIds);
251+
}
243252

244-
throw new AysRolesNotExistException(notExistsRoleIds);
245253
}
246254

247255
}

src/test/java/org/ays/auth/model/entity/AysUserEntityBuilder.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import org.ays.util.AysValidTestData;
1111

1212
import java.time.LocalDateTime;
13-
import java.util.List;
13+
import java.util.Set;
1414

1515
public class AysUserEntityBuilder extends TestDataBuilder<AysUserEntity> {
1616

@@ -30,8 +30,10 @@ public AysUserEntityBuilder withValidValues() {
3030
.withValidValues()
3131
.build();
3232

33-
List<AysRoleEntity> roleEntities = List.of(
34-
new AysRoleEntityBuilder().withValidValues().build()
33+
Set<AysRoleEntity> roleEntities = Set.of(
34+
new AysRoleEntityBuilder()
35+
.withValidValues()
36+
.build()
3537
);
3638

3739
InstitutionEntity institutionEntity = new InstitutionEntityBuilder().withValidValues().build();
@@ -78,7 +80,7 @@ public AysUserEntityBuilder withLoginAttempt(AysUserEntity.LoginAttemptEntity lo
7880
return this;
7981
}
8082

81-
public AysUserEntityBuilder withRoles(List<AysRoleEntity> roles) {
83+
public AysUserEntityBuilder withRoles(Set<AysRoleEntity> roles) {
8284
data.setRoles(roles);
8385
return this;
8486
}

0 commit comments

Comments
 (0)