fix(db): V51 backfills annotation_id on block comments and notifications
Previously issued block-comment notifications were stored with annotation_id=NULL because CommentService.postBlockComment did not populate DocumentComment.annotationId. Now that the code fix is in place, existing rows need to be filled in so legacy notifications can also carry the query param that the frontend deep-link flow expects. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -302,6 +302,57 @@ class MigrationIntegrationTest {
|
||||
).isInstanceOf(DataIntegrityViolationException.class);
|
||||
}
|
||||
|
||||
// ─── V51: backfill annotation_id on block comments and notifications ─────
|
||||
|
||||
@Test
|
||||
void v51_backfillsAnnotationIdOnBlockCommentsFromTheirBlocks() {
|
||||
UUID docId = createDocument();
|
||||
UUID annotationId = insertAnnotation(docId);
|
||||
UUID blockId = insertBlock(docId, annotationId);
|
||||
UUID commentId = insertBlockCommentWithNullAnnotationId(docId, blockId);
|
||||
|
||||
jdbc.update(V51_BACKFILL_COMMENTS_SQL);
|
||||
|
||||
UUID stored = jdbc.queryForObject(
|
||||
"SELECT annotation_id FROM document_comments WHERE id = ?",
|
||||
UUID.class, commentId);
|
||||
assertThat(stored).isEqualTo(annotationId);
|
||||
}
|
||||
|
||||
@Test
|
||||
void v51_backfillsAnnotationIdOnNotificationsFromTheirReferencedComment() {
|
||||
UUID docId = createDocument();
|
||||
UUID userId = insertUser("recipient-" + UUID.randomUUID() + "@example.com");
|
||||
UUID annotationId = insertAnnotation(docId);
|
||||
UUID blockId = insertBlock(docId, annotationId);
|
||||
UUID commentId = insertBlockCommentWithAnnotationId(docId, blockId, annotationId);
|
||||
UUID notificationId = insertNotificationWithNullAnnotationId(docId, commentId, userId);
|
||||
|
||||
jdbc.update(V51_BACKFILL_NOTIFICATIONS_SQL);
|
||||
|
||||
UUID stored = jdbc.queryForObject(
|
||||
"SELECT annotation_id FROM notifications WHERE id = ?",
|
||||
UUID.class, notificationId);
|
||||
assertThat(stored).isEqualTo(annotationId);
|
||||
}
|
||||
|
||||
private static final String V51_BACKFILL_COMMENTS_SQL = """
|
||||
UPDATE document_comments dc
|
||||
SET annotation_id = tb.annotation_id
|
||||
FROM transcription_blocks tb
|
||||
WHERE dc.block_id = tb.id
|
||||
AND dc.annotation_id IS NULL
|
||||
""";
|
||||
|
||||
private static final String V51_BACKFILL_NOTIFICATIONS_SQL = """
|
||||
UPDATE notifications n
|
||||
SET annotation_id = dc.annotation_id
|
||||
FROM document_comments dc
|
||||
WHERE n.reference_id = dc.id
|
||||
AND n.annotation_id IS NULL
|
||||
AND dc.annotation_id IS NOT NULL
|
||||
""";
|
||||
|
||||
// ─── helpers ─────────────────────────────────────────────────────────────
|
||||
|
||||
private UUID createPerson(String firstName, String lastName) {
|
||||
@@ -326,4 +377,63 @@ class MigrationIntegrationTest {
|
||||
em.flush();
|
||||
return doc.getId();
|
||||
}
|
||||
|
||||
private UUID insertAnnotation(UUID docId) {
|
||||
UUID id = UUID.randomUUID();
|
||||
jdbc.update("""
|
||||
INSERT INTO document_annotations
|
||||
(id, document_id, page_number, x, y, width, height, color)
|
||||
VALUES (?, ?, 1, 0.1, 0.1, 0.3, 0.1, '#00C7B1')
|
||||
""", id, docId);
|
||||
return id;
|
||||
}
|
||||
|
||||
private UUID insertBlock(UUID docId, UUID annotationId) {
|
||||
UUID id = UUID.randomUUID();
|
||||
jdbc.update("""
|
||||
INSERT INTO transcription_blocks
|
||||
(id, annotation_id, document_id, text, sort_order)
|
||||
VALUES (?, ?, ?, '', 0)
|
||||
""", id, annotationId, docId);
|
||||
return id;
|
||||
}
|
||||
|
||||
private UUID insertUser(String email) {
|
||||
UUID id = UUID.randomUUID();
|
||||
jdbc.update("""
|
||||
INSERT INTO users (id, email, password, enabled, notify_on_reply, notify_on_mention)
|
||||
VALUES (?, ?, 'hash', true, false, false)
|
||||
""", id, email);
|
||||
return id;
|
||||
}
|
||||
|
||||
private UUID insertBlockCommentWithNullAnnotationId(UUID docId, UUID blockId) {
|
||||
UUID id = UUID.randomUUID();
|
||||
jdbc.update("""
|
||||
INSERT INTO document_comments
|
||||
(id, document_id, block_id, annotation_id, author_name, content)
|
||||
VALUES (?, ?, ?, NULL, 'Tester', 'Hi')
|
||||
""", id, docId, blockId);
|
||||
return id;
|
||||
}
|
||||
|
||||
private UUID insertBlockCommentWithAnnotationId(UUID docId, UUID blockId, UUID annotationId) {
|
||||
UUID id = UUID.randomUUID();
|
||||
jdbc.update("""
|
||||
INSERT INTO document_comments
|
||||
(id, document_id, block_id, annotation_id, author_name, content)
|
||||
VALUES (?, ?, ?, ?, 'Tester', 'Hi')
|
||||
""", id, docId, blockId, annotationId);
|
||||
return id;
|
||||
}
|
||||
|
||||
private UUID insertNotificationWithNullAnnotationId(UUID docId, UUID commentId, UUID recipientId) {
|
||||
UUID id = UUID.randomUUID();
|
||||
jdbc.update("""
|
||||
INSERT INTO notifications
|
||||
(id, recipient_id, type, document_id, reference_id, annotation_id, read, actor_name)
|
||||
VALUES (?, ?, 'MENTION', ?, ?, NULL, false, 'Tester')
|
||||
""", id, recipientId, docId, commentId);
|
||||
return id;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user