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