From 8304ccba7e54b2a0f6bdd98c1e27ba749866759a Mon Sep 17 00:00:00 2001 From: Annika Holmqvist Date: Tue, 7 Apr 2026 11:13:03 +0200 Subject: [PATCH 1/9] feat: add logging to VetController and VetService - Introduced `SLF4J` logging for key actions in `VetController` (e.g., endpoints: `create`, `getAll`, `getById`) and `VetService` (e.g., methods: `createVet`, `getAllVets`, `getVetById`). - Enhanced traceability and debugging capabilities by logging request details and actions. --- .../java/org/example/vet1177/controller/VetController.java | 7 +++++++ src/main/java/org/example/vet1177/services/VetService.java | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/src/main/java/org/example/vet1177/controller/VetController.java b/src/main/java/org/example/vet1177/controller/VetController.java index b73aa76..befc856 100644 --- a/src/main/java/org/example/vet1177/controller/VetController.java +++ b/src/main/java/org/example/vet1177/controller/VetController.java @@ -7,6 +7,8 @@ import org.example.vet1177.entities.User; import org.example.vet1177.policy.AdminPolicy; import org.example.vet1177.services.VetService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; @@ -19,6 +21,8 @@ @RequestMapping("/api/vets") public class VetController { + private static final Logger log = LoggerFactory.getLogger(VetController.class); + private final VetService vetService; private final AdminPolicy adminPolicy; @@ -31,6 +35,7 @@ public VetController(VetService vetService, AdminPolicy adminPolicy) { public ResponseEntity createVet( @AuthenticationPrincipal User user, @Valid @RequestBody VetRequest request) { + log.info("POST /api/vets - creating vet"); adminPolicy.requireAdmin(user); VetResponse response = vetService.createVet(request); return new ResponseEntity<>(response, HttpStatus.CREATED); @@ -38,12 +43,14 @@ public ResponseEntity createVet( @GetMapping public ResponseEntity> getAllVets() { + log.info("GET /api/vets"); List response = vetService.getAllVets(); return ResponseEntity.ok(response); } @GetMapping("/{id}") public ResponseEntity getVetById(@PathVariable UUID id) { + log.info("GET /api/vets/{}", id); VetResponse response = vetService.getVetById(id); return ResponseEntity.ok(response); } diff --git a/src/main/java/org/example/vet1177/services/VetService.java b/src/main/java/org/example/vet1177/services/VetService.java index 552a36a..ef08c7a 100644 --- a/src/main/java/org/example/vet1177/services/VetService.java +++ b/src/main/java/org/example/vet1177/services/VetService.java @@ -9,6 +9,8 @@ import org.example.vet1177.exception.ResourceNotFoundException; import org.example.vet1177.repository.UserRepository; import org.example.vet1177.repository.VetRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -19,6 +21,8 @@ @Transactional public class VetService { + private static final Logger log = LoggerFactory.getLogger(VetService.class); + private final VetRepository vetRepository; private final UserRepository userRepository; @@ -29,6 +33,7 @@ public VetService(VetRepository vetRepository, UserRepository userRepository) { public VetResponse createVet(VetRequest request) { + log.info("Creating vet userId={}", request.userId()); User user = userRepository.findById(request.userId()) .orElseThrow(() -> new ResourceNotFoundException("User", request.userId())); @@ -63,12 +68,14 @@ public VetResponse createVet(VetRequest request) { @Transactional(readOnly = true) public List getAllVets() { + log.debug("Fetching all vets"); return vetRepository.findAll().stream().map(VetResponse::from).toList(); } @Transactional(readOnly = true) public VetResponse getVetById(UUID userId) { + log.debug("Fetching vet id={}", userId); return vetRepository.findById(userId).map(VetResponse::from) .orElseThrow(() -> new ResourceNotFoundException("Vet", userId)); } From 9364b9a51e0c578f99131671481c1eb4c89113fd Mon Sep 17 00:00:00 2001 From: Annika Holmqvist Date: Tue, 7 Apr 2026 11:13:13 +0200 Subject: [PATCH 2/9] feat: add logging to PetController and PetService - Introduced `SLF4J` logging in `PetController` and `PetService` for key actions (create, read, update, delete). - Improved traceability and debugging by logging request details and method activities. --- .../org/example/vet1177/controller/PetController.java | 5 +++++ .../java/org/example/vet1177/services/PetService.java | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/org/example/vet1177/controller/PetController.java b/src/main/java/org/example/vet1177/controller/PetController.java index 191088e..ab75041 100644 --- a/src/main/java/org/example/vet1177/controller/PetController.java +++ b/src/main/java/org/example/vet1177/controller/PetController.java @@ -5,6 +5,8 @@ import org.example.vet1177.dto.response.pet.PetResponse; import org.example.vet1177.entities.Pet; import org.example.vet1177.services.PetService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.*; import java.util.UUID; @@ -13,6 +15,8 @@ @RequestMapping("/pets") public class PetController { + private static final Logger log = LoggerFactory.getLogger(PetController.class); + private final PetService petService; public PetController(PetService petService) { @@ -26,6 +30,7 @@ public PetResponse createPet( @RequestParam(required = false) UUID ownerId, @Valid @RequestBody PetRequest request ) { + log.info("POST /pets - creating pet for currentUserId={} ownerId={}", currentUserId, ownerId); Pet saved = petService.createPet(currentUserId, ownerId, request); return new PetResponse( diff --git a/src/main/java/org/example/vet1177/services/PetService.java b/src/main/java/org/example/vet1177/services/PetService.java index d086a01..d9d13ba 100644 --- a/src/main/java/org/example/vet1177/services/PetService.java +++ b/src/main/java/org/example/vet1177/services/PetService.java @@ -9,6 +9,8 @@ import org.example.vet1177.repository.MedicalRecordRepository; import org.example.vet1177.repository.PetRepository; import org.example.vet1177.repository.UserRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.stereotype.Service; @@ -19,6 +21,7 @@ @Service public class PetService { + private static final Logger log = LoggerFactory.getLogger(PetService.class); private final PetRepository petRepository; private final UserRepository userRepository; @@ -37,6 +40,7 @@ public PetService(PetRepository petRepository, // CREATE - OWNER kan skapa för sig själv, ADMIN kan skapa för en OWNER via ownerId. public Pet createPet(UUID currentUserId, UUID ownerId, PetRequest request) { + log.info("Creating pet currentUserId={} ownerId={}", currentUserId, ownerId); User currentUser = getUserById(currentUserId); if (!petPolicy.canCreate(currentUser)) { @@ -67,6 +71,7 @@ public Pet createPet(UUID currentUserId, UUID ownerId, PetRequest request) { // READ // - Måste vara ADMIN eller OWNER för att se pet public Pet getPetById(UUID petId, User currentUser) { + log.debug("Fetching pet id={}", petId); Pet pet = petRepository.findById(petId) .orElseThrow(() -> new RuntimeException("Pet not found")); @@ -91,6 +96,7 @@ public Pet getPetById(UUID petId, User currentUser) { // Lista djur som tillhör ägaren public List getPetsByOwner(UUID currentUserId, UUID ownerId) { + log.debug("Fetching pets ownerId={}", ownerId); User currentUser = getUserById(currentUserId); if (!petPolicy.canViewOwnerPets(currentUser, ownerId)){ throw new RuntimeException("Du saknar behörighet"); @@ -100,6 +106,7 @@ public List getPetsByOwner(UUID currentUserId, UUID ownerId) { // UPDATE public Pet updatePet(UUID currentUserId, UUID petId, PetRequest request) { + log.info("Updating pet id={}", petId); User currentUser = getUserById(currentUserId); Pet existingPet = getPetByIdOrThrow(petId); @@ -120,6 +127,7 @@ public Pet updatePet(UUID currentUserId, UUID petId, PetRequest request) { // DELETE @Transactional public void deletePet(UUID petId, User currentUser) { + log.info("Deleting pet id={}", petId); Pet pet = petRepository.findById(petId) .orElseThrow(() -> new RuntimeException("Djuret finns inte")); From 50391fda0b9488426a0de42dc3129db17388a949 Mon Sep 17 00:00:00 2001 From: Annika Holmqvist Date: Tue, 7 Apr 2026 11:13:19 +0200 Subject: [PATCH 3/9] feat: add logging to UserController and UserService - Introduced `SLF4J` logging in `UserController` and `UserService` for key actions (create, read, update, delete). - Enhanced traceability and debugging by logging request details and method activities. --- .../vet1177/controller/UserController.java | 9 +++++++++ .../example/vet1177/services/UserService.java | 17 +++++++++++++++++ 2 files changed, 26 insertions(+) diff --git a/src/main/java/org/example/vet1177/controller/UserController.java b/src/main/java/org/example/vet1177/controller/UserController.java index 39cc09e..3c227e6 100644 --- a/src/main/java/org/example/vet1177/controller/UserController.java +++ b/src/main/java/org/example/vet1177/controller/UserController.java @@ -4,6 +4,8 @@ import org.example.vet1177.dto.request.user.UserRequest; import org.example.vet1177.dto.response.user.UserResponse; import org.example.vet1177.services.UserService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -16,6 +18,8 @@ @RequestMapping("/api/users") public class UserController { + private static final Logger log = LoggerFactory.getLogger(UserController.class); + private final UserService userService; public UserController(UserService userService) { @@ -25,6 +29,7 @@ public UserController(UserService userService) { //GET /users- Hämta alla användare @GetMapping public ResponseEntity> getAllUsers() { + log.info("GET /api/users"); List users = userService.getAllUsers(); return ResponseEntity.ok(users); } @@ -32,6 +37,7 @@ public ResponseEntity> getAllUsers() { // GET /users/{id}- Hämta 1 användare @GetMapping("/{id}") public ResponseEntity getUserById(@PathVariable UUID id) { + log.info("GET /api/users/{}", id); UserResponse user = userService.getById(id); return ResponseEntity.ok(user); } @@ -39,6 +45,7 @@ public ResponseEntity getUserById(@PathVariable UUID id) { //POST /users - skapa ny användare @PostMapping public ResponseEntity createUser(@Valid @RequestBody UserRequest request) { + log.info("POST /api/users - creating user"); UserResponse user = userService.createUser(request); return ResponseEntity.status(HttpStatus.CREATED).body(user); } @@ -47,6 +54,7 @@ public ResponseEntity createUser(@Valid @RequestBody UserRequest r @PutMapping("/{id}") public ResponseEntity updateUser(@PathVariable UUID id, @Valid @RequestBody UserUpdateRequest request) { + log.info("PUT /api/users/{}", id); UserResponse user = userService.updateUser(id, request); return ResponseEntity.ok(user); } @@ -54,6 +62,7 @@ public ResponseEntity updateUser(@PathVariable UUID id, //DELETE /users/{id} - Tar bort användare @DeleteMapping("/{id}") public ResponseEntity deleteUser(@PathVariable UUID id) { + log.info("DELETE /api/users/{}", 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 23edc55..f972c09 100644 --- a/src/main/java/org/example/vet1177/services/UserService.java +++ b/src/main/java/org/example/vet1177/services/UserService.java @@ -12,6 +12,8 @@ import org.example.vet1177.repository.MedicalRecordRepository; import org.example.vet1177.repository.PetRepository; import org.example.vet1177.repository.UserRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.dao.DataIntegrityViolationException; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; @@ -24,6 +26,9 @@ @Service public class UserService { + + private static final Logger log = LoggerFactory.getLogger(UserService.class); + // TODO: Implementera Spring Security för autentisering och auktorisering private final PasswordEncoder passwordEncoder = new BCryptPasswordEncoder(); private final UserRepository userRepository; @@ -50,21 +55,25 @@ public UserResponse createUser(UserRequest request) { passwordHash, request.getRole()); applyClinicRules(user, request.getClinicId()); + log.info("Creating user with email={}", request.getEmail()); try { return mapToResponse(userRepository.save(user)); } catch (DataIntegrityViolationException e) { + log.warn("Duplicate email on create: {}", request.getEmail()); 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) public User getByEmail(String email){ + log.debug("Fetching user by email={}", 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) { + log.debug("Fetching user entity id={}", id); return userRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("User", id)); } @@ -72,6 +81,7 @@ public User getUserEntityById(UUID id) { // 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) { + log.debug("Fetching user id={}", id); User user = userRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("User", id)); return mapToResponse(user); @@ -79,6 +89,7 @@ public UserResponse getById(UUID id) { //Get all users public List getAllUsers() { + log.debug("Fetching all users"); return userRepository.findAll() .stream() .map(this::mapToResponse) @@ -87,6 +98,7 @@ public List getAllUsers() { //Update user public UserResponse updateUser(UUID id, UserUpdateRequest request) { + log.debug("Updating user id={}", id); User user = userRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("User", id)); @@ -102,15 +114,18 @@ public UserResponse updateUser(UUID id, UserUpdateRequest request) { if (request.getClinicId() != null) { applyClinicRulesForUpdate(user, request.getClinicId()); } + log.info("Updated user id={}", id); try { return mapToResponse(userRepository.save(user)); } catch (DataIntegrityViolationException e) { + log.warn("Duplicate email on update id={}", id); throw new BusinessRuleException("Email används redan"); } } //Delete user public void deleteUser(UUID id) { + log.debug("Deleting user id={}", id); User user = userRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("User", id)); @@ -132,7 +147,9 @@ public void deleteUser(UUID id) { try { userRepository.delete(user); + log.info("Deleted user id={}", id); } catch (DataIntegrityViolationException e) { + log.warn("Cannot delete user id={} due to related records", id); throw new BusinessRuleException("Användaren kan inte raderas på grund av kopplade poster"); } } From a54e35922bb9efddc70126c2c57cea39a10a6c43 Mon Sep 17 00:00:00 2001 From: Annika Holmqvist Date: Tue, 7 Apr 2026 11:13:25 +0200 Subject: [PATCH 4/9] feat: add logging to ClinicController and ClinicService - Introduced `SLF4J` logging in `ClinicController` and `ClinicService` for key actions (create, read, update, delete). - Enhanced traceability and debugging by logging request details and method activities. --- .../org/example/vet1177/controller/ClinicController.java | 9 +++++++++ .../java/org/example/vet1177/services/ClinicService.java | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/main/java/org/example/vet1177/controller/ClinicController.java b/src/main/java/org/example/vet1177/controller/ClinicController.java index f1a2b77..3edefde 100644 --- a/src/main/java/org/example/vet1177/controller/ClinicController.java +++ b/src/main/java/org/example/vet1177/controller/ClinicController.java @@ -5,6 +5,8 @@ import org.example.vet1177.dto.request.clinic.UpdateClinicRequest; import org.example.vet1177.dto.response.clinic.ClinicResponse; import org.example.vet1177.services.ClinicService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -15,6 +17,8 @@ @RequestMapping("/api/clinics") public class ClinicController { + private static final Logger log = LoggerFactory.getLogger(ClinicController.class); + private final ClinicService clinicService; public ClinicController(ClinicService clinicService) { @@ -26,6 +30,7 @@ public ClinicController(ClinicService clinicService) { public ResponseEntity create( @Valid @RequestBody CreateClinicRequest request) { + log.info("POST /api/clinics - creating clinic"); return ResponseEntity.ok( ClinicResponse.from( clinicService.create( @@ -40,6 +45,7 @@ public ResponseEntity create( // READ ALL @GetMapping public ResponseEntity> getAll() { + log.info("GET /api/clinics"); return ResponseEntity.ok( clinicService.getAll() .stream() @@ -51,6 +57,7 @@ public ResponseEntity> getAll() { // READ ONE @GetMapping("/{id}") public ResponseEntity getById(@PathVariable UUID id) { + log.info("GET /api/clinics/{}", id); return ResponseEntity.ok( ClinicResponse.from( clinicService.getById(id) @@ -64,6 +71,7 @@ public ResponseEntity update( @PathVariable UUID id, @Valid @RequestBody UpdateClinicRequest request) { + log.info("PUT /api/clinics/{}", id); return ResponseEntity.ok( ClinicResponse.from( clinicService.update( @@ -79,6 +87,7 @@ public ResponseEntity update( // DELETE @DeleteMapping("/{id}") public ResponseEntity delete(@PathVariable UUID id) { + log.info("DELETE /api/clinics/{}", id); clinicService.delete(id); return ResponseEntity.noContent().build(); } diff --git a/src/main/java/org/example/vet1177/services/ClinicService.java b/src/main/java/org/example/vet1177/services/ClinicService.java index 87214be..70d4ad6 100644 --- a/src/main/java/org/example/vet1177/services/ClinicService.java +++ b/src/main/java/org/example/vet1177/services/ClinicService.java @@ -3,6 +3,8 @@ import org.example.vet1177.entities.Clinic; import org.example.vet1177.exception.ResourceNotFoundException; import org.example.vet1177.repository.ClinicRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -13,6 +15,8 @@ @Transactional public class ClinicService { + private static final Logger log = LoggerFactory.getLogger(ClinicService.class); + private final ClinicRepository clinicRepository; public ClinicService(ClinicRepository clinicRepository){ @@ -21,6 +25,7 @@ public ClinicService(ClinicRepository clinicRepository){ //Skapa public Clinic create(String name, String address, String phoneNumber){ + log.info("Creating clinic name={}", name); Clinic clinic = new Clinic(name, address, phoneNumber); return clinicRepository.save(clinic); } @@ -28,17 +33,20 @@ public Clinic create(String name, String address, String phoneNumber){ // Läsa @Transactional(readOnly = true) public List getAll(){ + log.debug("Fetching all clinics"); return clinicRepository.findAll(); } @Transactional(readOnly = true) public Clinic getById(UUID id){ + log.debug("Fetching clinic id={}", id); return clinicRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("Clinic", id)); } // Uppdatera public Clinic update(UUID id, String name, String address, String phoneNumber){ + log.info("Updating clinic id={}", id); Clinic clinic = getById(id); clinic.setName(name); @@ -50,6 +58,7 @@ public Clinic update(UUID id, String name, String address, String phoneNumber){ //Ta bort public void delete(UUID id){ + log.info("Deleting clinic id={}", id); Clinic clinic = getById(id); clinicRepository.delete(clinic); } From 90a51fe83d62c57a965d2a160d1d3fb107e7609e Mon Sep 17 00:00:00 2001 From: Annika Holmqvist Date: Tue, 7 Apr 2026 11:13:37 +0200 Subject: [PATCH 5/9] feat: add logging to MedicalRecordController and MedicalRecordService - Introduced `SLF4J` logging in `MedicalRecordController` and `MedicalRecordService` for key actions (create, read, update, delete). - Enhanced traceability and debugging by logging request details and method activities. --- .../controller/MedicalRecordController.java | 15 +++++++++++++++ .../vet1177/services/MedicalRecordService.java | 16 ++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/main/java/org/example/vet1177/controller/MedicalRecordController.java b/src/main/java/org/example/vet1177/controller/MedicalRecordController.java index 00d54f2..e17ee2d 100644 --- a/src/main/java/org/example/vet1177/controller/MedicalRecordController.java +++ b/src/main/java/org/example/vet1177/controller/MedicalRecordController.java @@ -5,6 +5,8 @@ import org.example.vet1177.policy.MedicalRecordPolicy; import org.example.vet1177.services.MedicalRecordService; import org.example.vet1177.services.UserService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.http.ResponseEntity; import org.example.vet1177.dto.request.medicalrecord.*; import org.example.vet1177.dto.response.medicalrecord.*; @@ -20,6 +22,8 @@ @RequestMapping("/api/medical-records") public class MedicalRecordController { + private static final Logger log = LoggerFactory.getLogger(MedicalRecordController.class); + private final MedicalRecordService medicalRecordService; private final MedicalRecordPolicy medicalRecordPolicy; private final UserService userService; @@ -40,6 +44,7 @@ public ResponseEntity create( @Valid @RequestBody CreateMedicalRecordRequest request, @AuthenticationPrincipal User currentUser) { + log.info("POST /api/medical-records - creating record for petId={}", request.petId()); return ResponseEntity.ok( MedicalRecordResponse.from( medicalRecordService.create( @@ -60,6 +65,7 @@ public ResponseEntity getById( @PathVariable UUID id, @AuthenticationPrincipal User currentUser) { + log.info("GET /api/medical-records/{}", id); MedicalRecord record = medicalRecordService.getById(id); medicalRecordPolicy.canView(currentUser, record); return ResponseEntity.ok(MedicalRecordResponse.from(record)); @@ -71,6 +77,7 @@ public ResponseEntity getById( public ResponseEntity> getMyRecords( @AuthenticationPrincipal User currentUser) { + log.info("GET /api/medical-records/my-records"); if (currentUser.getRole() != Role.OWNER) { throw new ForbiddenException("Endast djurägare kan se sina egna ärenden"); } @@ -90,6 +97,7 @@ public ResponseEntity> getByOwner( @PathVariable UUID ownerId, @AuthenticationPrincipal User currentUser) { + log.info("GET /api/medical-records/owner/{}", ownerId); if (currentUser.getRole() == Role.OWNER && !currentUser.getId().equals(ownerId)) { throw new ForbiddenException("Du kan bara se dina egna ärenden"); @@ -111,6 +119,7 @@ public ResponseEntity> getByPet( @PathVariable UUID petId, @AuthenticationPrincipal User currentUser) { + log.info("GET /api/medical-records/pet/{}", petId); return ResponseEntity.ok( medicalRecordService.getByPetAllowedForUser(petId, currentUser) .stream() @@ -126,6 +135,7 @@ public ResponseEntity> getByClinic( @PathVariable UUID clinicId, @AuthenticationPrincipal User currentUser) { + log.info("GET /api/medical-records/clinic/{}", clinicId); medicalRecordPolicy.canViewClinic(currentUser, clinicId); return ResponseEntity.ok( medicalRecordService.getByClinic(clinicId) @@ -143,6 +153,7 @@ public ResponseEntity> getByClinicAndStatus( @PathVariable RecordStatus status, @AuthenticationPrincipal User currentUser) { + log.info("GET /api/medical-records/clinic/{}/status/{}", clinicId, status); medicalRecordPolicy.canViewClinic(currentUser, clinicId); return ResponseEntity.ok( medicalRecordService.getByClinicAndStatus(clinicId, status) @@ -160,6 +171,7 @@ public ResponseEntity update( @Valid @RequestBody UpdateMedicalRecordRequest request, @AuthenticationPrincipal User currentUser) { + log.info("PUT /api/medical-records/{}", id); MedicalRecord record = medicalRecordService.getById(id); medicalRecordPolicy.canUpdate(currentUser, record); @@ -183,6 +195,7 @@ public ResponseEntity assignVet( @Valid @RequestBody AssignVetRequest request, @AuthenticationPrincipal User currentUser) { + log.info("PUT /api/medical-records/{}/assign-vet vetId={}", id, request.vetId()); MedicalRecord record = medicalRecordService.getById(id); User vetToAssign = userService.getUserEntityById(request.vetId()); medicalRecordPolicy.canAssignVet(currentUser, record, vetToAssign); @@ -202,6 +215,7 @@ public ResponseEntity updateStatus( @Valid @RequestBody UpdateStatusRequest request, @AuthenticationPrincipal User currentUser) { + log.info("PUT /api/medical-records/{}/status status={}", id, request.status()); MedicalRecord record = medicalRecordService.getById(id); medicalRecordPolicy.canUpdateStatus(currentUser, record, request.status()); @@ -223,6 +237,7 @@ public ResponseEntity close( @PathVariable UUID id, @AuthenticationPrincipal User currentUser) { + log.info("PUT /api/medical-records/{}/close", id); MedicalRecord record = medicalRecordService.getById(id); medicalRecordPolicy.canClose(currentUser, record); diff --git a/src/main/java/org/example/vet1177/services/MedicalRecordService.java b/src/main/java/org/example/vet1177/services/MedicalRecordService.java index 19fc6c0..71bd2b2 100644 --- a/src/main/java/org/example/vet1177/services/MedicalRecordService.java +++ b/src/main/java/org/example/vet1177/services/MedicalRecordService.java @@ -7,6 +7,8 @@ import org.example.vet1177.repository.ClinicRepository; import org.example.vet1177.repository.MedicalRecordRepository; import org.example.vet1177.repository.PetRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -18,6 +20,8 @@ @Transactional public class MedicalRecordService { + private static final Logger log = LoggerFactory.getLogger(MedicalRecordService.class); + private final MedicalRecordRepository medicalRecordRepository; private final PetRepository petRepository; private final ClinicRepository clinicRepository; @@ -45,6 +49,7 @@ public MedicalRecord create( UUID clinicId, User currentUser) { + log.info("Creating medical record petId={} clinicId={}", petId, clinicId); Pet pet = petRepository.findById(petId) .orElseThrow(() -> new ResourceNotFoundException("Pet", petId)); @@ -80,32 +85,38 @@ public MedicalRecord create( @Transactional(readOnly = true) public MedicalRecord getById(UUID id) { + log.debug("Fetching medical record id={}", id); return medicalRecordRepository.findById(id) .orElseThrow(() -> new ResourceNotFoundException("MedicalRecord", id)); // ← rad 49 } @Transactional(readOnly = true) public List getByPet(UUID petId) { + log.debug("Fetching medical records petId={}", petId); return medicalRecordRepository.findByPetId(petId); } @Transactional(readOnly = true) public List getByOwner(UUID ownerId) { + log.debug("Fetching medical records ownerId={}", ownerId); return medicalRecordRepository.findByOwnerId(ownerId); } @Transactional(readOnly = true) public List getByClinic(UUID clinicId) { + log.debug("Fetching medical records clinicId={}", clinicId); return medicalRecordRepository.findByClinicId(clinicId); } @Transactional(readOnly = true) public List getByClinicAndStatus(UUID clinicId, RecordStatus status) { + log.debug("Fetching medical records clinicId={} status={}", clinicId, status); return medicalRecordRepository.findByClinicIdAndStatus(clinicId, status); } @Transactional(readOnly = true) public List getByPetAllowedForUser(UUID petId, User currentUser) { + log.debug("Fetching allowed medical records petId={}", petId); List all = medicalRecordRepository.findByPetId(petId); return all.stream() @@ -115,6 +126,7 @@ public List getByPetAllowedForUser(UUID petId, User currentUser) @Transactional(readOnly = true) public List getByOwnerAllowedForUser(UUID ownerId, User currentUser) { + log.debug("Fetching allowed medical records ownerId={}", ownerId); List all = medicalRecordRepository.findByOwnerId(ownerId); return all.stream() @@ -125,6 +137,7 @@ public List getByOwnerAllowedForUser(UUID ownerId, User currentUs // ── Uppdatera ───────────────────────────────────────────── public MedicalRecord update(UUID id, String title, String description, User updatedBy) { + log.info("Updating medical record id={}", id); MedicalRecord record = getById(id); if (record.getStatus().isFinal()) { @@ -150,6 +163,7 @@ public MedicalRecord update(UUID id, String title, String description, User upda } public MedicalRecord assignVet(UUID recordId, User vetToAssign, User updatedBy) { + log.info("Assigning vet id={} to record id={}", vetToAssign.getId(), recordId); MedicalRecord record = getById(recordId); if (record.getStatus().isFinal()) { throw new BusinessRuleException( @@ -183,6 +197,7 @@ public MedicalRecord assignVet(UUID recordId, User vetToAssign, User updatedBy) } public MedicalRecord updateStatus(UUID recordId, RecordStatus newStatus, User updatedBy) { + log.info("Updating status of record id={} to {}", recordId, newStatus); MedicalRecord record = getById(recordId); if (record.getStatus().isFinal()) { @@ -213,6 +228,7 @@ public MedicalRecord updateStatus(UUID recordId, RecordStatus newStatus, User up // ── Stänga ──────────────────────────────────────────────── public MedicalRecord close(UUID recordId, User closedBy) { + log.info("Closing medical record id={}", recordId); MedicalRecord record = getById(recordId); if (record.getStatus().isFinal()) { // ← rad 108 From 0eaf11e922461eca357b5b105770605b9f1db905 Mon Sep 17 00:00:00 2001 From: Annika Holmqvist Date: Tue, 7 Apr 2026 11:13:45 +0200 Subject: [PATCH 6/9] feat: add logging to CommentController and CommentService - Introduced `SLF4J` logging in `CommentController` and `CommentService` for key actions (create, read, update, delete, count). - Enhanced traceability and debugging by logging request details and method activities. --- .../example/vet1177/controller/CommentController.java | 9 +++++++++ .../org/example/vet1177/services/CommentService.java | 9 +++++++++ 2 files changed, 18 insertions(+) diff --git a/src/main/java/org/example/vet1177/controller/CommentController.java b/src/main/java/org/example/vet1177/controller/CommentController.java index 57cbe75..f481783 100644 --- a/src/main/java/org/example/vet1177/controller/CommentController.java +++ b/src/main/java/org/example/vet1177/controller/CommentController.java @@ -6,6 +6,8 @@ import org.example.vet1177.dto.response.comment.CommentResponse; import org.example.vet1177.entities.User; import org.example.vet1177.services.CommentService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.http.ResponseEntity; import org.springframework.security.core.annotation.AuthenticationPrincipal; import org.springframework.transaction.annotation.Transactional; @@ -18,6 +20,8 @@ @RequestMapping("/api/comments") public class CommentController { + private static final Logger log = LoggerFactory.getLogger(CommentController.class); + private final CommentService commentService; public CommentController(CommentService commentService) { @@ -31,6 +35,7 @@ public ResponseEntity create( @Valid @RequestBody CreateCommentRequest request, @AuthenticationPrincipal User currentUser) { + log.info("POST /api/comments recordId={}", request.recordId()); return ResponseEntity.ok( CommentResponse.from( commentService.create( @@ -49,6 +54,7 @@ public ResponseEntity> getByRecord( @PathVariable UUID recordId, @AuthenticationPrincipal User currentUser) { + log.info("GET /api/comments/record/{}", recordId); return ResponseEntity.ok( commentService.getByRecord(recordId, currentUser) .stream() @@ -65,6 +71,7 @@ public ResponseEntity update( @Valid @RequestBody UpdateCommentRequest request, @AuthenticationPrincipal User currentUser) { + log.info("PUT /api/comments/{}", id); return ResponseEntity.ok( CommentResponse.from( commentService.update(id, request.body(), currentUser) @@ -78,6 +85,7 @@ public ResponseEntity delete( @PathVariable UUID id, @AuthenticationPrincipal User currentUser) { + log.info("DELETE /api/comments/{}", id); commentService.delete(id, currentUser); return ResponseEntity.noContent().build(); } @@ -88,6 +96,7 @@ public ResponseEntity delete( public ResponseEntity countByRecord( @PathVariable UUID recordId, @AuthenticationPrincipal User currentUser) { + log.info("GET /api/comments/record/{}/count", recordId); return ResponseEntity.ok( commentService.countByRecord(recordId, currentUser) ); diff --git a/src/main/java/org/example/vet1177/services/CommentService.java b/src/main/java/org/example/vet1177/services/CommentService.java index 8d86d04..a378ab8 100644 --- a/src/main/java/org/example/vet1177/services/CommentService.java +++ b/src/main/java/org/example/vet1177/services/CommentService.java @@ -5,6 +5,8 @@ import org.example.vet1177.policy.CommentPolicy; import org.example.vet1177.repository.CommentRepository; import org.example.vet1177.repository.MedicalRecordRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; @@ -15,6 +17,8 @@ @Transactional public class CommentService { + private static final Logger log = LoggerFactory.getLogger(CommentService.class); + private final CommentRepository commentRepository; private final MedicalRecordRepository medicalRecordRepository; private final CommentPolicy commentPolicy; @@ -32,6 +36,7 @@ public CommentService( } public Comment create(UUID recordId, String body, User currentUser) { + log.info("Creating comment recordId={}", recordId); MedicalRecord record = medicalRecordRepository.findById(recordId) .orElseThrow(() -> new ResourceNotFoundException("MedicalRecord", recordId)); @@ -56,6 +61,7 @@ public Comment create(UUID recordId, String body, User currentUser) { @Transactional(readOnly = true) public List getByRecord(UUID recordId, User currentUser) { + log.debug("Fetching comments recordId={}", recordId); MedicalRecord record = medicalRecordRepository.findById(recordId) .orElseThrow(() -> new ResourceNotFoundException("MedicalRecord", recordId)); @@ -65,6 +71,7 @@ public List getByRecord(UUID recordId, User currentUser) { } public Comment update(UUID commentId, String body, User currentUser) { + log.info("Updating comment id={}", commentId); Comment comment = commentRepository.findById(commentId) .orElseThrow(() -> new ResourceNotFoundException("Comment", commentId)); @@ -86,6 +93,7 @@ public Comment update(UUID commentId, String body, User currentUser) { } public void delete(UUID commentId, User currentUser) { + log.info("Deleting comment id={}", commentId); Comment comment = commentRepository.findById(commentId) .orElseThrow(() -> new ResourceNotFoundException("Comment", commentId)); @@ -104,6 +112,7 @@ public void delete(UUID commentId, User currentUser) { @Transactional(readOnly = true) public long countByRecord(UUID recordId, User currentUser) { + log.debug("Counting comments recordId={}", recordId); MedicalRecord record = medicalRecordRepository.findById(recordId) .orElseThrow(() -> new ResourceNotFoundException("MedicalRecord", recordId)); From 7aafdeab70a2bfe6956ef4d789f4d83604fe354a Mon Sep 17 00:00:00 2001 From: Annika Holmqvist Date: Tue, 7 Apr 2026 11:13:52 +0200 Subject: [PATCH 7/9] feat: add logging to ActivityLogController and ActivityLogService - Introduced `SLF4J` logging in `ActivityLogController` and `ActivityLogService` for key actions (create, read). - Enhanced traceability and debugging by logging request details and method activities. --- .../example/vet1177/controller/ActivityLogController.java | 5 +++++ .../org/example/vet1177/services/ActivityLogService.java | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/src/main/java/org/example/vet1177/controller/ActivityLogController.java b/src/main/java/org/example/vet1177/controller/ActivityLogController.java index 7b1aca6..5086b48 100644 --- a/src/main/java/org/example/vet1177/controller/ActivityLogController.java +++ b/src/main/java/org/example/vet1177/controller/ActivityLogController.java @@ -4,6 +4,8 @@ import org.example.vet1177.entities.User; import org.example.vet1177.services.ActivityLogService; import org.example.vet1177.services.UserService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.web.bind.annotation.*; import java.util.List; @@ -13,6 +15,8 @@ @RequestMapping("/api/activity-logs") public class ActivityLogController { + private static final Logger log = LoggerFactory.getLogger(ActivityLogController.class); + private final ActivityLogService activityLogService; private final UserService userService; @@ -28,6 +32,7 @@ public List getLogsByRecord( @PathVariable UUID recordId, @RequestHeader("userId") UUID userId ) { + log.info("GET /api/activity-logs/record/{}", recordId); User user = userService.getUserEntityById(userId); return activityLogService.getByRecord(recordId, user) diff --git a/src/main/java/org/example/vet1177/services/ActivityLogService.java b/src/main/java/org/example/vet1177/services/ActivityLogService.java index 5a6cbec..f0d411b 100644 --- a/src/main/java/org/example/vet1177/services/ActivityLogService.java +++ b/src/main/java/org/example/vet1177/services/ActivityLogService.java @@ -8,6 +8,8 @@ import org.example.vet1177.exception.ForbiddenException; import org.example.vet1177.policy.ActivityLogPolicy; import org.example.vet1177.repository.ActivityLogRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.stereotype.Service; import java.util.List; @@ -16,6 +18,8 @@ @Service public class ActivityLogService { + private static final Logger LOG = LoggerFactory.getLogger(ActivityLogService.class); + private final ActivityLogRepository repository; private final ActivityLogPolicy activityLogPolicy; @@ -30,19 +34,23 @@ public ActivityLogService(ActivityLogRepository repository, public void log(ActivityType action, String description, User user, MedicalRecord record) { if (action == null || description == null || user == null || record == null) { + LOG.warn("Invalid activity log data"); throw new BusinessRuleException("Invalid activity log data"); } ActivityLog log = new ActivityLog(action, description, user, record); repository.save(log); + LOG.info("Activity logged action={} recordId={}", action, record.getId()); } // READ public List getByRecord(UUID recordId, User currentUser) { + LOG.debug("Fetching activity logs recordId={}", recordId); if (recordId == null || currentUser == null) { + LOG.warn("Access denied to activity logs - missing recordId or user"); throw new ForbiddenException("Åtkomst nekad"); } From 3464169f0d09ed7ad923b9b32acb7c35a79c30b8 Mon Sep 17 00:00:00 2001 From: Annika Holmqvist Date: Tue, 7 Apr 2026 11:14:16 +0200 Subject: [PATCH 8/9] feat: add logging to AttachmentController - Introduced `SLF4J` logging in `AttachmentController` for key actions (create, read, delete). - Enhanced traceability and debugging by logging request details for API endpoints. Closes #94 --- .../example/vet1177/controller/AttachmentController.java | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/main/java/org/example/vet1177/controller/AttachmentController.java b/src/main/java/org/example/vet1177/controller/AttachmentController.java index 75aa0b0..b732ff6 100644 --- a/src/main/java/org/example/vet1177/controller/AttachmentController.java +++ b/src/main/java/org/example/vet1177/controller/AttachmentController.java @@ -7,6 +7,8 @@ import org.example.vet1177.dto.response.attachment.AttachmentResponse; import org.example.vet1177.entities.User; import org.example.vet1177.services.AttachmentService; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.ResponseEntity; @@ -20,6 +22,8 @@ @RequestMapping("/api/attachments") public class AttachmentController { + private static final Logger log = LoggerFactory.getLogger(AttachmentController.class); + private final AttachmentService attachmentService; private final Validator validator; @@ -39,6 +43,7 @@ public ResponseEntity uploadAttachment( @RequestPart(value = "description", required = false) String description) { + log.info("POST /api/attachments/record/{} - uploading attachment", recordId); AttachmentRequest request = new AttachmentRequest(recordId, description); var violations = validator.validate(request); @@ -56,6 +61,7 @@ public ResponseEntity> listAttachments( @AuthenticationPrincipal User currentUser, @PathVariable UUID recordId) { + log.info("GET /api/attachments/record/{}", recordId); List responses = attachmentService.getAttachmentsByRecord(currentUser, recordId); return ResponseEntity.ok(responses); } @@ -66,6 +72,7 @@ public ResponseEntity downloadAttachment( @AuthenticationPrincipal User currentUser, @PathVariable UUID id) { + log.info("GET /api/attachments/{}/download", id); AttachmentResponse response = attachmentService.getAttachment(currentUser, id); return ResponseEntity.ok(response); } @@ -76,6 +83,7 @@ public ResponseEntity deleteAttachment( @AuthenticationPrincipal User currentUser, @PathVariable UUID id) { + log.info("DELETE /api/attachments/{}", id); attachmentService.deleteAttachment(currentUser, id); return ResponseEntity.noContent().build(); } From 493fdd3f640a933c58720a272c82b7ac57a2b51a Mon Sep 17 00:00:00 2001 From: Annika Holmqvist Date: Wed, 8 Apr 2026 10:03:10 +0200 Subject: [PATCH 9/9] feat: enhance logging in PetService - Updated logging levels to `debug` for non-critical actions. - Added detailed `info` logs for successful create, update, and delete operations to improve traceability. --- .../org/example/vet1177/services/PetService.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/main/java/org/example/vet1177/services/PetService.java b/src/main/java/org/example/vet1177/services/PetService.java index e55c1f5..91552e4 100644 --- a/src/main/java/org/example/vet1177/services/PetService.java +++ b/src/main/java/org/example/vet1177/services/PetService.java @@ -43,7 +43,7 @@ public PetService(PetRepository petRepository, // CREATE - OWNER kan skapa för sig själv, ADMIN kan skapa för en OWNER via ownerId. public Pet createPet(UUID currentUserId, UUID ownerId, PetRequest request) { - log.info("Creating pet currentUserId={} ownerId={}", currentUserId, ownerId); + log.debug("Creating pet currentUserId={} ownerId={}", currentUserId, ownerId); User currentUser = getUserById(currentUserId); if (!petPolicy.canCreate(currentUser)) { @@ -67,7 +67,9 @@ public Pet createPet(UUID currentUserId, UUID ownerId, PetRequest request) { applyPetRequest(pet, request); pet.setOwner(owner); - return petRepository.save(pet); + Pet saved = petRepository.save(pet); + log.info("Created pet id={} ownerId={}", saved.getId(), owner.getId()); + return saved; } // READ @@ -108,7 +110,7 @@ public List getPetsByOwner(UUID currentUserId, UUID ownerId) { // UPDATE public Pet updatePet(UUID currentUserId, UUID petId, PetRequest request) { - log.info("Updating pet id={}", petId); + log.debug("Updating pet id={}", petId); User currentUser = getUserById(currentUserId); Pet existingPet = getPetByIdOrThrow(petId); @@ -123,13 +125,15 @@ public Pet updatePet(UUID currentUserId, UUID petId, PetRequest request) { existingPet.setWeightKg(request.getWeightKg()); - return petRepository.save(existingPet); + Pet saved = petRepository.save(existingPet); + log.info("Updated pet id={}", saved.getId()); + return saved; } // DELETE @Transactional public void deletePet(UUID petId, User currentUser) { - log.info("Deleting pet id={}", petId); + log.debug("Deleting pet id={}", petId); Pet pet = petRepository.findById(petId) .orElseThrow(() -> new ResourceNotFoundException("Pet", petId)); @@ -139,6 +143,7 @@ public void deletePet(UUID petId, User currentUser) { try { petRepository.delete(pet); petRepository.flush(); + log.info("Deleted pet id={}", petId); } catch (DataIntegrityViolationException e) { throw new BusinessRuleException("Djuret kan inte raderas eftersom journaler finns kopplade"); }