refactor(person): thin deletePerson to lean on V71 DB cascade (#684)

Drop the application-layer sender/receiver detach from deletePerson — the
V71 ON DELETE constraints now enforce it. Remove the now-unused
reassignSenderToNull repository method and rewrite the unit test to assert
only the existence check plus deleteById (verifyNoMoreInteractions).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-06-06 11:41:50 +02:00
parent e4d48aaa70
commit b307fe083b
3 changed files with 8 additions and 13 deletions

View File

@@ -194,12 +194,6 @@ public interface PersonRepository extends JpaRepository<Person, UUID> {
@Query(value = "UPDATE documents SET sender_id = :target WHERE sender_id = :source", nativeQuery = true)
void reassignSender(@Param("source") UUID source, @Param("target") UUID target);
// Used by deletePerson: detach a deleted person from documents they sent, so the hard
// delete cannot orphan a documents.sender_id FK (the column is nullable).
@Modifying
@Query(value = "UPDATE documents SET sender_id = NULL WHERE sender_id = :source", nativeQuery = true)
void reassignSenderToNull(@Param("source") UUID source);
@Modifying
@Query(value = """
INSERT INTO document_receivers (document_id, person_id)

View File

@@ -68,15 +68,13 @@ public class PersonService {
}
/**
* Hard-deletes a person used by triage. Detaches the person from any documents they
* sent (nulls sender_id) and from any received-document references first, so the delete
* cannot orphan an FK and fail with a 500.
* Hard-deletes a person used by triage. Referential integrity is enforced by the database
* (V71's {@code ON DELETE} constraints: sender_id {@code SET NULL}, receiver and @-mention
* rows {@code CASCADE}), so the service stays thin — it only verifies existence then deletes.
*/
@Transactional
public void deletePerson(UUID id) {
getById(id);
personRepository.reassignSenderToNull(id);
personRepository.deleteReceiverReferences(id);
personRepository.deleteById(id);
}

View File

@@ -27,6 +27,7 @@ import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
@@ -147,9 +148,11 @@ class PersonServiceTest {
personService.deletePerson(id);
verify(personRepository).reassignSenderToNull(id);
verify(personRepository).deleteReceiverReferences(id);
// Integrity is enforced by V71's ON DELETE constraints — the service only checks
// existence then deletes; it no longer detaches sender/receiver references itself.
verify(personRepository).findById(id);
verify(personRepository).deleteById(id);
verifyNoMoreInteractions(personRepository);
}
@Test