A social knowledge tool for researchers built on ATProto
1import { Result, ok, err } from '../../../../../shared/core/Result';
2import { UseCase } from '../../../../../shared/core/UseCase';
3import { UseCaseError } from '../../../../../shared/core/UseCaseError';
4import { AppError } from '../../../../../shared/core/AppError';
5import { CuratorId } from '../../../../cards/domain/value-objects/CuratorId';
6import { CardId } from '../../../../cards/domain/value-objects/CardId';
7import { CollectionId } from '../../../../cards/domain/value-objects/CollectionId';
8import { ActivityTypeEnum } from '../../../domain/value-objects/ActivityType';
9import { FeedService } from 'src/modules/feeds/domain/services/FeedService';
10
11export interface AddCardCollectedActivityDTO {
12 type: ActivityTypeEnum.CARD_COLLECTED;
13 actorId: string;
14 cardId: string;
15 collectionIds?: string[];
16}
17
18export type AddActivityToFeedDTO = AddCardCollectedActivityDTO;
19
20export interface AddActivityToFeedResponseDTO {
21 activityId: string;
22}
23
24export class ValidationError extends UseCaseError {
25 constructor(message: string) {
26 super(message);
27 }
28}
29
30export class AddActivityToFeedUseCase
31 implements
32 UseCase<
33 AddActivityToFeedDTO,
34 Result<
35 AddActivityToFeedResponseDTO,
36 ValidationError | AppError.UnexpectedError
37 >
38 >
39{
40 constructor(private feedService: FeedService) {}
41
42 async execute(
43 request: AddActivityToFeedDTO,
44 ): Promise<
45 Result<
46 AddActivityToFeedResponseDTO,
47 ValidationError | AppError.UnexpectedError
48 >
49 > {
50 try {
51 // Validate and create CuratorId
52 const actorIdResult = CuratorId.create(request.actorId);
53 if (actorIdResult.isErr()) {
54 return err(
55 new ValidationError(
56 `Invalid actor ID: ${actorIdResult.error.message}`,
57 ),
58 );
59 }
60 const actorId = actorIdResult.value;
61
62 // Validate and create CardId
63 const cardIdResult = CardId.createFromString(request.cardId);
64 if (cardIdResult.isErr()) {
65 return err(
66 new ValidationError(`Invalid card ID: ${cardIdResult.error.message}`),
67 );
68 }
69 const cardId = cardIdResult.value;
70
71 // Validate collection IDs if provided
72 let collectionIds: CollectionId[] | undefined;
73 if (request.collectionIds && request.collectionIds.length > 0) {
74 collectionIds = [];
75 for (const collectionIdStr of request.collectionIds) {
76 const collectionIdResult =
77 CollectionId.createFromString(collectionIdStr);
78 if (collectionIdResult.isErr()) {
79 return err(
80 new ValidationError(
81 `Invalid collection ID: ${collectionIdResult.error.message}`,
82 ),
83 );
84 }
85 collectionIds.push(collectionIdResult.value);
86 }
87 }
88
89 const activityResult = await this.feedService.addCardCollectedActivity(
90 actorId,
91 cardId,
92 collectionIds,
93 );
94
95 if (activityResult.isErr()) {
96 return err(new ValidationError(activityResult.error.message));
97 }
98
99 return ok({
100 activityId: activityResult.value.activityId.getStringValue(),
101 });
102 } catch (error) {
103 return err(AppError.UnexpectedError.create(error));
104 }
105 }
106}