https://project.mdnd-it.cc/work_packages/94
This commit is contained in:
2025-08-23 04:25:28 +02:00
parent 725516ad6c
commit 19cfa031d0
25823 changed files with 1095587 additions and 2801760 deletions
@@ -0,0 +1,144 @@
import { IUserRepository } from '../../Domain/IRepository/IUserRepository';
import { IOrganizationRepository } from '../../Domain/IRepository/IOrganizationRepository';
import { IDeckRepository } from '../../Domain/IRepository/IDeckRepository';
import { SearchQuery, SearchResult } from '../DTOs/SearchDto';
import { ShortUserDto, DetailUserDto } from '../DTOs/UserDto';
import { ShortOrganizationDto, DetailOrganizationDto } from '../DTOs/OrganizationDto';
import { ShortDeckDto, DetailDeckDto } from '../DTOs/DeckDto';
import { UserMapper } from '../DTOs/Mappers/UserMapper';
import { OrganizationMapper } from '../DTOs/Mappers/OrganizationMapper';
import { DeckMapper } from '../DTOs/Mappers/DeckMapper';
export type SearchType = 'users' | 'organizations' | 'decks';
export interface IGeneralSearchService {
searchUsers(searchQuery: SearchQuery): Promise<SearchResult<ShortUserDto>>;
searchOrganizations(searchQuery: SearchQuery): Promise<SearchResult<ShortOrganizationDto>>;
searchDecks(searchQuery: SearchQuery): Promise<SearchResult<ShortDeckDto>>;
searchByType(searchType: SearchType, searchQuery: SearchQuery): Promise<SearchResult<ShortUserDto | ShortOrganizationDto | ShortDeckDto>>;
}
export class GeneralSearchService implements IGeneralSearchService {
constructor(
private userRepo: IUserRepository,
private organizationRepo: IOrganizationRepository,
private deckRepo: IDeckRepository
) {}
static getSearchTypeFromUrl(url: string): SearchType {
if (url.includes('/users/') || url.includes('/api/users/')) {
return 'users';
} else if (url.includes('/organizations/') || url.includes('/api/organizations/')) {
return 'organizations';
} else if (url.includes('/decks/') || url.includes('/api/decks/')) {
return 'decks';
}
return 'users';
}
async searchUsers(searchQuery: SearchQuery): Promise<SearchResult<ShortUserDto>> {
const { query, limit = 20, offset = 0 } = searchQuery;
if (!query || query.trim().length === 0) {
return {
results: [],
totalCount: 0,
hasMore: false,
searchQuery: query,
searchType: 'users'
};
}
try {
const { users, totalCount } = await this.userRepo.search(query.trim(), limit, offset);
const results = users.map(user => UserMapper.toShortDto(user));
const hasMore = (offset + limit) < totalCount;
return {
results,
totalCount,
hasMore,
searchQuery: query,
searchType: 'users'
};
} catch (error) {
throw new Error('Failed to search users');
}
}
async searchOrganizations(searchQuery: SearchQuery): Promise<SearchResult<ShortOrganizationDto>> {
const { query, limit = 20, offset = 0 } = searchQuery;
if (!query || query.trim().length === 0) {
return {
results: [],
totalCount: 0,
hasMore: false,
searchQuery: query,
searchType: 'organizations'
};
}
const { organizations, totalCount } = await this.organizationRepo.search(query.trim(), limit, offset);
const results = organizations.map(org => OrganizationMapper.toShortDto(org));
const hasMore = (offset + limit) < totalCount;
return {
results,
totalCount,
hasMore,
searchQuery: query,
searchType: 'organizations'
};
}
async searchDecks(searchQuery: SearchQuery): Promise<SearchResult<ShortDeckDto>> {
const { query, limit = 20, offset = 0 } = searchQuery;
if (!query || query.trim().length === 0) {
return {
results: [],
totalCount: 0,
hasMore: false,
searchQuery: query,
searchType: 'decks'
};
}
const { decks, totalCount } = await this.deckRepo.search(query.trim(), limit, offset);
const results = decks.map(deck => DeckMapper.toShortDto(deck));
const hasMore = (offset + limit) < totalCount;
return {
results,
totalCount,
hasMore,
searchQuery: query,
searchType: 'decks'
};
}
async searchByType(
searchType: SearchType,
searchQuery: SearchQuery
): Promise<SearchResult<ShortUserDto | ShortOrganizationDto | ShortDeckDto>> {
switch (searchType) {
case 'users':
return await this.searchUsers(searchQuery) as SearchResult<ShortUserDto | ShortOrganizationDto | ShortDeckDto>;
case 'organizations':
return await this.searchOrganizations(searchQuery) as SearchResult<ShortUserDto | ShortOrganizationDto | ShortDeckDto>;
case 'decks':
return await this.searchDecks(searchQuery) as SearchResult<ShortUserDto | ShortOrganizationDto | ShortDeckDto>;
default:
throw new Error(`Unsupported search type: ${searchType}`);
}
}
async searchFromUrl(
url: string,
searchQuery: SearchQuery
): Promise<SearchResult<ShortUserDto | ShortOrganizationDto | ShortDeckDto>> {
const searchType = GeneralSearchService.getSearchTypeFromUrl(url);
return await this.searchByType(searchType, searchQuery);
}
}