A social knowledge tool for researchers built on ATProto
at development 111 lines 3.3 kB view raw
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 { ICollectionRepository } from '../../../domain/ICollectionRepository'; 6import { Collection, CollectionAccessType } from '../../../domain/Collection'; 7import { CuratorId } from '../../../domain/value-objects/CuratorId'; 8import { ICollectionPublisher } from '../../ports/ICollectionPublisher'; 9 10export interface CreateCollectionDTO { 11 name: string; 12 description?: string; 13 curatorId: string; 14} 15 16export interface CreateCollectionResponseDTO { 17 collectionId: string; 18} 19 20export class ValidationError extends UseCaseError { 21 constructor(message: string) { 22 super(message); 23 } 24} 25 26export class CreateCollectionUseCase 27 implements 28 UseCase< 29 CreateCollectionDTO, 30 Result< 31 CreateCollectionResponseDTO, 32 ValidationError | AppError.UnexpectedError 33 > 34 > 35{ 36 constructor( 37 private collectionRepository: ICollectionRepository, 38 private collectionPublisher: ICollectionPublisher, 39 ) {} 40 41 async execute( 42 request: CreateCollectionDTO, 43 ): Promise< 44 Result< 45 CreateCollectionResponseDTO, 46 ValidationError | AppError.UnexpectedError 47 > 48 > { 49 try { 50 // Validate and create CuratorId 51 const curatorIdResult = CuratorId.create(request.curatorId); 52 if (curatorIdResult.isErr()) { 53 return err( 54 new ValidationError( 55 `Invalid curator ID: ${curatorIdResult.error.message}`, 56 ), 57 ); 58 } 59 const curatorId = curatorIdResult.value; 60 61 // Create collection 62 const collectionResult = Collection.create({ 63 authorId: curatorId, 64 name: request.name, 65 description: request.description, 66 accessType: CollectionAccessType.CLOSED, 67 collaboratorIds: [], 68 createdAt: new Date(), 69 updatedAt: new Date(), 70 }); 71 72 if (collectionResult.isErr()) { 73 return err(new ValidationError(collectionResult.error.message)); 74 } 75 76 const collection = collectionResult.value; 77 78 // Save collection 79 const saveResult = await this.collectionRepository.save(collection); 80 if (saveResult.isErr()) { 81 return err(AppError.UnexpectedError.create(saveResult.error)); 82 } 83 84 // Publish collection 85 const publishResult = await this.collectionPublisher.publish(collection); 86 if (publishResult.isErr()) { 87 return err( 88 new ValidationError( 89 `Failed to publish collection: ${publishResult.error.message}`, 90 ), 91 ); 92 } 93 94 // Mark collection as published 95 collection.markAsPublished(publishResult.value); 96 97 // Save updated collection with published record ID 98 const saveUpdatedResult = 99 await this.collectionRepository.save(collection); 100 if (saveUpdatedResult.isErr()) { 101 return err(AppError.UnexpectedError.create(saveUpdatedResult.error)); 102 } 103 104 return ok({ 105 collectionId: collection.collectionId.getStringValue(), 106 }); 107 } catch (error) { 108 return err(AppError.UnexpectedError.create(error)); 109 } 110 } 111}