fix(comment): populate annotationId on block comments from the block
postBlockComment now looks up the block via TranscriptionService and sets comment.annotationId from block.getAnnotationId(). This closes the upstream root cause of issue #276, where notifications for block comments were stored with annotationId=null, breaking the notification deep-link flow on the document detail page. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -8,6 +8,7 @@ import org.raddatz.familienarchiv.exception.DomainException;
|
||||
import org.raddatz.familienarchiv.exception.ErrorCode;
|
||||
import org.raddatz.familienarchiv.model.AppUser;
|
||||
import org.raddatz.familienarchiv.model.DocumentComment;
|
||||
import org.raddatz.familienarchiv.model.TranscriptionBlock;
|
||||
import org.raddatz.familienarchiv.repository.CommentRepository;
|
||||
import org.springframework.stereotype.Service;
|
||||
import org.springframework.transaction.annotation.Transactional;
|
||||
@@ -26,6 +27,7 @@ public class CommentService {
|
||||
private final UserService userService;
|
||||
private final NotificationService notificationService;
|
||||
private final AuditService auditService;
|
||||
private final TranscriptionService transcriptionService;
|
||||
|
||||
public List<DocumentComment> getCommentsForDocument(UUID documentId) {
|
||||
List<DocumentComment> roots =
|
||||
@@ -46,9 +48,11 @@ public class CommentService {
|
||||
@Transactional
|
||||
public DocumentComment postBlockComment(UUID documentId, UUID blockId, String content,
|
||||
List<UUID> mentionedUserIds, AppUser author) {
|
||||
TranscriptionBlock block = transcriptionService.getBlock(documentId, blockId);
|
||||
DocumentComment comment = DocumentComment.builder()
|
||||
.documentId(documentId)
|
||||
.blockId(blockId)
|
||||
.annotationId(block.getAnnotationId())
|
||||
.content(content)
|
||||
.authorId(author.getId())
|
||||
.authorName(resolveAuthorName(author))
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.raddatz.familienarchiv.audit.AuditService;
|
||||
import org.raddatz.familienarchiv.exception.DomainException;
|
||||
import org.raddatz.familienarchiv.model.AppUser;
|
||||
import org.raddatz.familienarchiv.model.DocumentComment;
|
||||
import org.raddatz.familienarchiv.model.TranscriptionBlock;
|
||||
import org.raddatz.familienarchiv.model.UserGroup;
|
||||
import org.raddatz.familienarchiv.repository.CommentRepository;
|
||||
|
||||
@@ -39,6 +40,7 @@ class CommentServiceTest {
|
||||
@Mock UserService userService;
|
||||
@Mock NotificationService notificationService;
|
||||
@Mock AuditService auditService;
|
||||
@Mock TranscriptionService transcriptionService;
|
||||
@InjectMocks CommentService commentService;
|
||||
|
||||
// ─── postComment ──────────────────────────────────────────────────────────
|
||||
@@ -611,6 +613,8 @@ class CommentServiceTest {
|
||||
AppUser author = AppUser.builder().id(UUID.randomUUID()).email("felix@example.com").firstName("Felix").lastName("B").build();
|
||||
DocumentComment saved = DocumentComment.builder()
|
||||
.id(savedId).documentId(docId).blockId(blockId).authorName("Felix B").content("Nice").build();
|
||||
when(transcriptionService.getBlock(docId, blockId))
|
||||
.thenReturn(TranscriptionBlock.builder().id(blockId).documentId(docId).annotationId(UUID.randomUUID()).sortOrder(0).build());
|
||||
when(commentRepository.save(any())).thenReturn(saved);
|
||||
|
||||
commentService.postBlockComment(docId, blockId, "Nice", List.of(), author);
|
||||
@@ -643,7 +647,10 @@ class CommentServiceTest {
|
||||
void postBlockComment_setsBlockIdOnComment() {
|
||||
UUID documentId = UUID.randomUUID();
|
||||
UUID blockId = UUID.randomUUID();
|
||||
UUID annotationId = UUID.randomUUID();
|
||||
AppUser author = AppUser.builder().id(UUID.randomUUID()).email("felix@example.com").firstName("Felix").lastName("Brandt").build();
|
||||
when(transcriptionService.getBlock(documentId, blockId))
|
||||
.thenReturn(TranscriptionBlock.builder().id(blockId).documentId(documentId).annotationId(annotationId).sortOrder(0).build());
|
||||
when(commentRepository.save(any())).thenAnswer(inv -> {
|
||||
DocumentComment c = inv.getArgument(0);
|
||||
c.setId(UUID.randomUUID());
|
||||
@@ -657,4 +664,39 @@ class CommentServiceTest {
|
||||
assertThat(result.getDocumentId()).isEqualTo(documentId);
|
||||
assertThat(result.getContent()).isEqualTo("Looks like Breslau");
|
||||
}
|
||||
|
||||
@Test
|
||||
void postBlockComment_setsAnnotationIdFromBlock() {
|
||||
UUID documentId = UUID.randomUUID();
|
||||
UUID blockId = UUID.randomUUID();
|
||||
UUID annotationId = UUID.randomUUID();
|
||||
AppUser author = AppUser.builder().id(UUID.randomUUID()).email("felix@example.com").firstName("Felix").lastName("Brandt").build();
|
||||
when(transcriptionService.getBlock(documentId, blockId))
|
||||
.thenReturn(TranscriptionBlock.builder().id(blockId).documentId(documentId).annotationId(annotationId).sortOrder(0).build());
|
||||
when(commentRepository.save(any())).thenAnswer(inv -> {
|
||||
DocumentComment c = inv.getArgument(0);
|
||||
c.setId(UUID.randomUUID());
|
||||
return c;
|
||||
});
|
||||
|
||||
DocumentComment result = commentService.postBlockComment(
|
||||
documentId, blockId, "Nice work", List.of(), author);
|
||||
|
||||
assertThat(result.getAnnotationId()).isEqualTo(annotationId);
|
||||
}
|
||||
|
||||
@Test
|
||||
void postBlockComment_propagatesNotFound_whenBlockDoesNotExist() {
|
||||
UUID documentId = UUID.randomUUID();
|
||||
UUID blockId = UUID.randomUUID();
|
||||
AppUser author = AppUser.builder().id(UUID.randomUUID()).email("felix@example.com").firstName("Felix").lastName("Brandt").build();
|
||||
when(transcriptionService.getBlock(documentId, blockId))
|
||||
.thenThrow(DomainException.notFound(
|
||||
org.raddatz.familienarchiv.exception.ErrorCode.TRANSCRIPTION_BLOCK_NOT_FOUND,
|
||||
"Transcription block not found: " + blockId));
|
||||
|
||||
assertThatThrownBy(() -> commentService.postBlockComment(documentId, blockId, "Hi", List.of(), author))
|
||||
.isInstanceOf(DomainException.class)
|
||||
.hasMessageContaining("Transcription block not found");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user