Files
baya-monorepo/client/src/services/search/keys.ts
T
2026-07-09 04:09:35 +03:30

38 lines
1.9 KiB
TypeScript

import type { NurseSearchFilters } from './types';
/**
* React Query key factory for the search domain.
*
* **The filter object IS the query key** (phase §5, the caching contract). `results(filters)` keys on a
* **canonical** serialization of the full filter object — a stable key order with every *absent* optional
* filter omitted (never carried as `undefined`). Two filter sets that are semantically equal therefore
* produce the identical key, so changing a filter and **reverting** to a previous set is a cache hit with
* zero network calls (React Query hashes query keys deterministically; canonicalizing here makes the
* intent explicit and keeps the URL/query-param serialization aligned with the cache key).
*/
/** Canonical, order-stable filter object with absent optionals omitted (the cache key + query params). */
export function canonicalizeSearchFilters(filters: NurseSearchFilters): Record<string, string | number> {
const canonical: Record<string, string | number> = {
serviceCategoryId: filters.serviceCategoryId,
cityId: filters.cityId,
sort: filters.sort,
page: filters.page,
pageSize: filters.pageSize,
};
if (filters.districtId != null) canonical.districtId = filters.districtId;
if (filters.nurseGender != null) canonical.nurseGender = filters.nurseGender;
if (filters.priceMin != null && filters.priceMin !== '') canonical.priceMin = filters.priceMin;
if (filters.priceMax != null && filters.priceMax !== '') canonical.priceMax = filters.priceMax;
if (filters.priceUnit != null) canonical.priceUnit = filters.priceUnit;
return canonical;
}
export const searchKeys = {
all: ['search'] as const,
results: (filters: NurseSearchFilters) =>
[...searchKeys.all, 'results', canonicalizeSearchFilters(filters)] as const,
profiles: () => [...searchKeys.all, 'profile'] as const,
profile: (nurseId: number) => [...searchKeys.profiles(), nurseId] as const,
};