This repository has no description
semble
/
src
/
modules
/
notifications
/
application
/
eventHandlers
/
CollectionContributionCleanupEventHandler.ts
3.0 kB
78 lines
1import { CardRemovedFromCollectionEvent } from '../../../cards/domain/events/CardRemovedFromCollectionEvent';
2import { IEventHandler } from '../../../../shared/application/events/IEventSubscriber';
3import { Result, ok } from '../../../../shared/core/Result';
4import { INotificationRepository } from '../../domain/INotificationRepository';
5import { ICollectionRepository } from '../../../cards/domain/ICollectionRepository';
6import { CuratorId } from '../../../cards/domain/value-objects/CuratorId';
7
8export class CollectionContributionCleanupEventHandler
9 implements IEventHandler<CardRemovedFromCollectionEvent>
10{
11 constructor(
12 private notificationRepository: INotificationRepository,
13 private collectionRepository: ICollectionRepository,
14 ) {}
15
16 async handle(event: CardRemovedFromCollectionEvent): Promise<Result<void>> {
17 try {
18 // 1. Get collection to determine the recipient (collection author)
19 const collectionResult = await this.collectionRepository.findById(
20 event.collectionId,
21 );
22 if (collectionResult.isErr() || !collectionResult.value) {
23 // Collection not found, skip cleanup
24 return ok(undefined);
25 }
26
27 const collection = collectionResult.value;
28 const recipientUserId = collection.authorId.value;
29
30 // 2. Find notifications for this card
31 // Note: We query by card only, not by actor, because the notification actor
32 // is the person who added the card (not necessarily who removed it)
33 const notificationsResult = await this.notificationRepository.findByCard(
34 event.cardId.getStringValue(),
35 );
36
37 if (notificationsResult.isErr()) {
38 console.error(
39 'Error fetching notifications for cleanup:',
40 notificationsResult.error,
41 );
42 return ok(undefined);
43 }
44
45 const notifications = notificationsResult.value;
46
47 // 4. Filter and delete matching notifications
48 for (const notification of notifications) {
49 // Check if this notification is USER_ADDED_TO_YOUR_COLLECTION type
50 // and the recipient matches the collection author
51 // and the collection ID is in the metadata
52 if (
53 notification.type.value === 'USER_ADDED_TO_YOUR_COLLECTION' &&
54 notification.recipientUserId.value === recipientUserId &&
55 notification.metadata.collectionIds?.includes(
56 event.collectionId.getStringValue(),
57 )
58 ) {
59 const deleteResult = await this.notificationRepository.delete(
60 notification.notificationId,
61 );
62 if (deleteResult.isErr()) {
63 console.error('Failed to delete notification:', deleteResult.error);
64 // Continue with other notifications even if one fails
65 }
66 }
67 }
68
69 return ok(undefined);
70 } catch (error) {
71 console.error(
72 'Error in CollectionContributionCleanupEventHandler:',
73 error,
74 );
75 return ok(undefined); // Don't fail the event processing
76 }
77 }
78}