fix(search): correction recherche fuzzy catégories

- Backend : seuil word_similarity >= 0.4 (au lieu de > 0.4) sur cat.name
- Frontend : correction erreur TypeScript dans CategoryService.list()
  (params typé Record<string,string> pour satisfaire Angular HttpClient)
  — le code précédent ne compilait pas, la recherche était ignorée

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
This commit is contained in:
z3n
2026-06-19 13:31:49 +00:00
parent eb07ca085f
commit c8b3e393ea
2 changed files with 24 additions and 3 deletions

View File

@@ -22,7 +22,26 @@ export class CategoriesService {
private readonly apiRepo: Repository<ApiEntryEntity>, private readonly apiRepo: Repository<ApiEntryEntity>,
) {} ) {}
async findAll(): Promise<CategoryListResponse> { async findAll(search?: string): Promise<CategoryListResponse> {
if (search?.trim()) {
const text = search.trim();
const entities = await this.categoryRepo
.createQueryBuilder('cat')
.where(
`(
cat.name ILIKE :likeText
OR COALESCE(cat.description, '') ILIKE :likeText
OR word_similarity(:text, cat.name) >= 0.4
OR word_similarity(:text, COALESCE(cat.description, '')) > 0.5
)`,
{ likeText: `%${text}%`, text },
)
.orderBy('cat.order_index', 'ASC')
.addOrderBy('cat.name', 'ASC')
.getMany();
return { items: entities.map(toCategory) };
}
const entities = await this.categoryRepo.find({ const entities = await this.categoryRepo.find({
order: { orderIndex: 'ASC', name: 'ASC' }, order: { orderIndex: 'ASC', name: 'ASC' },
}); });

View File

@@ -12,8 +12,10 @@ export class CategoryService {
private http = inject(HttpClient); private http = inject(HttpClient);
private baseUrl = '/api/categories'; private baseUrl = '/api/categories';
list(): Observable<CategoryListResponse> { list(search?: string): Observable<CategoryListResponse> {
return this.http.get<CategoryListResponse>(this.baseUrl); const params: Record<string, string> = {};
if (search?.trim()) params['search'] = search;
return this.http.get<CategoryListResponse>(this.baseUrl, { params });
} }
browse(id: string | null): Observable<CategoryBrowseResponse> { browse(id: string | null): Observable<CategoryBrowseResponse> {