refactor(backend): replace 7-parameter updatePerson with PersonUpdateDTO

Reduces parameter count from 7 to 2 (id + dto), keeping all validation
and trimming logic in the service. Controller now binds request JSON
directly to the DTO via @RequestBody.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-03-20 11:52:16 +01:00
parent 5160009175
commit c006113db9
4 changed files with 45 additions and 22 deletions

View File

@@ -4,6 +4,7 @@ import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.raddatz.familienarchiv.dto.PersonUpdateDTO;
import org.raddatz.familienarchiv.model.Document;
import org.raddatz.familienarchiv.model.Person;
import org.raddatz.familienarchiv.service.DocumentService;
@@ -54,17 +55,14 @@ public class PersonController {
}
@PutMapping("/{id}")
public ResponseEntity<Person> updatePerson(@PathVariable UUID id, @RequestBody Map<String, String> body) {
String firstName = body.get("firstName");
String lastName = body.get("lastName");
if (firstName == null || firstName.isBlank() || lastName == null || lastName.isBlank()) {
public ResponseEntity<Person> updatePerson(@PathVariable UUID id, @RequestBody PersonUpdateDTO dto) {
if (dto.getFirstName() == null || dto.getFirstName().isBlank()
|| dto.getLastName() == null || dto.getLastName().isBlank()) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Vor- und Nachname sind Pflichtfelder");
}
Integer birthYear = body.get("birthYear") != null && !body.get("birthYear").isBlank()
? Integer.parseInt(body.get("birthYear")) : null;
Integer deathYear = body.get("deathYear") != null && !body.get("deathYear").isBlank()
? Integer.parseInt(body.get("deathYear")) : null;
return ResponseEntity.ok(personService.updatePerson(id, firstName.trim(), lastName.trim(), body.get("alias"), body.get("notes"), birthYear, deathYear));
dto.setFirstName(dto.getFirstName().trim());
dto.setLastName(dto.getLastName().trim());
return ResponseEntity.ok(personService.updatePerson(id, dto));
}
@PostMapping("/{id}/merge")

View File

@@ -0,0 +1,13 @@
package org.raddatz.familienarchiv.dto;
import lombok.Data;
@Data
public class PersonUpdateDTO {
private String firstName;
private String lastName;
private String alias;
private String notes;
private Integer birthYear;
private Integer deathYear;
}

View File

@@ -3,6 +3,7 @@ package org.raddatz.familienarchiv.service;
import java.util.List;
import java.util.UUID;
import org.raddatz.familienarchiv.dto.PersonUpdateDTO;
import org.raddatz.familienarchiv.model.Person;
import org.raddatz.familienarchiv.repository.PersonRepository;
import org.springframework.http.HttpStatus;
@@ -58,18 +59,18 @@ public class PersonService {
}
@Transactional
public Person updatePerson(UUID id, String firstName, String lastName, String alias, String notes, Integer birthYear, Integer deathYear) {
if (birthYear != null && deathYear != null && birthYear > deathYear) {
public Person updatePerson(UUID id, PersonUpdateDTO dto) {
if (dto.getBirthYear() != null && dto.getDeathYear() != null && dto.getBirthYear() > dto.getDeathYear()) {
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "Geburtsjahr darf nicht nach dem Todesjahr liegen");
}
Person person = personRepository.findById(id)
.orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Person nicht gefunden"));
person.setFirstName(firstName);
person.setLastName(lastName);
person.setAlias(alias == null || alias.isBlank() ? null : alias.trim());
person.setNotes(notes == null || notes.isBlank() ? null : notes.trim());
person.setBirthYear(birthYear);
person.setDeathYear(deathYear);
person.setFirstName(dto.getFirstName());
person.setLastName(dto.getLastName());
person.setAlias(dto.getAlias() == null || dto.getAlias().isBlank() ? null : dto.getAlias().trim());
person.setNotes(dto.getNotes() == null || dto.getNotes().isBlank() ? null : dto.getNotes().trim());
person.setBirthYear(dto.getBirthYear());
person.setDeathYear(dto.getDeathYear());
return personRepository.save(person);
}

View File

@@ -5,6 +5,7 @@ import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.raddatz.familienarchiv.dto.PersonUpdateDTO;
import org.raddatz.familienarchiv.model.Person;
import org.raddatz.familienarchiv.repository.PersonRepository;
import org.springframework.web.server.ResponseStatusException;
@@ -92,7 +93,9 @@ class PersonServiceTest {
when(personRepository.findById(id)).thenReturn(Optional.of(person));
when(personRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
Person result = personService.updatePerson(id, "Anna", "Alt", null, "Some notes here.", null, null);
PersonUpdateDTO dto = new PersonUpdateDTO();
dto.setFirstName("Anna"); dto.setLastName("Alt"); dto.setNotes("Some notes here.");
Person result = personService.updatePerson(id, dto);
assertThat(result.getNotes()).isEqualTo("Some notes here.");
}
@@ -104,7 +107,9 @@ class PersonServiceTest {
when(personRepository.findById(id)).thenReturn(Optional.of(person));
when(personRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
Person result = personService.updatePerson(id, "Anna", "Alt", null, " ", null, null);
PersonUpdateDTO dto = new PersonUpdateDTO();
dto.setFirstName("Anna"); dto.setLastName("Alt"); dto.setNotes(" ");
Person result = personService.updatePerson(id, dto);
assertThat(result.getNotes()).isNull();
}
@@ -118,7 +123,9 @@ class PersonServiceTest {
when(personRepository.findById(id)).thenReturn(Optional.of(person));
when(personRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
Person result = personService.updatePerson(id, "Anna", "Alt", null, null, 1890, 1965);
PersonUpdateDTO dto = new PersonUpdateDTO();
dto.setFirstName("Anna"); dto.setLastName("Alt"); dto.setBirthYear(1890); dto.setDeathYear(1965);
Person result = personService.updatePerson(id, dto);
assertThat(result.getBirthYear()).isEqualTo(1890);
assertThat(result.getDeathYear()).isEqualTo(1965);
@@ -128,7 +135,9 @@ class PersonServiceTest {
void updatePerson_throwsBadRequest_whenBirthYearAfterDeathYear() {
UUID id = UUID.randomUUID();
assertThatThrownBy(() -> personService.updatePerson(id, "Anna", "Alt", null, null, 1970, 1950))
PersonUpdateDTO dto = new PersonUpdateDTO();
dto.setFirstName("Anna"); dto.setLastName("Alt"); dto.setBirthYear(1970); dto.setDeathYear(1950);
assertThatThrownBy(() -> personService.updatePerson(id, dto))
.isInstanceOf(ResponseStatusException.class)
.extracting(e -> ((ResponseStatusException) e).getStatusCode().value())
.isEqualTo(400);
@@ -141,7 +150,9 @@ class PersonServiceTest {
when(personRepository.findById(id)).thenReturn(Optional.of(person));
when(personRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
Person result = personService.updatePerson(id, "Anna", "Alt", null, null, 1900, 1900);
PersonUpdateDTO dto = new PersonUpdateDTO();
dto.setFirstName("Anna"); dto.setLastName("Alt"); dto.setBirthYear(1900); dto.setDeathYear(1900);
Person result = personService.updatePerson(id, dto);
assertThat(result.getBirthYear()).isEqualTo(1900);
assertThat(result.getDeathYear()).isEqualTo(1900);