fix(#264): apiFetch — global X-Session-Id header (custom POI scoring в UI)

apiFetch и apiFetchWithStatus не передавали X-Session-Id header, из-за
чего POST /analyze возвращал custom_poi_score_items: [] и score без учёта
пользовательских POI. Добавлен withSessionHeader() helper с SSR guard;
user-supplied headers имеют приоритет (backward compat).
This commit is contained in:
lekss361 2026-05-17 10:31:54 +03:00
parent 26ee3b015c
commit 2d58c3a203

View file

@ -1,16 +1,38 @@
import { getOrCreateSessionId } from "@/lib/sessionId";
// Empty default = same-origin relative URLs.
// In prod Caddy proxies /api/* to backend; in dev Next.js rewrites do the same.
export const API_BASE_URL = process.env.NEXT_PUBLIC_API_BASE_URL ?? "";
/**
* Merges a global X-Session-Id header into the request init.
* Only runs in browser (SSR guard). User-supplied headers win over the
* auto-injected value so explicit overrides remain backward-compatible.
*/
function withSessionHeader(init?: RequestInit): RequestInit {
const base: RequestInit = init ?? {};
if (typeof window === "undefined") return base;
const sessionId = getOrCreateSessionId();
if (!sessionId) return base;
return {
...base,
headers: {
"X-Session-Id": sessionId,
...(base.headers ?? {}),
},
};
}
export async function apiFetch<T>(
path: string,
init?: RequestInit,
): Promise<T> {
const merged = withSessionHeader(init);
const response = await fetch(`${API_BASE_URL}${path}`, {
...init,
...merged,
headers: {
"Content-Type": "application/json",
...(init?.headers ?? {}),
...(merged.headers ?? {}),
},
});
if (!response.ok) {
@ -39,11 +61,12 @@ export async function apiFetchWithStatus<T>(
path: string,
init?: RequestInit,
): Promise<{ status: number; body: T }> {
const merged = withSessionHeader(init);
const response = await fetch(`${API_BASE_URL}${path}`, {
...init,
...merged,
headers: {
"Content-Type": "application/json",
...(init?.headers ?? {}),
...(merged.headers ?? {}),
},
});
let body: unknown = null;