feat(site-finder): grounded parcel-chat panel UI (#958) #1174

Merged
bot-backend merged 1 commit from feat/chat-ui-958 into main 2026-06-08 13:10:09 +00:00
Collaborator

Summary

First slice of #958 — the parcel-chat UI panel, consuming the just-shipped chat backend (#957). Mounts on site-finder/analysis/[cad] below the §22 forecast section (chat sits below the data it grounds on).

  • ChatPanel.tsx ("use client"): textarea + send, history-aware thread (cap 10 turns), 5 preset-intent quick-buttons (Сводка / Что строить / Почему такой прогноз / Риски / Сценарии), Enter-to-send / Shift+Enter newline.
  • postChatAsk in site-finder-api.ts via the shared apiFetch (base URL + X-Session-Id inherited). Types inline (codegen targets unreachable localhost in this env) — match the backend contract field-for-field.
  • Surfaces: advisory badge (advisory=true), grounded_in provenance ("источник: разделы … · run #N", toLocaleString("ru")), subtle «Детерминированный ответ» marker when llm_used=false.
  • States: loading, report_status="pending" → neutral "запустите анализ" turn (NOT an error), network error → role="alert" + retry.

The LLM prose path lights up once LLM_ENABLED=true + key in prod; until then the panel shows the deterministic chat answers (which work now).

Test plan

  • npm run lint → clean; npx tsc --noEmit → clean
  • vitest run ChatPanel.test.tsx6 passed (render, preset-button sends correct intent+cad_num, advisory/provenance render, pending-not-error, error-retry-refires, free-text submit)
  • code-reviewer APPROVE (no any / no useEffect-HTTP / no XSS / no inline hex / no emoji / no dep drift; contract exact)
  • visual smoke: /site-finder/analysis/<cad> → "Чат по участку" panel — preset buttons, advisory/provenance on a real answer, pending message for a no-forecast parcel

Conventions

Tokens-only (no inline hex), Lucide icons (no emoji), <Badge>/Section patterns, TanStack useMutation (no useEffect-for-HTTP), TS strict (no any), XSS-safe plain-text rendering, a11y (label/aria/focus/role=alert). No new dependency (package.json/lockfile untouched).

Scope / next

Chat UI only. Did NOT touch the horizon-selector (needs parcels.py — other dev) or build the broader forecast/scenario display screens (separate follow-up).

Refs #958

## Summary First slice of #958 — the **parcel-chat UI panel**, consuming the just-shipped chat backend (#957). Mounts on `site-finder/analysis/[cad]` below the §22 forecast section (chat sits below the data it grounds on). - `ChatPanel.tsx` (`"use client"`): textarea + send, history-aware thread (cap 10 turns), **5 preset-intent quick-buttons** (Сводка / Что строить / Почему такой прогноз / Риски / Сценарии), Enter-to-send / Shift+Enter newline. - `postChatAsk` in `site-finder-api.ts` via the shared `apiFetch` (base URL + X-Session-Id inherited). **Types inline** (codegen targets unreachable localhost in this env) — match the backend contract field-for-field. - Surfaces: **advisory badge** (advisory=true), **grounded_in provenance** ("источник: разделы … · run #N", `toLocaleString("ru")`), subtle **«Детерминированный ответ»** marker when `llm_used=false`. - States: loading, `report_status="pending"` → neutral "запустите анализ" turn (NOT an error), network error → `role="alert"` + retry. The LLM prose path lights up once `LLM_ENABLED=true` + key in prod; until then the panel shows the deterministic chat answers (which work now). ## Test plan - [x] `npm run lint` → clean; `npx tsc --noEmit` → clean - [x] `vitest run ChatPanel.test.tsx` → **6 passed** (render, preset-button sends correct intent+cad_num, advisory/provenance render, pending-not-error, error-retry-refires, free-text submit) - [x] code-reviewer ✅ APPROVE (no any / no useEffect-HTTP / no XSS / no inline hex / no emoji / no dep drift; contract exact) - [ ] visual smoke: `/site-finder/analysis/<cad>` → "Чат по участку" panel — preset buttons, advisory/provenance on a real answer, pending message for a no-forecast parcel ## Conventions Tokens-only (no inline hex), Lucide icons (no emoji), `<Badge>`/Section patterns, TanStack `useMutation` (no useEffect-for-HTTP), TS strict (no `any`), XSS-safe plain-text rendering, a11y (label/aria/focus/role=alert). **No new dependency** (package.json/lockfile untouched). ## Scope / next Chat UI only. Did NOT touch the horizon-selector (needs parcels.py — other dev) or build the broader forecast/scenario display screens (separate follow-up). Refs #958
bot-backend added 1 commit 2026-06-08 13:08:26 +00:00
feat(site-finder): grounded parcel-chat panel UI (#958)
All checks were successful
CI / changes (push) Successful in 6s
CI / backend-tests (push) Has been skipped
CI / backend-tests (pull_request) Has been skipped
CI / frontend-tests (push) Successful in 45s
CI / frontend-tests (pull_request) Successful in 42s
Deploy / changes (push) Successful in 5s
Deploy / build-backend (push) Has been skipped
Deploy / build-worker (push) Has been skipped
Deploy / build-frontend (push) Successful in 2m43s
Deploy / deploy (push) Successful in 1m4s
CI / changes (pull_request) Successful in 6s
4adfef2ad0
Chat panel on the analysis screen consuming POST /api/v1/chat/ask:
preset-intent quick-buttons (summary/what_to_build/why_forecast/risks/
scenarios), history-aware turns (cap 10), advisory badge + grounded_in
provenance + llm_used marker. Plain-text answer rendering (no HTML
injection); loading/pending/error states with retry. TanStack useMutation
(no useEffect-for-HTTP), tokens-only, Lucide icons, TS strict. Types inline
(codegen backend unreachable in env); no new dependency.

Refs #958
bot-backend merged commit 4adfef2ad0 into main 2026-06-08 13:10:09 +00:00
Sign in to join this conversation.
No reviewers
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#1174
No description provided.