bug(#254): useSiteAnalysis не передаёт X-Session-Id → custom POI не учитываются в analyze #264

Closed
opened 2026-05-17 07:28:08 +00:00 by lekss361 · 0 comments
Owner

Симптом

После добавления custom POI с весом UI "Вклад по категориям" не обновляется. Backend response не содержит custom POIs в score_breakdown_detailed потому что header X-Session-Id отсутствует в request.

Воспроизведение

  1. На /site-finder ввести cad 66:41:0204016:10
  2. Add custom POI с weight=-5 на расстоянии ~100m от парcел (через + Добавить точку)
  3. Refresh analyze → score breakdown НЕ показывает добавленную точку

Доказательство

Backend работает правильно — manual call с правильным session_id возвращает custom POIs:

fetch('/api/v1/parcels/66:41:0204016:10/analyze', {
  method:'POST', headers:{'X-Session-Id': '4a573b35-db0f-...'}
})
→ score: 1.87 (без X-Session-Id → 13.81)
→ custom_poi_score_items: 3 items
→ score_breakdown_detailed: 72 entries (включая 3 с category='custom_poi')

Backend correctly добавляет custom POIs в factors_detailed (parcels.py:2003-2004).

Root cause

frontend/src/hooks/useSiteAnalysis.tsmutationFn использует apiFetchWithStatus / apiFetch БЕЗ X-Session-Id header. Только useCustomPois.ts (CRUD) передаёт header.

// useSiteAnalysis.ts:105
const first = await apiFetchWithStatus<...>(analyzeUrl(cad), {
  method: "POST",
  // ← NO X-Session-Id header
  ...(bodyPayload ? { body, headers: { 'Content-Type': 'application/json' } } : {}),
});

Fix

Two options:

В frontend/src/lib/api.ts — auto-добавить X-Session-Id: getOrCreateSessionId() для всех requests. Тогда любой endpoint получит session header без явного передавать. Backward compat — backend игнорирует если endpoint не использует.

Option B: Per-hook

В useSiteAnalysis.ts — импорт getOrCreateSessionId + добавить header в оба apiFetch calls (line 105 + line 145).

import { getOrCreateSessionId } from "@/lib/sessionId";

const sessionId = getOrCreateSessionId();
const baseHeaders: Record<string, string> = { "X-Session-Id": sessionId };
if (bodyPayload) baseHeaders["Content-Type"] = "application/json";

const first = await apiFetchWithStatus<...>(analyzeUrl(cad), {
  method: "POST",
  body: bodyPayload,
  headers: baseHeaders,
});

Дополнительно проверить

После fix:

  • useAddCustomPoi / useUpdateCustomPoi / useDeleteCustomPoi mutations должны invalidate ["analyze", cad] query чтобы UI пере-fetch'ил с custom POI. Worker сказал это сделано (useCustomPois.ts), но verify что invalidation срабатывает с правильным cad.

Acceptance

  • После добавления custom POI weight=-5 в 100m от cad — score падает в UI
  • ScoreBreakdownStackedBar показывает "Custom POI" категорию (или "Custom: имя")
  • Top-3 минусы / плюсы — включают custom POI если они в top
  • Mutations invalidate analyze → автоматический refetch

Severity

🟠 P1 — фича #254 visually НЕ работает на проде, хотя backend correctly интегрирован. Макс не увидит влияние своих custom POIs.

Effort

~30 минут (Option A — 5 строк в api.ts ; Option B — 10 строк в useSiteAnalysis.ts)

(QA discovery 2026-05-17 07:25 UTC после deploy PR #257+#258 + smoke с реальными user POIs)

## Симптом После добавления custom POI с весом UI "Вклад по категориям" не обновляется. Backend response не содержит custom POIs в `score_breakdown_detailed` потому что **header X-Session-Id отсутствует в request**. ## Воспроизведение 1. На /site-finder ввести cad `66:41:0204016:10` 2. Add custom POI с weight=-5 на расстоянии ~100m от парcел (через `+ Добавить точку`) 3. Refresh analyze → score breakdown НЕ показывает добавленную точку ## Доказательство Backend работает правильно — manual call с правильным session_id возвращает custom POIs: ``` fetch('/api/v1/parcels/66:41:0204016:10/analyze', { method:'POST', headers:{'X-Session-Id': '4a573b35-db0f-...'} }) → score: 1.87 (без X-Session-Id → 13.81) → custom_poi_score_items: 3 items → score_breakdown_detailed: 72 entries (включая 3 с category='custom_poi') ``` Backend correctly добавляет custom POIs в `factors_detailed` (parcels.py:2003-2004). ## Root cause `frontend/src/hooks/useSiteAnalysis.ts` — `mutationFn` использует `apiFetchWithStatus` / `apiFetch` БЕЗ X-Session-Id header. Только `useCustomPois.ts` (CRUD) передаёт header. ```typescript // useSiteAnalysis.ts:105 const first = await apiFetchWithStatus<...>(analyzeUrl(cad), { method: "POST", // ← NO X-Session-Id header ...(bodyPayload ? { body, headers: { 'Content-Type': 'application/json' } } : {}), }); ``` ## Fix Two options: ### Option A: Global header в `apiFetch` (RECOMMENDED) В `frontend/src/lib/api.ts` — auto-добавить `X-Session-Id: getOrCreateSessionId()` для всех requests. Тогда любой endpoint получит session header без явного передавать. Backward compat — backend игнорирует если endpoint не использует. ### Option B: Per-hook В `useSiteAnalysis.ts` — импорт `getOrCreateSessionId` + добавить header в **оба** apiFetch calls (line 105 + line 145). ```typescript import { getOrCreateSessionId } from "@/lib/sessionId"; const sessionId = getOrCreateSessionId(); const baseHeaders: Record<string, string> = { "X-Session-Id": sessionId }; if (bodyPayload) baseHeaders["Content-Type"] = "application/json"; const first = await apiFetchWithStatus<...>(analyzeUrl(cad), { method: "POST", body: bodyPayload, headers: baseHeaders, }); ``` ## Дополнительно проверить После fix: - `useAddCustomPoi` / `useUpdateCustomPoi` / `useDeleteCustomPoi` mutations должны invalidate `["analyze", cad]` query чтобы UI пере-fetch'ил с custom POI. Worker сказал это сделано (`useCustomPois.ts`), но verify что invalidation срабатывает с правильным cad. ## Acceptance - [ ] После добавления custom POI weight=-5 в 100m от cad — score падает в UI - [ ] ScoreBreakdownStackedBar показывает "Custom POI" категорию (или "Custom: имя") - [ ] Top-3 минусы / плюсы — включают custom POI если они в top - [ ] Mutations invalidate analyze → автоматический refetch ## Severity 🟠 **P1** — фича #254 visually НЕ работает на проде, хотя backend correctly интегрирован. Макс не увидит влияние своих custom POIs. ## Effort ~30 минут (Option A — 5 строк в api.ts ; Option B — 10 строк в useSiteAnalysis.ts) (QA discovery 2026-05-17 07:25 UTC после deploy PR #257+#258 + smoke с реальными user POIs)
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: lekss361/gendesign#264
No description provided.