f9b7ba2424
Builds the FE against the SDK<->FE Clarity-Gate contract (board 2026-07-01 /
advisor-clarity-gate-contract). The advisor is now a CASE, not a chat:
- Request {question, context?}; response {mode: clarify|answer, clarity, general_answer,
answer, evidence, citations, visual_evidence, footnotes}.
- clarify mode: short L1 general answer (marked "allgemeine Definition, ohne Rechtsquelle")
+ domain context chips; picking a chip re-runs the case scoped (-> answer).
- answer mode: markdown answer with clickable [n] citation markers coupled to evidence
cards (highlight + scroll), evidence grouped by document family, visual_evidence
(visual_type), footnotes, honest summary counts (no trust score).
- FE never parses the answer for structure — only the deliberate [n] markers, mapped via
citations[]. New: contract.ts, useAdvisorCase, useCitationHighlight, ClarifyView,
EvidenceUnitCard, VisualEvidencePane, CaseView. Removed the v2 stream/chat components.
NOT deployed: FE shape-switch (JSON modes) must deploy TOGETHER with the SDK endpoint
delivering the contract (board deploy-coupling). Proxy/route.ts unchanged (SDK-owned).
tsc clean, 16 vitest (incl. clarify+answer fixtures), check-loc 0.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
35 lines
1.0 KiB
TypeScript
35 lines
1.0 KiB
TypeScript
'use client'
|
|
|
|
import { useState } from 'react'
|
|
import type { Citation } from '@/lib/sdk/advisor/contract'
|
|
import type { CiteHandler } from './Markdown'
|
|
|
|
/**
|
|
* Couples answer [n] markers to evidence cards: clicking [n] highlights + scrolls to the referenced
|
|
* evidence unit. Works across layout columns via the card's DOM id (ev-<evidence_id>).
|
|
*/
|
|
export function useCitationHighlight(citations: Citation[]): {
|
|
highlightedId?: string
|
|
cite?: CiteHandler
|
|
} {
|
|
const [highlightedId, setHighlightedId] = useState<string | undefined>()
|
|
if (citations.length === 0) return { highlightedId }
|
|
return {
|
|
highlightedId,
|
|
cite: {
|
|
count: citations.length,
|
|
onSelect: (n: number) => {
|
|
const c = citations[n - 1]
|
|
if (!c) return
|
|
setHighlightedId(c.evidence_id)
|
|
if (typeof document !== 'undefined') {
|
|
document.getElementById(`ev-${c.evidence_id}`)?.scrollIntoView({
|
|
behavior: 'smooth',
|
|
block: 'center',
|
|
})
|
|
}
|
|
},
|
|
},
|
|
}
|
|
}
|