A social knowledge tool for researchers built on ATProto
at development 105 lines 2.6 kB view raw
1import { Result, ok, err } from '../../../../../shared/core/Result'; 2import { UseCase } from '../../../../../shared/core/UseCase'; 3import { 4 ICollectionQueryRepository, 5 CollectionSortField, 6 SortOrder, 7} from '../../../domain/ICollectionQueryRepository'; 8import { URL } from '../../../domain/value-objects/URL'; 9 10export interface GetCollectionsForUrlQuery { 11 url: string; 12 page?: number; 13 limit?: number; 14 sortBy?: CollectionSortField; 15 sortOrder?: SortOrder; 16} 17 18export interface CollectionForUrlDTO { 19 id: string; 20 uri?: string; 21 name: string; 22 description?: string; 23 authorId: string; 24} 25 26export interface GetCollectionsForUrlResult { 27 collections: CollectionForUrlDTO[]; 28 pagination: { 29 currentPage: number; 30 totalPages: number; 31 totalCount: number; 32 hasMore: boolean; 33 limit: number; 34 }; 35 sorting: { 36 sortBy: CollectionSortField; 37 sortOrder: SortOrder; 38 }; 39} 40 41export class ValidationError extends Error { 42 constructor(message: string) { 43 super(message); 44 this.name = 'ValidationError'; 45 } 46} 47 48export class GetCollectionsForUrlUseCase 49 implements 50 UseCase<GetCollectionsForUrlQuery, Result<GetCollectionsForUrlResult>> 51{ 52 constructor(private collectionQueryRepo: ICollectionQueryRepository) {} 53 54 async execute( 55 query: GetCollectionsForUrlQuery, 56 ): Promise<Result<GetCollectionsForUrlResult>> { 57 // Validate URL 58 const urlResult = URL.create(query.url); 59 if (urlResult.isErr()) { 60 return err( 61 new ValidationError(`Invalid URL: ${urlResult.error.message}`), 62 ); 63 } 64 65 // Set defaults 66 const page = query.page || 1; 67 const limit = Math.min(query.limit || 20, 100); // Cap at 100 68 const sortBy = query.sortBy || CollectionSortField.NAME; 69 const sortOrder = query.sortOrder || SortOrder.ASC; 70 71 try { 72 // Execute query to get collections containing cards with this URL 73 const result = await this.collectionQueryRepo.getCollectionsWithUrl( 74 query.url, 75 { 76 page, 77 limit, 78 sortBy, 79 sortOrder, 80 }, 81 ); 82 83 return ok({ 84 collections: result.items, 85 pagination: { 86 currentPage: page, 87 totalPages: Math.ceil(result.totalCount / limit), 88 totalCount: result.totalCount, 89 hasMore: result.hasMore, 90 limit, 91 }, 92 sorting: { 93 sortBy, 94 sortOrder, 95 }, 96 }); 97 } catch (error) { 98 return err( 99 new Error( 100 `Failed to retrieve collections for URL: ${error instanceof Error ? error.message : 'Unknown error'}`, 101 ), 102 ); 103 } 104 } 105}