feat(transcription): person @mention sidecar + rename propagation (PR-A backend, #362) #366
@@ -13,11 +13,13 @@ import org.raddatz.familienarchiv.dto.PersonUpdateDTO;
|
|||||||
import org.raddatz.familienarchiv.exception.DomainException;
|
import org.raddatz.familienarchiv.exception.DomainException;
|
||||||
import org.raddatz.familienarchiv.exception.ErrorCode;
|
import org.raddatz.familienarchiv.exception.ErrorCode;
|
||||||
import org.raddatz.familienarchiv.model.Person;
|
import org.raddatz.familienarchiv.model.Person;
|
||||||
|
import org.raddatz.familienarchiv.model.PersonDisplayNameChangedEvent;
|
||||||
import org.raddatz.familienarchiv.model.PersonNameAlias;
|
import org.raddatz.familienarchiv.model.PersonNameAlias;
|
||||||
import org.raddatz.familienarchiv.model.PersonNameAliasType;
|
import org.raddatz.familienarchiv.model.PersonNameAliasType;
|
||||||
import org.raddatz.familienarchiv.model.PersonType;
|
import org.raddatz.familienarchiv.model.PersonType;
|
||||||
import org.raddatz.familienarchiv.repository.PersonNameAliasRepository;
|
import org.raddatz.familienarchiv.repository.PersonNameAliasRepository;
|
||||||
import org.raddatz.familienarchiv.repository.PersonRepository;
|
import org.raddatz.familienarchiv.repository.PersonRepository;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.http.HttpStatus;
|
import org.springframework.http.HttpStatus;
|
||||||
import org.springframework.stereotype.Service;
|
import org.springframework.stereotype.Service;
|
||||||
import org.springframework.transaction.annotation.Transactional;
|
import org.springframework.transaction.annotation.Transactional;
|
||||||
@@ -31,6 +33,7 @@ public class PersonService {
|
|||||||
|
|
||||||
private final PersonRepository personRepository;
|
private final PersonRepository personRepository;
|
||||||
private final PersonNameAliasRepository aliasRepository;
|
private final PersonNameAliasRepository aliasRepository;
|
||||||
|
private final ApplicationEventPublisher eventPublisher;
|
||||||
|
|
||||||
public List<PersonSummaryDTO> findAll(String q) {
|
public List<PersonSummaryDTO> findAll(String q) {
|
||||||
if (q == null) {
|
if (q == null) {
|
||||||
@@ -157,6 +160,7 @@ public class PersonService {
|
|||||||
validateYears(dto.getBirthYear(), dto.getDeathYear());
|
validateYears(dto.getBirthYear(), dto.getDeathYear());
|
||||||
Person person = personRepository.findById(id)
|
Person person = personRepository.findById(id)
|
||||||
.orElseThrow(() -> DomainException.notFound(ErrorCode.PERSON_NOT_FOUND, "Person not found: " + id));
|
.orElseThrow(() -> DomainException.notFound(ErrorCode.PERSON_NOT_FOUND, "Person not found: " + id));
|
||||||
|
String oldDisplayName = person.getDisplayName();
|
||||||
person.setPersonType(dto.getPersonType());
|
person.setPersonType(dto.getPersonType());
|
||||||
person.setTitle(dto.getTitle() == null || dto.getTitle().isBlank() ? null : dto.getTitle().trim());
|
person.setTitle(dto.getTitle() == null || dto.getTitle().isBlank() ? null : dto.getTitle().trim());
|
||||||
person.setFirstName(dto.getFirstName());
|
person.setFirstName(dto.getFirstName());
|
||||||
@@ -165,7 +169,12 @@ public class PersonService {
|
|||||||
person.setNotes(dto.getNotes() == null || dto.getNotes().isBlank() ? null : dto.getNotes().trim());
|
person.setNotes(dto.getNotes() == null || dto.getNotes().isBlank() ? null : dto.getNotes().trim());
|
||||||
person.setBirthYear(dto.getBirthYear());
|
person.setBirthYear(dto.getBirthYear());
|
||||||
person.setDeathYear(dto.getDeathYear());
|
person.setDeathYear(dto.getDeathYear());
|
||||||
return personRepository.save(person);
|
Person saved = personRepository.save(person);
|
||||||
|
String newDisplayName = saved.getDisplayName();
|
||||||
|
if (!Objects.equals(oldDisplayName, newDisplayName)) {
|
||||||
|
eventPublisher.publishEvent(new PersonDisplayNameChangedEvent(id, oldDisplayName, newDisplayName));
|
||||||
|
}
|
||||||
|
return saved;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Transactional
|
@Transactional
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package org.raddatz.familienarchiv.service;
|
|||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.mockito.ArgumentCaptor;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.junit.jupiter.MockitoExtension;
|
import org.mockito.junit.jupiter.MockitoExtension;
|
||||||
@@ -10,11 +11,13 @@ import org.raddatz.familienarchiv.dto.PersonSummaryDTO;
|
|||||||
import org.raddatz.familienarchiv.dto.PersonUpdateDTO;
|
import org.raddatz.familienarchiv.dto.PersonUpdateDTO;
|
||||||
import org.raddatz.familienarchiv.exception.DomainException;
|
import org.raddatz.familienarchiv.exception.DomainException;
|
||||||
import org.raddatz.familienarchiv.model.Person;
|
import org.raddatz.familienarchiv.model.Person;
|
||||||
|
import org.raddatz.familienarchiv.model.PersonDisplayNameChangedEvent;
|
||||||
import org.raddatz.familienarchiv.model.PersonNameAlias;
|
import org.raddatz.familienarchiv.model.PersonNameAlias;
|
||||||
import org.raddatz.familienarchiv.model.PersonNameAliasType;
|
import org.raddatz.familienarchiv.model.PersonNameAliasType;
|
||||||
import org.raddatz.familienarchiv.model.PersonType;
|
import org.raddatz.familienarchiv.model.PersonType;
|
||||||
import org.raddatz.familienarchiv.repository.PersonNameAliasRepository;
|
import org.raddatz.familienarchiv.repository.PersonNameAliasRepository;
|
||||||
import org.raddatz.familienarchiv.repository.PersonRepository;
|
import org.raddatz.familienarchiv.repository.PersonRepository;
|
||||||
|
import org.springframework.context.ApplicationEventPublisher;
|
||||||
import org.springframework.web.server.ResponseStatusException;
|
import org.springframework.web.server.ResponseStatusException;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -31,6 +34,7 @@ class PersonServiceTest {
|
|||||||
|
|
||||||
@Mock PersonRepository personRepository;
|
@Mock PersonRepository personRepository;
|
||||||
@Mock PersonNameAliasRepository aliasRepository;
|
@Mock PersonNameAliasRepository aliasRepository;
|
||||||
|
@Mock ApplicationEventPublisher eventPublisher;
|
||||||
@InjectMocks PersonService personService;
|
@InjectMocks PersonService personService;
|
||||||
|
|
||||||
// ─── getById ─────────────────────────────────────────────────────────────
|
// ─── getById ─────────────────────────────────────────────────────────────
|
||||||
@@ -242,6 +246,37 @@ class PersonServiceTest {
|
|||||||
assertThat(result.getAlias()).isEqualTo("Anna Alt");
|
assertThat(result.getAlias()).isEqualTo("Anna Alt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ─── updatePerson (display-name change event) ────────────────────────────
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void updatePerson_publishesEvent_whenTitleChanges() {
|
||||||
|
UUID id = UUID.randomUUID();
|
||||||
|
Person existing = Person.builder()
|
||||||
|
.id(id).title("Herr").firstName("Auguste").lastName("Raddatz")
|
||||||
|
.personType(PersonType.PERSON).build();
|
||||||
|
String oldName = existing.getDisplayName();
|
||||||
|
|
||||||
|
when(personRepository.findById(id)).thenReturn(Optional.of(existing));
|
||||||
|
when(personRepository.save(any())).thenAnswer(inv -> inv.getArgument(0));
|
||||||
|
|
||||||
|
PersonUpdateDTO dto = new PersonUpdateDTO();
|
||||||
|
dto.setPersonType(PersonType.PERSON);
|
||||||
|
dto.setTitle("Frau"); dto.setFirstName("Auguste"); dto.setLastName("Raddatz");
|
||||||
|
|
||||||
|
personService.updatePerson(id, dto);
|
||||||
|
|
||||||
|
ArgumentCaptor<PersonDisplayNameChangedEvent> captor =
|
||||||
|
ArgumentCaptor.forClass(PersonDisplayNameChangedEvent.class);
|
||||||
|
verify(eventPublisher).publishEvent(captor.capture());
|
||||||
|
|
||||||
|
PersonDisplayNameChangedEvent event = captor.getValue();
|
||||||
|
assertThat(event.personId()).isEqualTo(id);
|
||||||
|
assertThat(event.oldDisplayName()).isEqualTo(oldName);
|
||||||
|
assertThat(event.newDisplayName())
|
||||||
|
.isNotEqualTo(oldName)
|
||||||
|
.contains("Frau");
|
||||||
|
}
|
||||||
|
|
||||||
// ─── findOrCreateByAlias ─────────────────────────────────────────────────
|
// ─── findOrCreateByAlias ─────────────────────────────────────────────────
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user