diff --git a/src/modules/cards/application/useCases/queries/GetUrlStatusForMyLibraryUseCase.ts b/src/modules/cards/application/useCases/queries/GetUrlStatusForMyLibraryUseCase.ts index da33d774..407e6ab3 100644 --- a/src/modules/cards/application/useCases/queries/GetUrlStatusForMyLibraryUseCase.ts +++ b/src/modules/cards/application/useCases/queries/GetUrlStatusForMyLibraryUseCase.ts @@ -15,9 +15,9 @@ export interface GetUrlStatusForMyLibraryQuery { export interface CollectionInfo { id: string; - uri: string; + uri?: string; name: string; - description: string; + description?: string; } export interface GetUrlStatusForMyLibraryResult { @@ -33,7 +33,10 @@ export class ValidationError extends UseCaseError { export class GetUrlStatusForMyLibraryUseCase extends BaseUseCase< GetUrlStatusForMyLibraryQuery, - Result + Result< + GetUrlStatusForMyLibraryResult, + ValidationError | AppError.UnexpectedError + > > { constructor( private cardRepository: ICardRepository, @@ -73,10 +76,8 @@ export class GetUrlStatusForMyLibraryUseCase extends BaseUseCase< const url = urlResult.value; // Check if user has a URL card with this URL - const existingCardResult = await this.cardRepository.findUsersUrlCardByUrl( - url, - curatorId, - ); + const existingCardResult = + await this.cardRepository.findUsersUrlCardByUrl(url, curatorId); if (existingCardResult.isErr()) { return err(AppError.UnexpectedError.create(existingCardResult.error)); } @@ -87,24 +88,23 @@ export class GetUrlStatusForMyLibraryUseCase extends BaseUseCase< if (card) { result.cardId = card.cardId.getStringValue(); - // TODO: Need to extend ICollectionQueryRepository with method to get collections containing a specific card for a user - // For now, we'll note this limitation - // const collectionsResult = await this.collectionQueryRepository.getCollectionsContainingCardForUser( - // card.cardId, - // curatorId, - // ); - // if (collectionsResult.isErr()) { - // return err(AppError.UnexpectedError.create(collectionsResult.error)); - // } - // result.collections = collectionsResult.value.map(collection => ({ - // id: collection.id, - // uri: collection.uri, - // name: collection.name, - // description: collection.description, - // })); + // Get collections containing this card for the user + try { + const collections = + await this.collectionQueryRepository.getCollectionsContainingCardForUser( + card.cardId.getStringValue(), + curatorId.value, + ); - // Placeholder for collections - will need repository extension - result.collections = []; + result.collections = collections.map((collection) => ({ + id: collection.id, + uri: collection.uri, + name: collection.name, + description: collection.description, + })); + } catch (error) { + return err(AppError.UnexpectedError.create(error)); + } } return ok(result); diff --git a/src/modules/cards/domain/ICollectionQueryRepository.ts b/src/modules/cards/domain/ICollectionQueryRepository.ts index 830f8581..fe36974c 100644 --- a/src/modules/cards/domain/ICollectionQueryRepository.ts +++ b/src/modules/cards/domain/ICollectionQueryRepository.ts @@ -36,9 +36,22 @@ export interface CollectionQueryResultDTO { authorId: string; // Just the curator ID, not enriched data } +// View data for collections containing a specific card +export interface CollectionContainingCardDTO { + id: string; + uri?: string; + name: string; + description?: string; +} + export interface ICollectionQueryRepository { findByCreator( curatorId: string, options: CollectionQueryOptions, ): Promise>; + + getCollectionsContainingCardForUser( + cardId: string, + curatorId: string, + ): Promise; } diff --git a/src/modules/cards/tests/utils/InMemoryCollectionQueryRepository.ts b/src/modules/cards/tests/utils/InMemoryCollectionQueryRepository.ts index 8cacb1fd..ce28e729 100644 --- a/src/modules/cards/tests/utils/InMemoryCollectionQueryRepository.ts +++ b/src/modules/cards/tests/utils/InMemoryCollectionQueryRepository.ts @@ -1,8 +1,8 @@ -import { Result, ok, err } from '../../../../shared/core/Result'; import { ICollectionQueryRepository, CollectionQueryOptions, CollectionQueryResultDTO, + CollectionContainingCardDTO, PaginatedQueryResult, CollectionSortField, SortOrder, @@ -116,6 +116,45 @@ export class InMemoryCollectionQueryRepository return sorted; } + async getCollectionsContainingCardForUser( + cardId: string, + curatorId: string, + ): Promise { + try { + // Get all collections and filter by creator + const allCollections = this.collectionRepository.getAllCollections(); + const creatorCollections = allCollections.filter( + (collection) => collection.authorId.value === curatorId, + ); + + // Filter collections that contain the specified card + const collectionsWithCard = creatorCollections.filter((collection) => + collection.cardLinks.some( + (link) => link.cardId.getStringValue() === cardId, + ), + ); + + // Transform to DTOs + const result: CollectionContainingCardDTO[] = collectionsWithCard.map( + (collection) => { + const collectionPublishedRecordId = collection.publishedRecordId; + return { + id: collection.collectionId.getStringValue(), + uri: collectionPublishedRecordId?.uri, + name: collection.name.value, + description: collection.description?.value, + }; + }, + ); + + return result; + } catch (error) { + throw new Error( + `Failed to get collections containing card: ${error instanceof Error ? error.message : String(error)}`, + ); + } + } + clear(): void { // No separate state to clear }