A social knowledge tool for researchers built on ATProto
at development 145 lines 4.5 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 { CollectionId } from '../../../domain/value-objects/CollectionId'; 7import { CuratorId } from '../../../domain/value-objects/CuratorId'; 8import { CollectionName } from '../../../domain/value-objects/CollectionName'; 9import { CollectionDescription } from '../../../domain/value-objects/CollectionDescription'; 10import { ICollectionPublisher } from '../../ports/ICollectionPublisher'; 11 12export interface UpdateCollectionDTO { 13 collectionId: string; 14 name: string; 15 description?: string; 16 curatorId: string; 17} 18 19export interface UpdateCollectionResponseDTO { 20 collectionId: string; 21} 22 23export class ValidationError extends UseCaseError { 24 constructor(message: string) { 25 super(message); 26 } 27} 28 29export class UpdateCollectionUseCase 30 implements 31 UseCase< 32 UpdateCollectionDTO, 33 Result< 34 UpdateCollectionResponseDTO, 35 ValidationError | AppError.UnexpectedError 36 > 37 > 38{ 39 constructor( 40 private collectionRepository: ICollectionRepository, 41 private collectionPublisher: ICollectionPublisher, 42 ) {} 43 44 async execute( 45 request: UpdateCollectionDTO, 46 ): Promise< 47 Result< 48 UpdateCollectionResponseDTO, 49 ValidationError | AppError.UnexpectedError 50 > 51 > { 52 try { 53 // Validate and create CuratorId 54 const curatorIdResult = CuratorId.create(request.curatorId); 55 if (curatorIdResult.isErr()) { 56 return err( 57 new ValidationError( 58 `Invalid curator ID: ${curatorIdResult.error.message}`, 59 ), 60 ); 61 } 62 const curatorId = curatorIdResult.value; 63 64 // Validate and create CollectionId 65 const collectionIdResult = CollectionId.createFromString( 66 request.collectionId, 67 ); 68 if (collectionIdResult.isErr()) { 69 return err( 70 new ValidationError( 71 `Invalid collection ID: ${collectionIdResult.error.message}`, 72 ), 73 ); 74 } 75 const collectionId = collectionIdResult.value; 76 77 // Find the collection 78 const collectionResult = 79 await this.collectionRepository.findById(collectionId); 80 if (collectionResult.isErr()) { 81 return err(AppError.UnexpectedError.create(collectionResult.error)); 82 } 83 84 const collection = collectionResult.value; 85 if (!collection) { 86 return err( 87 new ValidationError(`Collection not found: ${request.collectionId}`), 88 ); 89 } 90 91 // Check if user is the author 92 if (!collection.authorId.equals(curatorId)) { 93 return err( 94 new ValidationError( 95 'Only the collection author can update the collection', 96 ), 97 ); 98 } 99 100 // Update collection details using domain method 101 const updateResult = collection.updateDetails( 102 request.name, 103 request.description, 104 ); 105 if (updateResult.isErr()) { 106 return err(new ValidationError(updateResult.error.message)); 107 } 108 109 // Save updated collection 110 const saveResult = await this.collectionRepository.save(collection); 111 if (saveResult.isErr()) { 112 return err(AppError.UnexpectedError.create(saveResult.error)); 113 } 114 115 // Republish collection if it was already published 116 if (collection.isPublished) { 117 const republishResult = 118 await this.collectionPublisher.publish(collection); 119 if (republishResult.isErr()) { 120 return err( 121 new ValidationError( 122 `Failed to republish collection: ${republishResult.error.message}`, 123 ), 124 ); 125 } 126 127 // Update published record ID 128 collection.markAsPublished(republishResult.value); 129 130 // Save collection with updated published record ID 131 const saveUpdatedResult = 132 await this.collectionRepository.save(collection); 133 if (saveUpdatedResult.isErr()) { 134 return err(AppError.UnexpectedError.create(saveUpdatedResult.error)); 135 } 136 } 137 138 return ok({ 139 collectionId: collection.collectionId.getStringValue(), 140 }); 141 } catch (error) { 142 return err(AppError.UnexpectedError.create(error)); 143 } 144 } 145}