From 733e20e7f5fdd3215d4a0233bf849014f5d1ce5e Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Sun, 5 Apr 2026 16:03:27 +0200 Subject: [PATCH 01/17] Feat: UserRequest --- .../vet1177/controller/UserController.java | 4 ++ .../vet1177/dto/request/user/UserRequest.java | 70 +++++++++++++++++++ .../dto/response/user/UserResponse.java | 4 ++ 3 files changed, 78 insertions(+) create mode 100644 src/main/java/org/example/vet1177/controller/UserController.java create mode 100644 src/main/java/org/example/vet1177/dto/request/user/UserRequest.java create mode 100644 src/main/java/org/example/vet1177/dto/response/user/UserResponse.java diff --git a/src/main/java/org/example/vet1177/controller/UserController.java b/src/main/java/org/example/vet1177/controller/UserController.java new file mode 100644 index 00000000..dcdee63d --- /dev/null +++ b/src/main/java/org/example/vet1177/controller/UserController.java @@ -0,0 +1,4 @@ +package org.example.vet1177.controller; + +public class UserController { +} diff --git a/src/main/java/org/example/vet1177/dto/request/user/UserRequest.java b/src/main/java/org/example/vet1177/dto/request/user/UserRequest.java new file mode 100644 index 00000000..aaefca6f --- /dev/null +++ b/src/main/java/org/example/vet1177/dto/request/user/UserRequest.java @@ -0,0 +1,70 @@ +package org.example.vet1177.dto.request.user; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.NotBlank; +import jakarta.validation.constraints.NotNull; +import org.example.vet1177.entities.Role; + +import java.util.UUID; + +public class UserRequest { + + @NotBlank + private String name; + + @NotBlank + @Email + private String email; + + @NotBlank + private String password; + + @NotNull + private Role role; + + @NotNull + private UUID ClinicId; + + public UserRequest(){ + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Role getRole() { + return role; + } + + public void setRole(Role role) { + this.role = role; + } + + public UUID getClinicId() { + return ClinicId; + } + + public void setClinicId(UUID clinicId) { + ClinicId = clinicId; + } +} diff --git a/src/main/java/org/example/vet1177/dto/response/user/UserResponse.java b/src/main/java/org/example/vet1177/dto/response/user/UserResponse.java new file mode 100644 index 00000000..1a29fb88 --- /dev/null +++ b/src/main/java/org/example/vet1177/dto/response/user/UserResponse.java @@ -0,0 +1,4 @@ +package org.example.vet1177.dto.response.user; + +public class UserResponse { +} From e0dacbca09c049bc3e21dc7d540e072563cf0fdc Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Sun, 5 Apr 2026 16:16:38 +0200 Subject: [PATCH 02/17] Feat: UserResponse --- .../dto/response/user/UserResponse.java | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/src/main/java/org/example/vet1177/dto/response/user/UserResponse.java b/src/main/java/org/example/vet1177/dto/response/user/UserResponse.java index 1a29fb88..fe6212a1 100644 --- a/src/main/java/org/example/vet1177/dto/response/user/UserResponse.java +++ b/src/main/java/org/example/vet1177/dto/response/user/UserResponse.java @@ -1,4 +1,86 @@ package org.example.vet1177.dto.response.user; +import org.example.vet1177.entities.Role; + +import java.time.Instant; +import java.util.UUID; + public class UserResponse { + + private UUID id; + private String name; + private String email; + private Role role; + private UUID clinicId; + private Instant createdAt; + private Instant updatedAt; + + public UserResponse() { + } + + public UserResponse(UUID id, String name, String email, Role role, UUID clinicId, Instant createdAt, Instant updatedAt) { + this.id =id; + this.name =name; + this.email = email; + this.role = role; + this.clinicId = clinicId; + this.createdAt = createdAt; + this.updatedAt =updatedAt; + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public Role getRole() { + return role; + } + + public void setRole(Role role) { + this.role = role; + } + + public UUID getClinicId() { + return clinicId; + } + + public void setClinicId(UUID clinicId) { + this.clinicId = clinicId; + } + + public Instant getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Instant createdAt) { + this.createdAt = createdAt; + } + + public Instant getUpdatedAt() { + return updatedAt; + } + + public void setUpdatedAt(Instant updatedAt) { + this.updatedAt = updatedAt; + } } From f74cb703e045bdb7240b367f1fbd72c8abfd75ca Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Sun, 5 Apr 2026 17:04:48 +0200 Subject: [PATCH 03/17] feat: Add UserController and update UserService with getAllUsers --- .../vet1177/controller/UserController.java | 37 +++++++++++++++++++ .../example/vet1177/services/UserService.java | 18 +++++++++ 2 files changed, 55 insertions(+) diff --git a/src/main/java/org/example/vet1177/controller/UserController.java b/src/main/java/org/example/vet1177/controller/UserController.java index dcdee63d..4f423832 100644 --- a/src/main/java/org/example/vet1177/controller/UserController.java +++ b/src/main/java/org/example/vet1177/controller/UserController.java @@ -1,4 +1,41 @@ package org.example.vet1177.controller; +import org.example.vet1177.dto.response.user.UserResponse; +import org.example.vet1177.services.UserService; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequestMapping("/users") public class UserController { + + private final UserService userService; + + public UserController(UserService userService) { + this.userService = userService; + } + + //GET /users- Hämta alla användare + @GetMapping + public ResponseEntity> getAllUsers() { + List users = userService.getAllUsers(); + return ResponseEntity.ok(users); + } + + // GEt /users/{id}- Hämta en användte + + //POST /users - skapa ny användare +// @GetMapping +// public UserResponse createUser() { +// return ; +// } + + //PUT /users/{id} - uppdatera användare + + //DELETE /users/{id} - Tar bort användare + } diff --git a/src/main/java/org/example/vet1177/services/UserService.java b/src/main/java/org/example/vet1177/services/UserService.java index 17d8be0b..0fcf0a90 100644 --- a/src/main/java/org/example/vet1177/services/UserService.java +++ b/src/main/java/org/example/vet1177/services/UserService.java @@ -1,5 +1,6 @@ package org.example.vet1177.services; +import org.example.vet1177.dto.response.user.UserResponse; import org.example.vet1177.entities.Role; import org.example.vet1177.entities.User; import org.example.vet1177.exception.ResourceNotFoundException; @@ -7,6 +8,7 @@ import org.springframework.stereotype.Service; +import java.util.List; import java.util.UUID; @Service @@ -33,4 +35,20 @@ public User getByEmail(String email){ .orElseThrow(() -> new ResourceNotFoundException("User", email)); } + //Get all users + public List getAllUsers() { + return userRepository.findAll() + .stream() + .map(user -> new UserResponse( + user.getId(), + user.getName(), + user.getEmail(), + user.getRole(), + user.getClinic() != null ? user.getClinic().getId() : null, + user.getCreatedAt(), + user.getUpdatedAt() + )) + .toList(); + } + } From 1644951f926252a8befae513bf80d10b3e2b2d39 Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Sun, 5 Apr 2026 17:42:26 +0200 Subject: [PATCH 04/17] Add getUserEntityById to UserService and fix ActivityLogController and MedicalRecordController incompatible type --- .../controller/ActivityLogController.java | 2 +- .../controller/MedicalRecordController.java | 2 +- .../vet1177/controller/UserController.java | 7 ++++ .../example/vet1177/services/UserService.java | 40 +++++++++++++------ 4 files changed, 36 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/example/vet1177/controller/ActivityLogController.java b/src/main/java/org/example/vet1177/controller/ActivityLogController.java index de6e6b7f..7b1aca63 100644 --- a/src/main/java/org/example/vet1177/controller/ActivityLogController.java +++ b/src/main/java/org/example/vet1177/controller/ActivityLogController.java @@ -28,7 +28,7 @@ public List getLogsByRecord( @PathVariable UUID recordId, @RequestHeader("userId") UUID userId ) { - User user = userService.getById(userId); + User user = userService.getUserEntityById(userId); return activityLogService.getByRecord(recordId, user) .stream() diff --git a/src/main/java/org/example/vet1177/controller/MedicalRecordController.java b/src/main/java/org/example/vet1177/controller/MedicalRecordController.java index 51c9c079..00d54f24 100644 --- a/src/main/java/org/example/vet1177/controller/MedicalRecordController.java +++ b/src/main/java/org/example/vet1177/controller/MedicalRecordController.java @@ -184,7 +184,7 @@ public ResponseEntity assignVet( @AuthenticationPrincipal User currentUser) { MedicalRecord record = medicalRecordService.getById(id); - User vetToAssign = userService.getById(request.vetId()); + User vetToAssign = userService.getUserEntityById(request.vetId()); medicalRecordPolicy.canAssignVet(currentUser, record, vetToAssign); return ResponseEntity.ok( diff --git a/src/main/java/org/example/vet1177/controller/UserController.java b/src/main/java/org/example/vet1177/controller/UserController.java index 4f423832..3257efa3 100644 --- a/src/main/java/org/example/vet1177/controller/UserController.java +++ b/src/main/java/org/example/vet1177/controller/UserController.java @@ -4,10 +4,12 @@ import org.example.vet1177.services.UserService; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import java.util.List; +import java.util.UUID; @RestController @RequestMapping("/users") @@ -27,6 +29,11 @@ public ResponseEntity> getAllUsers() { } // GEt /users/{id}- Hämta en användte + @GetMapping("/{id}") + public ResponseEntity getUserById(@PathVariable UUID id) { + UserResponse user = userService.getById(id); + return ResponseEntity.ok(user); + } //POST /users - skapa ny användare // @GetMapping diff --git a/src/main/java/org/example/vet1177/services/UserService.java b/src/main/java/org/example/vet1177/services/UserService.java index 0fcf0a90..f0b4b07f 100644 --- a/src/main/java/org/example/vet1177/services/UserService.java +++ b/src/main/java/org/example/vet1177/services/UserService.java @@ -25,30 +25,44 @@ public User createUser(String name, String email, String passwordHash, Role role return userRepository.save(user); } - public User getById(UUID id){ + public User getByEmail(String email){ + return userRepository.findByEmail(email) + .orElseThrow(() -> new ResourceNotFoundException("User", email)); + } + + // Returnerar User-entiteten, används internt när andra services behöver ett User-objekt. OK? - annars + public User getUserEntityById(UUID id) { return userRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("User", id)); } - public User getByEmail(String email){ - return userRepository.findByEmail(email) - .orElseThrow(() -> new ResourceNotFoundException("User", email)); + // Returnerar UserResponse DTO, används av UserController för att exponera användardata till klienten. + // Ändra anrop från getById() till getUserEntityById() i ActivityLogController + public UserResponse getById(UUID id) { + User user = userRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("User", id)); + return mapToResponse(user); } //Get all users public List getAllUsers() { return userRepository.findAll() .stream() - .map(user -> new UserResponse( - user.getId(), - user.getName(), - user.getEmail(), - user.getRole(), - user.getClinic() != null ? user.getClinic().getId() : null, - user.getCreatedAt(), - user.getUpdatedAt() - )) + .map(this::mapToResponse) .toList(); } + //Helper + private UserResponse mapToResponse(User user) { + return new UserResponse( + user.getId(), + user.getName(), + user.getEmail(), + user.getRole(), + user.getClinic() != null ? user.getClinic().getId() : null, + user.getCreatedAt(), + user.getUpdatedAt() + ); + } + } From fb41acfd04fcf462d3b7de3ba1fab24186d141a3 Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Sun, 5 Apr 2026 18:04:09 +0200 Subject: [PATCH 05/17] Add createUser to UserController and fix createUser in UserService --- .../vet1177/controller/UserController.java | 16 ++++++++-------- .../example/vet1177/services/UserService.java | 7 ++++--- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/example/vet1177/controller/UserController.java b/src/main/java/org/example/vet1177/controller/UserController.java index 3257efa3..c5d34690 100644 --- a/src/main/java/org/example/vet1177/controller/UserController.java +++ b/src/main/java/org/example/vet1177/controller/UserController.java @@ -1,12 +1,11 @@ package org.example.vet1177.controller; +import jakarta.validation.Valid; +import org.example.vet1177.dto.request.user.UserRequest; import org.example.vet1177.dto.response.user.UserResponse; import org.example.vet1177.services.UserService; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PathVariable; -import org.springframework.web.bind.annotation.RequestMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; import java.util.List; import java.util.UUID; @@ -36,10 +35,11 @@ public ResponseEntity getUserById(@PathVariable UUID id) { } //POST /users - skapa ny användare -// @GetMapping -// public UserResponse createUser() { -// return ; -// } + @PostMapping + public ResponseEntity createUser(@Valid @RequestBody UserRequest request) { + UserResponse user = userService.createUser(request); + return ResponseEntity.status(201).body(user); + } //PUT /users/{id} - uppdatera användare diff --git a/src/main/java/org/example/vet1177/services/UserService.java b/src/main/java/org/example/vet1177/services/UserService.java index f0b4b07f..bf486f42 100644 --- a/src/main/java/org/example/vet1177/services/UserService.java +++ b/src/main/java/org/example/vet1177/services/UserService.java @@ -1,5 +1,6 @@ package org.example.vet1177.services; +import org.example.vet1177.dto.request.user.UserRequest; import org.example.vet1177.dto.response.user.UserResponse; import org.example.vet1177.entities.Role; import org.example.vet1177.entities.User; @@ -20,9 +21,9 @@ public UserService(UserRepository userRepository){ this.userRepository = userRepository; } - public User createUser(String name, String email, String passwordHash, Role role){ - User user = new User(name, email, passwordHash, role); - return userRepository.save(user); + public UserResponse createUser(UserRequest request) { + User user = new User(request.getName(), request.getEmail(), request.getPassword(), request.getRole()); + return mapToResponse(userRepository.save(user)); } public User getByEmail(String email){ From b10c3cbd39a02d35d3141d867c09842670155d10 Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Sun, 5 Apr 2026 20:25:06 +0200 Subject: [PATCH 06/17] Add updateUser to UserController and in UserService. Added todo: in userserivce to remind to secure the password when implement spring-security --- .../example/vet1177/controller/UserController.java | 5 +++++ .../vet1177/dto/request/user/UserRequest.java | 7 +++---- .../org/example/vet1177/services/UserService.java | 13 ++++++++++++- 3 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/example/vet1177/controller/UserController.java b/src/main/java/org/example/vet1177/controller/UserController.java index c5d34690..d58a4057 100644 --- a/src/main/java/org/example/vet1177/controller/UserController.java +++ b/src/main/java/org/example/vet1177/controller/UserController.java @@ -42,6 +42,11 @@ public ResponseEntity createUser(@Valid @RequestBody UserRequest r } //PUT /users/{id} - uppdatera användare + @PutMapping("/{id}") + public ResponseEntity updateUser(@PathVariable UUID id, @Valid @RequestBody UserRequest request) { + UserResponse user = userService.updateUser(id, request); + return ResponseEntity.ok(user); + } //DELETE /users/{id} - Tar bort användare diff --git a/src/main/java/org/example/vet1177/dto/request/user/UserRequest.java b/src/main/java/org/example/vet1177/dto/request/user/UserRequest.java index aaefca6f..1adb8aff 100644 --- a/src/main/java/org/example/vet1177/dto/request/user/UserRequest.java +++ b/src/main/java/org/example/vet1177/dto/request/user/UserRequest.java @@ -22,8 +22,7 @@ public class UserRequest { @NotNull private Role role; - @NotNull - private UUID ClinicId; + private UUID clinicId; public UserRequest(){ } @@ -61,10 +60,10 @@ public void setRole(Role role) { } public UUID getClinicId() { - return ClinicId; + return clinicId; } public void setClinicId(UUID clinicId) { - ClinicId = clinicId; + this.clinicId = clinicId; } } diff --git a/src/main/java/org/example/vet1177/services/UserService.java b/src/main/java/org/example/vet1177/services/UserService.java index bf486f42..eb314f97 100644 --- a/src/main/java/org/example/vet1177/services/UserService.java +++ b/src/main/java/org/example/vet1177/services/UserService.java @@ -2,7 +2,6 @@ import org.example.vet1177.dto.request.user.UserRequest; import org.example.vet1177.dto.response.user.UserResponse; -import org.example.vet1177.entities.Role; import org.example.vet1177.entities.User; import org.example.vet1177.exception.ResourceNotFoundException; import org.example.vet1177.repository.UserRepository; @@ -21,7 +20,9 @@ public UserService(UserRepository userRepository){ this.userRepository = userRepository; } + public UserResponse createUser(UserRequest request) { + // TODO: Hasha lösenordet med BCrypt när Spring Security implementeras User user = new User(request.getName(), request.getEmail(), request.getPassword(), request.getRole()); return mapToResponse(userRepository.save(user)); } @@ -53,6 +54,16 @@ public List getAllUsers() { .toList(); } + //Update user + public UserResponse updateUser(UUID id, UserRequest request) { + User user = userRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("User", id)); + user.setName(request.getName()); + user.setEmail(request.getEmail()); + + return mapToResponse(userRepository.save(user)); + } + //Helper private UserResponse mapToResponse(User user) { return new UserResponse( From f4725ecc0f6657e2c570d7cf7a4d39d15a92db5c Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Sun, 5 Apr 2026 20:53:37 +0200 Subject: [PATCH 07/17] feat: deleteUser --- .../vet1177/controller/UserController.java | 15 +++++++++++---- .../org/example/vet1177/services/UserService.java | 9 ++++++++- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/example/vet1177/controller/UserController.java b/src/main/java/org/example/vet1177/controller/UserController.java index d58a4057..664858ea 100644 --- a/src/main/java/org/example/vet1177/controller/UserController.java +++ b/src/main/java/org/example/vet1177/controller/UserController.java @@ -4,6 +4,7 @@ import org.example.vet1177.dto.request.user.UserRequest; import org.example.vet1177.dto.response.user.UserResponse; import org.example.vet1177.services.UserService; +import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -27,7 +28,7 @@ public ResponseEntity> getAllUsers() { return ResponseEntity.ok(users); } - // GEt /users/{id}- Hämta en användte + // GET /users/{id}- Hämta 1 användare @GetMapping("/{id}") public ResponseEntity getUserById(@PathVariable UUID id) { UserResponse user = userService.getById(id); @@ -38,16 +39,22 @@ public ResponseEntity getUserById(@PathVariable UUID id) { @PostMapping public ResponseEntity createUser(@Valid @RequestBody UserRequest request) { UserResponse user = userService.createUser(request); - return ResponseEntity.status(201).body(user); + return ResponseEntity.status(HttpStatus.CREATED).body(user); } //PUT /users/{id} - uppdatera användare + // PUT /users/{id} - uppdatera användare @PutMapping("/{id}") - public ResponseEntity updateUser(@PathVariable UUID id, @Valid @RequestBody UserRequest request) { + public ResponseEntity updateUser(@PathVariable UUID id, + @Valid @RequestBody UserRequest request) { UserResponse user = userService.updateUser(id, request); return ResponseEntity.ok(user); } //DELETE /users/{id} - Tar bort användare - + @DeleteMapping("/{id}") + public ResponseEntity deleteUser(@PathVariable UUID id) { + userService.deleteUser(id); + return ResponseEntity.noContent().build(); + } } diff --git a/src/main/java/org/example/vet1177/services/UserService.java b/src/main/java/org/example/vet1177/services/UserService.java index eb314f97..7132fe57 100644 --- a/src/main/java/org/example/vet1177/services/UserService.java +++ b/src/main/java/org/example/vet1177/services/UserService.java @@ -20,13 +20,13 @@ public UserService(UserRepository userRepository){ this.userRepository = userRepository; } - public UserResponse createUser(UserRequest request) { // TODO: Hasha lösenordet med BCrypt när Spring Security implementeras User user = new User(request.getName(), request.getEmail(), request.getPassword(), request.getRole()); return mapToResponse(userRepository.save(user)); } + // TODO: GET /users/search?email= - Sök användare på email, kräver ADMIN-roll (implementera när Spring Security är på plats) public User getByEmail(String email){ return userRepository.findByEmail(email) .orElseThrow(() -> new ResourceNotFoundException("User", email)); @@ -64,6 +64,13 @@ public UserResponse updateUser(UUID id, UserRequest request) { return mapToResponse(userRepository.save(user)); } + //Delete user + public void deleteUser(UUID id) { + User user = userRepository.findById(id) + .orElseThrow(() -> new ResourceNotFoundException("User", id)); + userRepository.delete(user); + } + //Helper private UserResponse mapToResponse(User user) { return new UserResponse( From ea43114e156229403d310c007202340dac13c18d Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Sun, 5 Apr 2026 21:17:20 +0200 Subject: [PATCH 08/17] feat(user): add email validation and clinic rules for VET --- .../vet1177/repository/UserRepository.java | 2 + .../example/vet1177/services/UserService.java | 45 ++++++++++++++++--- 2 files changed, 42 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/example/vet1177/repository/UserRepository.java b/src/main/java/org/example/vet1177/repository/UserRepository.java index 9651ae7d..49058751 100644 --- a/src/main/java/org/example/vet1177/repository/UserRepository.java +++ b/src/main/java/org/example/vet1177/repository/UserRepository.java @@ -9,4 +9,6 @@ public interface UserRepository extends JpaRepository { Optional findByEmail(String email); + boolean existsByEmail(String email); + boolean existsByEmailAndIdNot(String email, UUID id); } diff --git a/src/main/java/org/example/vet1177/services/UserService.java b/src/main/java/org/example/vet1177/services/UserService.java index 7132fe57..b256723c 100644 --- a/src/main/java/org/example/vet1177/services/UserService.java +++ b/src/main/java/org/example/vet1177/services/UserService.java @@ -2,6 +2,8 @@ import org.example.vet1177.dto.request.user.UserRequest; import org.example.vet1177.dto.response.user.UserResponse; +import org.example.vet1177.entities.Clinic; +import org.example.vet1177.entities.Role; import org.example.vet1177.entities.User; import org.example.vet1177.exception.ResourceNotFoundException; import org.example.vet1177.repository.UserRepository; @@ -15,14 +17,21 @@ public class UserService { private final UserRepository userRepository; + private final ClinicService clinicService; - public UserService(UserRepository userRepository){ + public UserService(UserRepository userRepository, ClinicService clinicService){ this.userRepository = userRepository; + this.clinicService = clinicService; } - + // TODO: Hasha lösenordet med BCrypt när Spring Security implementeras public UserResponse createUser(UserRequest request) { - // TODO: Hasha lösenordet med BCrypt när Spring Security implementeras - User user = new User(request.getName(), request.getEmail(), request.getPassword(), request.getRole()); + validateEmailUnique(request.getEmail()); + User user = new User( + request.getName(), + request.getEmail(), + request.getPassword(), + request.getRole()); + applyClinicRules(user, request); return mapToResponse(userRepository.save(user)); } @@ -58,9 +67,10 @@ public List getAllUsers() { public UserResponse updateUser(UUID id, UserRequest request) { User user = userRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("User", id)); + validateEmailUniqueForUpdate(request.getEmail(), id); user.setName(request.getName()); user.setEmail(request.getEmail()); - + applyClinicRules(user, request); return mapToResponse(userRepository.save(user)); } @@ -84,4 +94,29 @@ private UserResponse mapToResponse(User user) { ); } + private void validateEmailUnique(String email) { + if (userRepository.existsByEmail(email)) { + throw new IllegalArgumentException("Email används redan"); + } + } + + private void validateEmailUniqueForUpdate(String email, UUID userId) { + if (userRepository.existsByEmailAndIdNot(email, userId)) { + throw new IllegalArgumentException("Email används redan"); + } + } + + private void applyClinicRules(User user, UserRequest request) { + if (request.getRole() == Role.VET) { + if (request.getClinicId() == null) { + throw new IllegalArgumentException("Veterinär måste vara kopplad till en klinik"); + } + + Clinic clinic = clinicService.getById(request.getClinicId()); + user.setClinic(clinic); + } else { + user.setClinic(null); + } + } + } From 0eb37e26ee5c3a7d5a8b13a819cdf6134b14dd8b Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Sun, 5 Apr 2026 21:30:49 +0200 Subject: [PATCH 09/17] pusch --- src/main/java/org/example/vet1177/services/UserService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/org/example/vet1177/services/UserService.java b/src/main/java/org/example/vet1177/services/UserService.java index b256723c..b7aab848 100644 --- a/src/main/java/org/example/vet1177/services/UserService.java +++ b/src/main/java/org/example/vet1177/services/UserService.java @@ -118,5 +118,4 @@ private void applyClinicRules(User user, UserRequest request) { user.setClinic(null); } } - } From baab67829f7bc43509e019403760a28b90ee0fbc Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Mon, 6 Apr 2026 09:48:53 +0200 Subject: [PATCH 10/17] fix: added /api to usercontroller --- .../java/org/example/vet1177/controller/UserController.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/org/example/vet1177/controller/UserController.java b/src/main/java/org/example/vet1177/controller/UserController.java index 664858ea..e2dcb3e3 100644 --- a/src/main/java/org/example/vet1177/controller/UserController.java +++ b/src/main/java/org/example/vet1177/controller/UserController.java @@ -12,7 +12,7 @@ import java.util.UUID; @RestController -@RequestMapping("/users") +@RequestMapping("/api/users") public class UserController { private final UserService userService; From 591c8eb12079fa7457d068a3034dab3cd87710b1 Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Mon, 6 Apr 2026 11:01:11 +0200 Subject: [PATCH 11/17] feat(user): separate DTOs for create/update and refactor clinic rules --- .../vet1177/controller/UserController.java | 3 +- .../vet1177/dto/request/user/UserRequest.java | 3 ++ .../dto/request/user/UserUpdateRequest.java | 41 +++++++++++++++++++ .../example/vet1177/services/UserService.java | 40 ++++++++++++------ 4 files changed, 73 insertions(+), 14 deletions(-) create mode 100644 src/main/java/org/example/vet1177/dto/request/user/UserUpdateRequest.java diff --git a/src/main/java/org/example/vet1177/controller/UserController.java b/src/main/java/org/example/vet1177/controller/UserController.java index e2dcb3e3..6fd3d797 100644 --- a/src/main/java/org/example/vet1177/controller/UserController.java +++ b/src/main/java/org/example/vet1177/controller/UserController.java @@ -7,6 +7,7 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; +import org.example.vet1177.dto.request.user.UserUpdateRequest; import java.util.List; import java.util.UUID; @@ -46,7 +47,7 @@ public ResponseEntity createUser(@Valid @RequestBody UserRequest r // PUT /users/{id} - uppdatera användare @PutMapping("/{id}") public ResponseEntity updateUser(@PathVariable UUID id, - @Valid @RequestBody UserRequest request) { + @Valid @RequestBody UserUpdateRequest request) { UserResponse user = userService.updateUser(id, request); return ResponseEntity.ok(user); } diff --git a/src/main/java/org/example/vet1177/dto/request/user/UserRequest.java b/src/main/java/org/example/vet1177/dto/request/user/UserRequest.java index 1adb8aff..ae1cf0fd 100644 --- a/src/main/java/org/example/vet1177/dto/request/user/UserRequest.java +++ b/src/main/java/org/example/vet1177/dto/request/user/UserRequest.java @@ -3,6 +3,7 @@ import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotBlank; import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; import org.example.vet1177.entities.Role; import java.util.UUID; @@ -10,6 +11,7 @@ public class UserRequest { @NotBlank + @Size(min = 2, max = 100) private String name; @NotBlank @@ -17,6 +19,7 @@ public class UserRequest { private String email; @NotBlank + @Size(min = 8, max = 100) private String password; @NotNull diff --git a/src/main/java/org/example/vet1177/dto/request/user/UserUpdateRequest.java b/src/main/java/org/example/vet1177/dto/request/user/UserUpdateRequest.java new file mode 100644 index 00000000..dcc50dcb --- /dev/null +++ b/src/main/java/org/example/vet1177/dto/request/user/UserUpdateRequest.java @@ -0,0 +1,41 @@ +package org.example.vet1177.dto.request.user; + +import jakarta.validation.constraints.Email; +import jakarta.validation.constraints.Size; + +import java.util.UUID; + +public class UserUpdateRequest { + + @Size(min = 2, max = 100) + private String name; + + @Email + private String email; + + private UUID clinicId; + + public UUID getClinicId() { + return clinicId; + } + + public void setClinicId(UUID clinicId) { + this.clinicId = clinicId; + } + + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } +} \ No newline at end of file diff --git a/src/main/java/org/example/vet1177/services/UserService.java b/src/main/java/org/example/vet1177/services/UserService.java index b7aab848..c6427cc6 100644 --- a/src/main/java/org/example/vet1177/services/UserService.java +++ b/src/main/java/org/example/vet1177/services/UserService.java @@ -1,15 +1,18 @@ package org.example.vet1177.services; import org.example.vet1177.dto.request.user.UserRequest; +import org.example.vet1177.dto.request.user.UserUpdateRequest; import org.example.vet1177.dto.response.user.UserResponse; import org.example.vet1177.entities.Clinic; import org.example.vet1177.entities.Role; import org.example.vet1177.entities.User; import org.example.vet1177.exception.ResourceNotFoundException; +import org.example.vet1177.repository.ClinicRepository; import org.example.vet1177.repository.UserRepository; import org.springframework.stereotype.Service; + import java.util.List; import java.util.UUID; @@ -17,11 +20,12 @@ public class UserService { private final UserRepository userRepository; - private final ClinicService clinicService; + private final ClinicRepository clinicRepository; - public UserService(UserRepository userRepository, ClinicService clinicService){ + public UserService(UserRepository userRepository, + ClinicRepository clinicRepository){ this.userRepository = userRepository; - this.clinicService = clinicService; + this.clinicRepository = clinicRepository; } // TODO: Hasha lösenordet med BCrypt när Spring Security implementeras public UserResponse createUser(UserRequest request) { @@ -31,7 +35,7 @@ public UserResponse createUser(UserRequest request) { request.getEmail(), request.getPassword(), request.getRole()); - applyClinicRules(user, request); + applyClinicRules(user, request.getClinicId()); return mapToResponse(userRepository.save(user)); } @@ -64,13 +68,21 @@ public List getAllUsers() { } //Update user - public UserResponse updateUser(UUID id, UserRequest request) { + public UserResponse updateUser(UUID id, UserUpdateRequest request) { User user = userRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("User", id)); - validateEmailUniqueForUpdate(request.getEmail(), id); - user.setName(request.getName()); - user.setEmail(request.getEmail()); - applyClinicRules(user, request); + + if (request.getEmail() != null) { + validateEmailUniqueForUpdate(request.getEmail(), id); + user.setEmail(request.getEmail()); + } + + if (request.getName() != null) { + user.setName(request.getName()); + } + + applyClinicRules(user, request.getClinicId()); + return mapToResponse(userRepository.save(user)); } @@ -106,13 +118,15 @@ private void validateEmailUniqueForUpdate(String email, UUID userId) { } } - private void applyClinicRules(User user, UserRequest request) { - if (request.getRole() == Role.VET) { - if (request.getClinicId() == null) { + private void applyClinicRules(User user, UUID clinicId) { + if (user.getRole() == Role.VET) { + if (clinicId == null) { throw new IllegalArgumentException("Veterinär måste vara kopplad till en klinik"); } - Clinic clinic = clinicService.getById(request.getClinicId()); + Clinic clinic = clinicRepository.findById(clinicId) + .orElseThrow(() -> new ResourceNotFoundException("Clinic", clinicId)); + user.setClinic(clinic); } else { user.setClinic(null); From 934a2a233c25e3fc02859f173d1bcd647846bf7a Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Mon, 6 Apr 2026 11:21:32 +0200 Subject: [PATCH 12/17] fix: use BusinessRuleException instead of IllegalArgumentException in UserService --- .../vet1177/controller/UserController.java | 1 - .../example/vet1177/services/UserService.java | 25 ++++++++++++++----- 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/main/java/org/example/vet1177/controller/UserController.java b/src/main/java/org/example/vet1177/controller/UserController.java index 6fd3d797..39cc09ef 100644 --- a/src/main/java/org/example/vet1177/controller/UserController.java +++ b/src/main/java/org/example/vet1177/controller/UserController.java @@ -44,7 +44,6 @@ public ResponseEntity createUser(@Valid @RequestBody UserRequest r } //PUT /users/{id} - uppdatera användare - // PUT /users/{id} - uppdatera användare @PutMapping("/{id}") public ResponseEntity updateUser(@PathVariable UUID id, @Valid @RequestBody UserUpdateRequest request) { diff --git a/src/main/java/org/example/vet1177/services/UserService.java b/src/main/java/org/example/vet1177/services/UserService.java index c6427cc6..7d54b00a 100644 --- a/src/main/java/org/example/vet1177/services/UserService.java +++ b/src/main/java/org/example/vet1177/services/UserService.java @@ -6,6 +6,7 @@ import org.example.vet1177.entities.Clinic; import org.example.vet1177.entities.Role; import org.example.vet1177.entities.User; +import org.example.vet1177.exception.BusinessRuleException; import org.example.vet1177.exception.ResourceNotFoundException; import org.example.vet1177.repository.ClinicRepository; import org.example.vet1177.repository.UserRepository; @@ -81,7 +82,9 @@ public UserResponse updateUser(UUID id, UserUpdateRequest request) { user.setName(request.getName()); } - applyClinicRules(user, request.getClinicId()); + if (request.getClinicId() != null) { + applyClinicRulesForUpdate(user, request.getClinicId()); + } return mapToResponse(userRepository.save(user)); } @@ -108,28 +111,38 @@ private UserResponse mapToResponse(User user) { private void validateEmailUnique(String email) { if (userRepository.existsByEmail(email)) { - throw new IllegalArgumentException("Email används redan"); + throw new BusinessRuleException("Email används redan"); } } private void validateEmailUniqueForUpdate(String email, UUID userId) { if (userRepository.existsByEmailAndIdNot(email, userId)) { - throw new IllegalArgumentException("Email används redan"); + throw new BusinessRuleException("Email används redan"); } } + // Vid skapande — VET måste ha klinik, övriga får inte ha det private void applyClinicRules(User user, UUID clinicId) { if (user.getRole() == Role.VET) { if (clinicId == null) { - throw new IllegalArgumentException("Veterinär måste vara kopplad till en klinik"); + throw new BusinessRuleException("Veterinär måste vara kopplad till en klinik"); } - Clinic clinic = clinicRepository.findById(clinicId) .orElseThrow(() -> new ResourceNotFoundException("Clinic", clinicId)); - user.setClinic(clinic); } else { user.setClinic(null); } } + + // Vid uppdatering — klinik ändras bara om clinicId skickas med + private void applyClinicRulesForUpdate(User user, UUID clinicId) { + if (user.getRole() != Role.VET) { + throw new BusinessRuleException("Endast veterinärer kan kopplas till en klinik"); + } + Clinic clinic = clinicRepository.findById(clinicId) + .orElseThrow(() -> new ResourceNotFoundException("Clinic", clinicId)); + user.setClinic(clinic); + } + } From 0ccf7f1a32649cb87c3889e1aa49e2c48b720576 Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Mon, 6 Apr 2026 11:41:14 +0200 Subject: [PATCH 13/17] fix: hash passwords with BCrypt before persisting user --- pom.xml | 6 ++++++ .../org/example/vet1177/services/UserService.java | 12 +++++++++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/pom.xml b/pom.xml index 083ac4b6..79e872c3 100644 --- a/pom.xml +++ b/pom.xml @@ -86,6 +86,12 @@ s3 2.20.0 + + + org.springframework.security + spring-security-crypto + + diff --git a/src/main/java/org/example/vet1177/services/UserService.java b/src/main/java/org/example/vet1177/services/UserService.java index 7d54b00a..a1d66c64 100644 --- a/src/main/java/org/example/vet1177/services/UserService.java +++ b/src/main/java/org/example/vet1177/services/UserService.java @@ -10,6 +10,8 @@ import org.example.vet1177.exception.ResourceNotFoundException; import org.example.vet1177.repository.ClinicRepository; import org.example.vet1177.repository.UserRepository; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; @@ -19,7 +21,8 @@ @Service public class UserService { - + // TODO: Implementera Spring Security för autentisering och auktorisering + private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); private final UserRepository userRepository; private final ClinicRepository clinicRepository; @@ -28,13 +31,14 @@ public UserService(UserRepository userRepository, this.userRepository = userRepository; this.clinicRepository = clinicRepository; } - // TODO: Hasha lösenordet med BCrypt när Spring Security implementeras + public UserResponse createUser(UserRequest request) { validateEmailUnique(request.getEmail()); + String passwordHash = passwordEncoder.encode(request.getPassword()); User user = new User( request.getName(), request.getEmail(), - request.getPassword(), + passwordHash, request.getRole()); applyClinicRules(user, request.getClinicId()); return mapToResponse(userRepository.save(user)); @@ -145,4 +149,6 @@ private void applyClinicRulesForUpdate(User user, UUID clinicId) { user.setClinic(clinic); } + + } From 42110149f6e4c8acad3f43147ad8a2d7818c346b Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Mon, 6 Apr 2026 12:10:32 +0200 Subject: [PATCH 14/17] fix: block user deletion when referenced by pets or medical records --- .../repository/MedicalRecordRepository.java | 4 +++ .../vet1177/repository/PetRepository.java | 2 ++ .../example/vet1177/services/UserService.java | 30 ++++++++++++++++++- 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/main/java/org/example/vet1177/repository/MedicalRecordRepository.java b/src/main/java/org/example/vet1177/repository/MedicalRecordRepository.java index 9635d336..db8f424f 100644 --- a/src/main/java/org/example/vet1177/repository/MedicalRecordRepository.java +++ b/src/main/java/org/example/vet1177/repository/MedicalRecordRepository.java @@ -33,4 +33,8 @@ public interface MedicalRecordRepository extends JpaRepository findByAssignedVetId(UUID vetId); List findByStatus(RecordStatus status); boolean existsByPetIdAndClinicId(UUID petId, UUID clinicId); + boolean existsByOwnerId(UUID ownerId); + boolean existsByAssignedVetId(UUID vetId); + boolean existsByCreatedById(UUID userId); + boolean existsByUpdatedById(UUID userId); } \ No newline at end of file diff --git a/src/main/java/org/example/vet1177/repository/PetRepository.java b/src/main/java/org/example/vet1177/repository/PetRepository.java index 2be1c431..dd221448 100644 --- a/src/main/java/org/example/vet1177/repository/PetRepository.java +++ b/src/main/java/org/example/vet1177/repository/PetRepository.java @@ -15,4 +15,6 @@ public interface PetRepository extends JpaRepository { //hämta ett specifikt pet för en specifik owner Optional findByIdAndOwnerId(UUID petId, UUID ownerId); + + boolean existsByOwner_Id(UUID ownerId); } \ No newline at end of file diff --git a/src/main/java/org/example/vet1177/services/UserService.java b/src/main/java/org/example/vet1177/services/UserService.java index a1d66c64..c912214d 100644 --- a/src/main/java/org/example/vet1177/services/UserService.java +++ b/src/main/java/org/example/vet1177/services/UserService.java @@ -9,6 +9,8 @@ import org.example.vet1177.exception.BusinessRuleException; import org.example.vet1177.exception.ResourceNotFoundException; import org.example.vet1177.repository.ClinicRepository; +import org.example.vet1177.repository.MedicalRecordRepository; +import org.example.vet1177.repository.PetRepository; import org.example.vet1177.repository.UserRepository; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @@ -25,11 +27,17 @@ public class UserService { private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); private final UserRepository userRepository; private final ClinicRepository clinicRepository; + private final PetRepository petRepository; + private final MedicalRecordRepository medicalRecordRepository; public UserService(UserRepository userRepository, - ClinicRepository clinicRepository){ + ClinicRepository clinicRepository, + PetRepository petRepository, + MedicalRecordRepository medicalRecordRepository) { this.userRepository = userRepository; this.clinicRepository = clinicRepository; + this.petRepository = petRepository; + this.medicalRecordRepository = medicalRecordRepository; } public UserResponse createUser(UserRequest request) { @@ -97,6 +105,26 @@ public UserResponse updateUser(UUID id, UserUpdateRequest request) { public void deleteUser(UUID id) { User user = userRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("User", id)); + + if (petRepository.existsByOwner_Id(id)) { + throw new BusinessRuleException("Användaren har kopplade djur och kan inte raderas"); + } + if (petRepository.existsByOwner_Id(id)) { + throw new BusinessRuleException("Användaren har kopplade djur och kan inte raderas"); + } + if (medicalRecordRepository.existsByOwnerId(id)) { + throw new BusinessRuleException("Användaren är ägare på journalposter och kan inte raderas"); + } + if (medicalRecordRepository.existsByAssignedVetId(id)) { + throw new BusinessRuleException("Användaren är tilldelad veterinär på journalposter och kan inte raderas"); + } + if (medicalRecordRepository.existsByCreatedById(id)) { + throw new BusinessRuleException("Användaren har skapat journalposter och kan inte raderas"); + } + if (medicalRecordRepository.existsByUpdatedById(id)) { + throw new BusinessRuleException("Användaren har uppdaterat journalposter och kan inte raderas"); + } + userRepository.delete(user); } From 8dc07649c3a7f8c4bc26fe01ae822b6785f18ea3 Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Mon, 6 Apr 2026 13:27:10 +0200 Subject: [PATCH 15/17] fix: add unique DB constraint on email and handle concurrent duplicate key violations. reject clinicId for non-VET users on create --- .../example/vet1177/services/UserService.java | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/example/vet1177/services/UserService.java b/src/main/java/org/example/vet1177/services/UserService.java index c912214d..87440a79 100644 --- a/src/main/java/org/example/vet1177/services/UserService.java +++ b/src/main/java/org/example/vet1177/services/UserService.java @@ -12,6 +12,7 @@ import org.example.vet1177.repository.MedicalRecordRepository; import org.example.vet1177.repository.PetRepository; import org.example.vet1177.repository.UserRepository; +import org.springframework.dao.DataIntegrityViolationException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.stereotype.Service; @@ -49,7 +50,11 @@ public UserResponse createUser(UserRequest request) { passwordHash, request.getRole()); applyClinicRules(user, request.getClinicId()); - return mapToResponse(userRepository.save(user)); + try { + return mapToResponse(userRepository.save(user)); + } catch (DataIntegrityViolationException e) { + throw new BusinessRuleException("Email används redan"); + } } // TODO: GET /users/search?email= - Sök användare på email, kräver ADMIN-roll (implementera när Spring Security är på plats) @@ -97,8 +102,11 @@ public UserResponse updateUser(UUID id, UserUpdateRequest request) { if (request.getClinicId() != null) { applyClinicRulesForUpdate(user, request.getClinicId()); } - - return mapToResponse(userRepository.save(user)); + try { + return mapToResponse(userRepository.save(user)); + } catch (DataIntegrityViolationException e) { + throw new BusinessRuleException("Email används redan"); + } } //Delete user @@ -163,8 +171,11 @@ private void applyClinicRules(User user, UUID clinicId) { .orElseThrow(() -> new ResourceNotFoundException("Clinic", clinicId)); user.setClinic(clinic); } else { - user.setClinic(null); + if (clinicId != null) { + throw new BusinessRuleException("Endast veterinärer kan kopplas till en klinik"); } + user.setClinic(null); + } } // Vid uppdatering — klinik ändras bara om clinicId skickas med From a97112af648237187e222a30df64225fbc12d8a8 Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Mon, 6 Apr 2026 17:27:39 +0200 Subject: [PATCH 16/17] fix: remove duplicate pet ownership check in deleteUser --- .../java/org/example/vet1177/services/UserService.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/java/org/example/vet1177/services/UserService.java b/src/main/java/org/example/vet1177/services/UserService.java index 87440a79..23edc553 100644 --- a/src/main/java/org/example/vet1177/services/UserService.java +++ b/src/main/java/org/example/vet1177/services/UserService.java @@ -114,9 +114,6 @@ public void deleteUser(UUID id) { User user = userRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("User", id)); - if (petRepository.existsByOwner_Id(id)) { - throw new BusinessRuleException("Användaren har kopplade djur och kan inte raderas"); - } if (petRepository.existsByOwner_Id(id)) { throw new BusinessRuleException("Användaren har kopplade djur och kan inte raderas"); } @@ -133,7 +130,11 @@ public void deleteUser(UUID id) { throw new BusinessRuleException("Användaren har uppdaterat journalposter och kan inte raderas"); } - userRepository.delete(user); + try { + userRepository.delete(user); + } catch (DataIntegrityViolationException e) { + throw new BusinessRuleException("Användaren kan inte raderas på grund av kopplade poster"); + } } //Helper From 41cd3b4239097de4b8cfddfac718aa51f5738c5f Mon Sep 17 00:00:00 2001 From: Linda Eskilsson Date: Mon, 6 Apr 2026 17:31:11 +0200 Subject: [PATCH 17/17] fix: resolve pom.xml merge conflict, remove redundant spring-security-crypto dependency --- pom.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/pom.xml b/pom.xml index 79e872c3..083ac4b6 100644 --- a/pom.xml +++ b/pom.xml @@ -86,12 +86,6 @@ s3 2.20.0 - - - org.springframework.security - spring-security-crypto - -