diff --git a/backend/src/main/java/org/raddatz/familienarchiv/repository/NotificationRepository.java b/backend/src/main/java/org/raddatz/familienarchiv/repository/NotificationRepository.java index 7de51cd8..b2759a99 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/repository/NotificationRepository.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/repository/NotificationRepository.java @@ -15,6 +15,9 @@ public interface NotificationRepository extends JpaRepository findByRecipientIdOrderByCreatedAtDesc(UUID recipientId, Pageable pageable); + Page findByRecipientIdAndTypeOrderByCreatedAtDesc( + UUID recipientId, NotificationType type, Pageable pageable); + Page findByRecipientIdAndTypeAndReadFalseOrderByCreatedAtDesc( UUID recipientId, NotificationType type, Pageable pageable); diff --git a/backend/src/main/java/org/raddatz/familienarchiv/service/NotificationService.java b/backend/src/main/java/org/raddatz/familienarchiv/service/NotificationService.java index 6df48bf8..2f88931d 100644 --- a/backend/src/main/java/org/raddatz/familienarchiv/service/NotificationService.java +++ b/backend/src/main/java/org/raddatz/familienarchiv/service/NotificationService.java @@ -98,6 +98,10 @@ public class NotificationService { return notificationRepository.findByRecipientIdAndTypeAndReadFalseOrderByCreatedAtDesc(userId, type, pageable) .map(this::toDTO); } + if (type != null) { + return notificationRepository.findByRecipientIdAndTypeOrderByCreatedAtDesc(userId, type, pageable) + .map(this::toDTO); + } return notificationRepository.findByRecipientIdOrderByCreatedAtDesc(userId, pageable) .map(this::toDTO); } diff --git a/backend/src/test/java/org/raddatz/familienarchiv/repository/NotificationRepositoryTest.java b/backend/src/test/java/org/raddatz/familienarchiv/repository/NotificationRepositoryTest.java index c64ba2db..0f68d992 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/repository/NotificationRepositoryTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/repository/NotificationRepositoryTest.java @@ -79,6 +79,24 @@ class NotificationRepositoryTest { assertThat(result.getTotalElements()).isEqualTo(5); } + // ─── findByRecipientIdAndType (without read filter) ────────────────────── + + @Test + void findByType_returnsBothReadAndUnreadMentions() { + notificationRepository.save(mention(userA, false)); // unread + notificationRepository.save(mention(userA, true)); // read — should also be included + notificationRepository.save(reply(userA, false)); // REPLY — excluded + notificationRepository.save(mention(userB, false)); // different user — excluded + + Page result = notificationRepository + .findByRecipientIdAndTypeOrderByCreatedAtDesc( + userA.getId(), NotificationType.MENTION, Pageable.ofSize(10)); + + assertThat(result.getContent()).hasSize(2); + assertThat(result.getContent()).allMatch(n -> n.getType() == NotificationType.MENTION); + assertThat(result.getContent()).allMatch(n -> n.getRecipient().getId().equals(userA.getId())); + } + // ─── helpers ───────────────────────────────────────────────────────────── private Notification mention(AppUser recipient, boolean read) { diff --git a/backend/src/test/java/org/raddatz/familienarchiv/service/NotificationServiceTest.java b/backend/src/test/java/org/raddatz/familienarchiv/service/NotificationServiceTest.java index 28badf84..56c8b5eb 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/service/NotificationServiceTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/service/NotificationServiceTest.java @@ -386,6 +386,21 @@ class NotificationServiceTest { verify(notificationRepository, never()).findByRecipientIdOrderByCreatedAtDesc(any(), any()); } + @Test + void getNotifications_withTypeOnly_usesTypeFilteredRepoMethod() { + when(notificationRepository.findByRecipientIdAndTypeOrderByCreatedAtDesc( + eq(userA.getId()), eq(NotificationType.MENTION), any())) + .thenReturn(Page.empty()); + + notificationService.getNotifications(userA.getId(), NotificationType.MENTION, null, Pageable.ofSize(5)); + + verify(notificationRepository).findByRecipientIdAndTypeOrderByCreatedAtDesc( + eq(userA.getId()), eq(NotificationType.MENTION), any()); + verify(notificationRepository, never()).findByRecipientIdOrderByCreatedAtDesc(any(), any()); + verify(notificationRepository, never()) + .findByRecipientIdAndTypeAndReadFalseOrderByCreatedAtDesc(any(), any(), any()); + } + // ─── private helpers ────────────────────────────────────────────────────── private DocumentComment commentWithAuthor(UUID id, UUID parentId, UUID authorId, String authorName) { diff --git a/frontend/src/lib/components/DashboardMentions.svelte b/frontend/src/lib/components/DashboardMentions.svelte index 7339879d..ff6b9052 100644 --- a/frontend/src/lib/components/DashboardMentions.svelte +++ b/frontend/src/lib/components/DashboardMentions.svelte @@ -18,7 +18,7 @@ let { mentions }: Props = $props(); {#if mentions.length > 0}

- Erwähnungen + Benachrichtigungen

{#each mentions as mention (mention.id)}
@@ -28,6 +28,9 @@ let { mentions }: Props = $props(); class="font-serif text-sm text-ink hover:text-ink-2" > {mention.actorName ?? ''} + {#if mention.type === 'MENTION'}erwähnt Sie{:else}hat geantwortet{/if} {:else} {mention.actorName ?? ''} diff --git a/frontend/src/routes/+page.server.ts b/frontend/src/routes/+page.server.ts index 19a783eb..a3be30a1 100644 --- a/frontend/src/routes/+page.server.ts +++ b/frontend/src/routes/+page.server.ts @@ -58,13 +58,9 @@ export async function load({ url, fetch }) { if (isDashboard) { const [mentionsResult, incompleteResult, recentResult] = await Promise.allSettled([ - api.GET('/api/notifications', { - params: { query: { type: 'MENTION', read: false, size: 5 } } - }), + api.GET('/api/notifications', { params: { query: { size: 5 } } }), api.GET('/api/documents/incomplete', { params: { query: { size: 5 } } }), - api.GET('/api/documents/search', { - params: { query: { status: 'REVIEWED' } } - }) + api.GET('/api/documents/search', { params: { query: {} } }) ]); if (mentionsResult.status === 'fulfilled' && mentionsResult.value.response.ok) {