import { InitiateOAuthSignInUseCase } from '../../../../modules/user/application/use-cases/InitiateOAuthSignInUseCase'; import { CompleteOAuthSignInUseCase } from '../../../../modules/user/application/use-cases/CompleteOAuthSignInUseCase'; import { RefreshAccessTokenUseCase } from '../../../../modules/user/application/use-cases/RefreshAccessTokenUseCase'; import { AddUrlToLibraryUseCase } from '../../../../modules/cards/application/useCases/commands/AddUrlToLibraryUseCase'; import { AddCardToLibraryUseCase } from '../../../../modules/cards/application/useCases/commands/AddCardToLibraryUseCase'; import { AddCardToCollectionUseCase } from '../../../../modules/cards/application/useCases/commands/AddCardToCollectionUseCase'; import { UpdateNoteCardUseCase } from '../../../../modules/cards/application/useCases/commands/UpdateNoteCardUseCase'; import { UpdateUrlCardAssociationsUseCase } from '../../../../modules/cards/application/useCases/commands/UpdateUrlCardAssociationsUseCase'; import { RemoveCardFromLibraryUseCase } from '../../../../modules/cards/application/useCases/commands/RemoveCardFromLibraryUseCase'; import { RemoveCardFromCollectionUseCase } from '../../../../modules/cards/application/useCases/commands/RemoveCardFromCollectionUseCase'; import { GetUrlMetadataUseCase } from '../../../../modules/cards/application/useCases/queries/GetUrlMetadataUseCase'; import { GetUrlCardViewUseCase } from '../../../../modules/cards/application/useCases/queries/GetUrlCardViewUseCase'; import { GetLibrariesForCardUseCase } from '../../../../modules/cards/application/useCases/queries/GetLibrariesForCardUseCase'; import { GetUrlCardsUseCase } from '../../../../modules/cards/application/useCases/queries/GetUrlCardsUseCase'; import { CreateCollectionUseCase } from '../../../../modules/cards/application/useCases/commands/CreateCollectionUseCase'; import { UpdateCollectionUseCase } from '../../../../modules/cards/application/useCases/commands/UpdateCollectionUseCase'; import { DeleteCollectionUseCase } from '../../../../modules/cards/application/useCases/commands/DeleteCollectionUseCase'; import { GetCollectionPageUseCase } from '../../../../modules/cards/application/useCases/queries/GetCollectionPageUseCase'; import { Repositories } from './RepositoryFactory'; import { Services, SharedServices } from './ServiceFactory'; import { GetProfileUseCase } from 'src/modules/cards/application/useCases/queries/GetProfileUseCase'; import { LoginWithAppPasswordUseCase } from 'src/modules/user/application/use-cases/LoginWithAppPasswordUseCase'; import { LogoutUseCase } from 'src/modules/user/application/use-cases/LogoutUseCase'; import { GenerateExtensionTokensUseCase } from 'src/modules/user/application/use-cases/GenerateExtensionTokensUseCase'; import { GetGlobalFeedUseCase } from '../../../../modules/feeds/application/useCases/queries/GetGlobalFeedUseCase'; import { GetGemActivityFeedUseCase } from '../../../../modules/feeds/application/useCases/queries/GetGemActivityFeedUseCase'; import { AddActivityToFeedUseCase } from '../../../../modules/feeds/application/useCases/commands/AddActivityToFeedUseCase'; import { GetCollectionsUseCase } from 'src/modules/cards/application/useCases/queries/GetCollectionsUseCase'; import { SearchCollectionsUseCase } from 'src/modules/cards/application/useCases/queries/SearchCollectionsUseCase'; import { GetOpenCollectionsWithContributorUseCase } from 'src/modules/cards/application/useCases/queries/GetOpenCollectionsWithContributorUseCase'; import { GetCollectionPageByAtUriUseCase } from 'src/modules/cards/application/useCases/queries/GetCollectionPageByAtUriUseCase'; import { GetUrlStatusForMyLibraryUseCase } from '../../../../modules/cards/application/useCases/queries/GetUrlStatusForMyLibraryUseCase'; import { GetLibrariesForUrlUseCase } from '../../../../modules/cards/application/useCases/queries/GetLibrariesForUrlUseCase'; import { GetCollectionsForUrlUseCase } from '../../../../modules/cards/application/useCases/queries/GetCollectionsForUrlUseCase'; import { GetNoteCardsForUrlUseCase } from '../../../../modules/cards/application/useCases/queries/GetNoteCardsForUrlUseCase'; import { IndexUrlForSearchUseCase } from '../../../../modules/search/application/useCases/commands/IndexUrlForSearchUseCase'; import { GetSimilarUrlsForUrlUseCase } from '../../../../modules/search/application/useCases/queries/GetSimilarUrlsForUrlUseCase'; import { SemanticSearchUrlsUseCase } from '../../../../modules/search/application/useCases/queries/SemanticSearchUrlsUseCase'; import { SearchBskyPostsForUrlUseCase } from '../../../../modules/search/application/use-cases/SearchBskyPostsForUrlUseCase'; import { SearchAtProtoAccountsUseCase } from '../../../../modules/search/application/use-cases/SearchAtProtoAccountsUseCase'; import { SearchLeafletDocsForUrlUseCase } from '../../../../modules/search/application/use-cases/SearchLeafletDocsForUrlUseCase'; import { ProcessCardFirehoseEventUseCase } from '../../../../modules/atproto/application/useCases/ProcessCardFirehoseEventUseCase'; import { ProcessCollectionFirehoseEventUseCase } from '../../../../modules/atproto/application/useCases/ProcessCollectionFirehoseEventUseCase'; import { ProcessCollectionLinkFirehoseEventUseCase } from '../../../../modules/atproto/application/useCases/ProcessCollectionLinkFirehoseEventUseCase'; import { ProcessMarginBookmarkFirehoseEventUseCase } from '../../../../modules/atproto/application/useCases/ProcessMarginBookmarkFirehoseEventUseCase'; import { ProcessMarginCollectionFirehoseEventUseCase } from '../../../../modules/atproto/application/useCases/ProcessMarginCollectionFirehoseEventUseCase'; import { ProcessMarginCollectionItemFirehoseEventUseCase } from '../../../../modules/atproto/application/useCases/ProcessMarginCollectionItemFirehoseEventUseCase'; import { ProcessCollectionLinkRemovalFirehoseEventUseCase } from '../../../../modules/atproto/application/useCases/ProcessCollectionLinkRemovalFirehoseEventUseCase'; import { GetMyNotificationsUseCase } from '../../../../modules/notifications/application/useCases/queries/GetMyNotificationsUseCase'; import { GetUnreadNotificationCountUseCase } from '../../../../modules/notifications/application/useCases/queries/GetUnreadNotificationCountUseCase'; import { MarkNotificationsAsReadUseCase } from '../../../../modules/notifications/application/useCases/commands/MarkNotificationsAsReadUseCase'; import { MarkAllNotificationsAsReadUseCase } from '../../../../modules/notifications/application/useCases/commands/MarkAllNotificationsAsReadUseCase'; import { CreateNotificationUseCase } from '../../../../modules/notifications/application/useCases/commands/CreateNotificationUseCase'; import { SyncAccountDataUseCase } from '../../../../modules/sync/application/useCases/SyncAccountDataUseCase'; export interface WorkerUseCases { addActivityToFeedUseCase: AddActivityToFeedUseCase; indexUrlForSearchUseCase: IndexUrlForSearchUseCase; createNotificationUseCase: CreateNotificationUseCase; syncAccountDataUseCase: SyncAccountDataUseCase; // Firehose-specific use cases addUrlToLibraryUseCase: AddUrlToLibraryUseCase; updateUrlCardAssociationsUseCase: UpdateUrlCardAssociationsUseCase; removeCardFromLibraryUseCase: RemoveCardFromLibraryUseCase; createCollectionUseCase: CreateCollectionUseCase; updateCollectionUseCase: UpdateCollectionUseCase; deleteCollectionUseCase: DeleteCollectionUseCase; processCardFirehoseEventUseCase: ProcessCardFirehoseEventUseCase; processCollectionFirehoseEventUseCase: ProcessCollectionFirehoseEventUseCase; processCollectionLinkFirehoseEventUseCase: ProcessCollectionLinkFirehoseEventUseCase; processMarginBookmarkFirehoseEventUseCase: ProcessMarginBookmarkFirehoseEventUseCase; processMarginCollectionFirehoseEventUseCase: ProcessMarginCollectionFirehoseEventUseCase; processMarginCollectionItemFirehoseEventUseCase: ProcessMarginCollectionItemFirehoseEventUseCase; processCollectionLinkRemovalFirehoseEventUseCase: ProcessCollectionLinkRemovalFirehoseEventUseCase; } export interface UseCases { // User use cases loginWithAppPasswordUseCase: LoginWithAppPasswordUseCase; logoutUseCase: LogoutUseCase; initiateOAuthSignInUseCase: InitiateOAuthSignInUseCase; completeOAuthSignInUseCase: CompleteOAuthSignInUseCase; getProfileUseCase: GetProfileUseCase; refreshAccessTokenUseCase: RefreshAccessTokenUseCase; generateExtensionTokensUseCase: GenerateExtensionTokensUseCase; // Card use cases addUrlToLibraryUseCase: AddUrlToLibraryUseCase; addCardToLibraryUseCase: AddCardToLibraryUseCase; addCardToCollectionUseCase: AddCardToCollectionUseCase; updateNoteCardUseCase: UpdateNoteCardUseCase; updateUrlCardAssociationsUseCase: UpdateUrlCardAssociationsUseCase; removeCardFromLibraryUseCase: RemoveCardFromLibraryUseCase; removeCardFromCollectionUseCase: RemoveCardFromCollectionUseCase; getUrlMetadataUseCase: GetUrlMetadataUseCase; getUrlCardViewUseCase: GetUrlCardViewUseCase; getLibrariesForCardUseCase: GetLibrariesForCardUseCase; getMyUrlCardsUseCase: GetUrlCardsUseCase; createCollectionUseCase: CreateCollectionUseCase; updateCollectionUseCase: UpdateCollectionUseCase; deleteCollectionUseCase: DeleteCollectionUseCase; getCollectionPageUseCase: GetCollectionPageUseCase; getCollectionPageByAtUriUseCase: GetCollectionPageByAtUriUseCase; getCollectionsUseCase: GetCollectionsUseCase; searchCollectionsUseCase: SearchCollectionsUseCase; getOpenCollectionsWithContributorUseCase: GetOpenCollectionsWithContributorUseCase; getUrlStatusForMyLibraryUseCase: GetUrlStatusForMyLibraryUseCase; getLibrariesForUrlUseCase: GetLibrariesForUrlUseCase; getCollectionsForUrlUseCase: GetCollectionsForUrlUseCase; getNoteCardsForUrlUseCase: GetNoteCardsForUrlUseCase; // Feed use cases getGlobalFeedUseCase: GetGlobalFeedUseCase; getGemActivityFeedUseCase: GetGemActivityFeedUseCase; addActivityToFeedUseCase: AddActivityToFeedUseCase; // Search use cases getSimilarUrlsForUrlUseCase: GetSimilarUrlsForUrlUseCase; semanticSearchUrlsUseCase: SemanticSearchUrlsUseCase; searchBskyPostsForUrlUseCase: SearchBskyPostsForUrlUseCase; searchAtProtoAccountsUseCase: SearchAtProtoAccountsUseCase; searchLeafletDocsForUrlUseCase: SearchLeafletDocsForUrlUseCase; // Notification use cases getMyNotificationsUseCase: GetMyNotificationsUseCase; getUnreadNotificationCountUseCase: GetUnreadNotificationCountUseCase; markNotificationsAsReadUseCase: MarkNotificationsAsReadUseCase; markAllNotificationsAsReadUseCase: MarkAllNotificationsAsReadUseCase; } export class UseCaseFactory { static create(repositories: Repositories, services: Services): UseCases { return this.createForWebApp(repositories, services); } static createForWebApp( repositories: Repositories, services: Services, ): UseCases { const getCollectionPageUseCase = new GetCollectionPageUseCase( repositories.collectionRepository, repositories.cardQueryRepository, services.profileService, ); return { // User use cases loginWithAppPasswordUseCase: new LoginWithAppPasswordUseCase( services.appPasswordProcessor, services.tokenService, repositories.userRepository, services.userAuthService, ), logoutUseCase: new LogoutUseCase(services.tokenService), initiateOAuthSignInUseCase: new InitiateOAuthSignInUseCase( services.oauthProcessor, ), completeOAuthSignInUseCase: new CompleteOAuthSignInUseCase( services.oauthProcessor, services.tokenService, repositories.userRepository, services.userAuthService, ), getProfileUseCase: new GetProfileUseCase( services.profileService, services.identityResolutionService, ), refreshAccessTokenUseCase: new RefreshAccessTokenUseCase( services.tokenService, ), generateExtensionTokensUseCase: new GenerateExtensionTokensUseCase( services.tokenService, ), // Card use cases addUrlToLibraryUseCase: new AddUrlToLibraryUseCase( repositories.cardRepository, services.metadataService, services.cardLibraryService, services.cardCollectionService, services.eventPublisher, ), addCardToLibraryUseCase: new AddCardToLibraryUseCase( repositories.cardRepository, services.cardLibraryService, services.cardCollectionService, ), addCardToCollectionUseCase: new AddCardToCollectionUseCase( repositories.cardRepository, services.cardCollectionService, services.eventPublisher, ), updateNoteCardUseCase: new UpdateNoteCardUseCase( repositories.cardRepository, services.cardPublisher, ), updateUrlCardAssociationsUseCase: new UpdateUrlCardAssociationsUseCase( repositories.cardRepository, services.cardLibraryService, services.cardCollectionService, services.eventPublisher, ), removeCardFromLibraryUseCase: new RemoveCardFromLibraryUseCase( repositories.cardRepository, services.cardLibraryService, services.eventPublisher, ), removeCardFromCollectionUseCase: new RemoveCardFromCollectionUseCase( repositories.cardRepository, services.cardCollectionService, services.eventPublisher, ), getUrlMetadataUseCase: new GetUrlMetadataUseCase( services.metadataService, repositories.cardRepository, ), getUrlCardViewUseCase: new GetUrlCardViewUseCase( repositories.cardQueryRepository, services.profileService, repositories.collectionRepository, ), getLibrariesForCardUseCase: new GetLibrariesForCardUseCase( repositories.cardQueryRepository, services.profileService, ), getMyUrlCardsUseCase: new GetUrlCardsUseCase( repositories.cardQueryRepository, services.identityResolutionService, services.profileService, ), createCollectionUseCase: new CreateCollectionUseCase( repositories.collectionRepository, services.collectionPublisher, ), updateCollectionUseCase: new UpdateCollectionUseCase( repositories.collectionRepository, services.collectionPublisher, ), deleteCollectionUseCase: new DeleteCollectionUseCase( repositories.collectionRepository, services.collectionPublisher, ), getCollectionPageUseCase, getCollectionPageByAtUriUseCase: new GetCollectionPageByAtUriUseCase( services.identityResolutionService, repositories.atUriResolutionService, getCollectionPageUseCase, services.configService.getAtProtoCollections().collection, services.configService.getAtProtoCollections().marginCollection, ), getCollectionsUseCase: new GetCollectionsUseCase( repositories.collectionQueryRepository, services.profileService, services.identityResolutionService, ), searchCollectionsUseCase: new SearchCollectionsUseCase( repositories.collectionQueryRepository, services.profileService, services.identityResolutionService, ), getOpenCollectionsWithContributorUseCase: new GetOpenCollectionsWithContributorUseCase( repositories.collectionQueryRepository, services.profileService, services.identityResolutionService, ), getUrlStatusForMyLibraryUseCase: new GetUrlStatusForMyLibraryUseCase( repositories.cardRepository, repositories.cardQueryRepository, repositories.collectionQueryRepository, repositories.collectionRepository, services.profileService, services.eventPublisher, ), getLibrariesForUrlUseCase: new GetLibrariesForUrlUseCase( repositories.cardQueryRepository, services.profileService, ), getCollectionsForUrlUseCase: new GetCollectionsForUrlUseCase( repositories.collectionQueryRepository, services.profileService, repositories.collectionRepository, ), getNoteCardsForUrlUseCase: new GetNoteCardsForUrlUseCase( repositories.cardQueryRepository, services.profileService, ), // Feed use cases getGlobalFeedUseCase: new GetGlobalFeedUseCase( repositories.feedRepository, services.profileService, repositories.cardQueryRepository, repositories.collectionRepository, ), getGemActivityFeedUseCase: new GetGemActivityFeedUseCase( repositories.feedRepository, services.profileService, repositories.cardQueryRepository, repositories.collectionRepository, repositories.collectionQueryRepository, ), addActivityToFeedUseCase: new AddActivityToFeedUseCase( services.feedService, repositories.cardRepository, repositories.followsRepository, repositories.feedRepository, ), // Search use cases getSimilarUrlsForUrlUseCase: new GetSimilarUrlsForUrlUseCase( services.searchService, ), semanticSearchUrlsUseCase: new SemanticSearchUrlsUseCase( services.searchService, services.identityResolutionService, ), searchBskyPostsForUrlUseCase: new SearchBskyPostsForUrlUseCase( services.atProtoAgentService, ), searchAtProtoAccountsUseCase: new SearchAtProtoAccountsUseCase( services.atProtoAgentService, ), searchLeafletDocsForUrlUseCase: new SearchLeafletDocsForUrlUseCase( services.leafletSearchService, repositories.cardQueryRepository, ), // Notification use cases getMyNotificationsUseCase: new GetMyNotificationsUseCase( repositories.notificationRepository, services.profileService, repositories.cardQueryRepository, repositories.collectionRepository, ), getUnreadNotificationCountUseCase: new GetUnreadNotificationCountUseCase( repositories.notificationRepository, ), markNotificationsAsReadUseCase: new MarkNotificationsAsReadUseCase( repositories.notificationRepository, ), markAllNotificationsAsReadUseCase: new MarkAllNotificationsAsReadUseCase( repositories.notificationRepository, ), }; } static createForWorker( repositories: Repositories, services: SharedServices, ): WorkerUseCases { // ======================================== // LEVEL 1: Leaf use cases (no use case dependencies) // ======================================== // Feed use cases const addActivityToFeedUseCase = new AddActivityToFeedUseCase( services.feedService, repositories.cardRepository, repositories.followsRepository, repositories.feedRepository, ); // Search use cases const indexUrlForSearchUseCase = new IndexUrlForSearchUseCase( services.searchService, ); // Notification use cases const createNotificationUseCase = new CreateNotificationUseCase( services.notificationService, ); // Card library use cases const addUrlToLibraryUseCase = new AddUrlToLibraryUseCase( repositories.cardRepository, services.metadataService, services.cardLibraryService, services.cardCollectionService, services.eventPublisher, ); const updateUrlCardAssociationsUseCase = new UpdateUrlCardAssociationsUseCase( repositories.cardRepository, services.cardLibraryService, services.cardCollectionService, services.eventPublisher, ); const removeCardFromLibraryUseCase = new RemoveCardFromLibraryUseCase( repositories.cardRepository, services.cardLibraryService, services.eventPublisher, ); // Collection use cases const createCollectionUseCase = new CreateCollectionUseCase( repositories.collectionRepository, services.collectionPublisher, ); const updateCollectionUseCase = new UpdateCollectionUseCase( repositories.collectionRepository, services.collectionPublisher, ); const deleteCollectionUseCase = new DeleteCollectionUseCase( repositories.collectionRepository, services.collectionPublisher, ); // ======================================== // LEVEL 2: Process use cases (depend on Level 1) // ======================================== const processCardFirehoseEventUseCase = new ProcessCardFirehoseEventUseCase( repositories.atUriResolutionService, addUrlToLibraryUseCase, updateUrlCardAssociationsUseCase, removeCardFromLibraryUseCase, repositories.cardRepository, ); const processCollectionFirehoseEventUseCase = new ProcessCollectionFirehoseEventUseCase( repositories.atUriResolutionService, createCollectionUseCase, updateCollectionUseCase, deleteCollectionUseCase, ); const processCollectionLinkFirehoseEventUseCase = new ProcessCollectionLinkFirehoseEventUseCase( repositories.atUriResolutionService, updateUrlCardAssociationsUseCase, ); const processCollectionLinkRemovalFirehoseEventUseCase = new ProcessCollectionLinkRemovalFirehoseEventUseCase( repositories.atUriResolutionService, updateUrlCardAssociationsUseCase, ); const processMarginBookmarkFirehoseEventUseCase = new ProcessMarginBookmarkFirehoseEventUseCase( repositories.atUriResolutionService, addUrlToLibraryUseCase, removeCardFromLibraryUseCase, ); const processMarginCollectionFirehoseEventUseCase = new ProcessMarginCollectionFirehoseEventUseCase( repositories.atUriResolutionService, createCollectionUseCase, updateCollectionUseCase, deleteCollectionUseCase, ); const processMarginCollectionItemFirehoseEventUseCase = new ProcessMarginCollectionItemFirehoseEventUseCase( repositories.atUriResolutionService, updateUrlCardAssociationsUseCase, ); // ======================================== // LEVEL 3: Sync use cases (depend on Level 2) // ======================================== const syncAccountDataUseCase = new SyncAccountDataUseCase( repositories.syncStatusRepository, services.atProtoRepoService, repositories.atUriResolutionService, processMarginBookmarkFirehoseEventUseCase, processMarginCollectionFirehoseEventUseCase, processMarginCollectionItemFirehoseEventUseCase, ); // ======================================== // Return all use cases // ======================================== return { // Level 1 addActivityToFeedUseCase, indexUrlForSearchUseCase, createNotificationUseCase, addUrlToLibraryUseCase, updateUrlCardAssociationsUseCase, removeCardFromLibraryUseCase, createCollectionUseCase, updateCollectionUseCase, deleteCollectionUseCase, // Level 2 processCardFirehoseEventUseCase, processCollectionFirehoseEventUseCase, processCollectionLinkFirehoseEventUseCase, processCollectionLinkRemovalFirehoseEventUseCase, processMarginBookmarkFirehoseEventUseCase, processMarginCollectionFirehoseEventUseCase, processMarginCollectionItemFirehoseEventUseCase, // Level 3 syncAccountDataUseCase, }; } }