feat(comments): add block-level comment endpoints with TDD
RED/GREEN for CommentService:
- getCommentsForBlock(blockId): returns root comments filtered by blockId
- postBlockComment(documentId, blockId, content, mentions, author): creates
comment with block_id set
RED/GREEN for CommentController:
- GET /api/documents/{docId}/transcription-blocks/{blockId}/comments
- POST /api/documents/{docId}/transcription-blocks/{blockId}/comments
- POST .../comments/{commentId}/replies (reuses existing replyToComment)
4 new tests: 2 service unit tests + 2 controller integration tests
All 25 CommentServiceTest + 24 CommentControllerTest green
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -85,6 +85,37 @@ public class CommentController {
|
||||
return commentService.replyToComment(documentId, commentId, dto.getContent(), dto.getMentionedUserIds(), author);
|
||||
}
|
||||
|
||||
// ─── Block (transcription) comments ────────────────────────────────────────
|
||||
|
||||
@GetMapping("/api/documents/{documentId}/transcription-blocks/{blockId}/comments")
|
||||
public List<DocumentComment> getBlockComments(@PathVariable UUID blockId) {
|
||||
return commentService.getCommentsForBlock(blockId);
|
||||
}
|
||||
|
||||
@PostMapping("/api/documents/{documentId}/transcription-blocks/{blockId}/comments")
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
@RequirePermission({Permission.ANNOTATE_ALL, Permission.WRITE_ALL})
|
||||
public DocumentComment postBlockComment(
|
||||
@PathVariable UUID documentId,
|
||||
@PathVariable UUID blockId,
|
||||
@RequestBody CreateCommentDTO dto,
|
||||
Authentication authentication) {
|
||||
AppUser author = resolveUser(authentication);
|
||||
return commentService.postBlockComment(documentId, blockId, dto.getContent(), dto.getMentionedUserIds(), author);
|
||||
}
|
||||
|
||||
@PostMapping("/api/documents/{documentId}/transcription-blocks/{blockId}/comments/{commentId}/replies")
|
||||
@ResponseStatus(HttpStatus.CREATED)
|
||||
@RequirePermission({Permission.ANNOTATE_ALL, Permission.WRITE_ALL})
|
||||
public DocumentComment replyToBlockComment(
|
||||
@PathVariable UUID documentId,
|
||||
@PathVariable UUID commentId,
|
||||
@RequestBody CreateCommentDTO dto,
|
||||
Authentication authentication) {
|
||||
AppUser author = resolveUser(authentication);
|
||||
return commentService.replyToComment(documentId, commentId, dto.getContent(), dto.getMentionedUserIds(), author);
|
||||
}
|
||||
|
||||
// ─── Edit and delete (shared) ─────────────────────────────────────────────
|
||||
|
||||
@PatchMapping("/api/documents/{documentId}/comments/{commentId}")
|
||||
|
||||
@@ -13,4 +13,6 @@ public interface CommentRepository extends JpaRepository<DocumentComment, UUID>
|
||||
List<DocumentComment> findByAnnotationIdAndParentIdIsNull(UUID annotationId);
|
||||
|
||||
List<DocumentComment> findByParentId(UUID parentId);
|
||||
|
||||
List<DocumentComment> findByBlockIdAndParentIdIsNull(UUID blockId);
|
||||
}
|
||||
|
||||
@@ -34,6 +34,28 @@ public class CommentService {
|
||||
return withRepliesAndMentions(roots);
|
||||
}
|
||||
|
||||
public List<DocumentComment> getCommentsForBlock(UUID blockId) {
|
||||
List<DocumentComment> roots = commentRepository.findByBlockIdAndParentIdIsNull(blockId);
|
||||
return withRepliesAndMentions(roots);
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public DocumentComment postBlockComment(UUID documentId, UUID blockId, String content,
|
||||
List<UUID> mentionedUserIds, AppUser author) {
|
||||
DocumentComment comment = DocumentComment.builder()
|
||||
.documentId(documentId)
|
||||
.blockId(blockId)
|
||||
.content(content)
|
||||
.authorId(author.getId())
|
||||
.authorName(resolveAuthorName(author))
|
||||
.build();
|
||||
saveMentions(comment, mentionedUserIds);
|
||||
DocumentComment saved = commentRepository.save(comment);
|
||||
withMentionDTOs(saved);
|
||||
notificationService.notifyMentions(mentionedUserIds, saved);
|
||||
return saved;
|
||||
}
|
||||
|
||||
@Transactional
|
||||
public DocumentComment postComment(UUID documentId, UUID annotationId, String content,
|
||||
List<UUID> mentionedUserIds, AppUser author) {
|
||||
|
||||
Reference in New Issue
Block a user