diff --git a/frontend/src/pages/AssistantChatPage.tsx b/frontend/src/pages/AssistantChatPage.tsx index c709e39c..833d9cad 100644 --- a/frontend/src/pages/AssistantChatPage.tsx +++ b/frontend/src/pages/AssistantChatPage.tsx @@ -267,48 +267,9 @@ export default function AssistantChatPage() { } }, []) - // Phase 3: convenience helper — refresh fact list, active fix, and (if open) - // schedule a preview refresh. Called after every chat send so the new state - // (PROMOTE-synthesized facts, new SUGGEST_FIX) appears in the lane. - const refreshSessionDerived = useCallback(async (chatId: string) => { - await Promise.all([refreshFacts(chatId), refreshActiveFix(chatId)]) - if (previewOpen) schedulePreviewRefresh(chatId) - }, [refreshFacts, refreshActiveFix, previewOpen, schedulePreviewRefresh]) - - const handleAddNote = async (text: string, summary: string | null) => { - if (!activeChatId) return - try { - const fact = await sessionFactsApi.create(activeChatId, { text, summary }) - setFacts(prev => [...prev, fact]) - schedulePreviewRefresh(activeChatId) - } catch { - toast.error('Failed to add note') - } - } - - const handleUpdateFact = async (factId: string, text: string, summary: string | null) => { - if (!activeChatId) return - try { - const updated = await sessionFactsApi.update(activeChatId, factId, { text, summary }) - setFacts(prev => prev.map(f => f.id === factId ? updated : f)) - schedulePreviewRefresh(activeChatId) - } catch { - toast.error('Failed to update fact') - } - } - - const handleDeleteFact = async (factId: string) => { - if (!activeChatId) return - try { - await sessionFactsApi.remove(activeChatId, factId) - setFacts(prev => prev.filter(f => f.id !== factId)) - schedulePreviewRefresh(activeChatId) - } catch { - toast.error('Failed to remove fact') - } - } - // Phase 3 — active suggested fix + resolution-note preview. + // Declared BEFORE refreshSessionDerived / handleAddNote so the useCallback + // dep arrays don't hit a temporal dead zone on React's synchronous render. const refreshActiveFix = useCallback(async (chatId: string) => { try { const fix = await sessionSuggestedFixesApi.getActive(chatId) @@ -351,6 +312,47 @@ export default function AssistantChatPage() { }, 500) }, [previewOpen, refreshPreview]) + // Phase 3: convenience helper — refresh fact list, active fix, and (if open) + // schedule a preview refresh. Called after every chat send so the new state + // (PROMOTE-synthesized facts, new SUGGEST_FIX) appears in the lane. + const refreshSessionDerived = useCallback(async (chatId: string) => { + await Promise.all([refreshFacts(chatId), refreshActiveFix(chatId)]) + if (previewOpen) schedulePreviewRefresh(chatId) + }, [refreshFacts, refreshActiveFix, previewOpen, schedulePreviewRefresh]) + + const handleAddNote = async (text: string, summary: string | null) => { + if (!activeChatId) return + try { + const fact = await sessionFactsApi.create(activeChatId, { text, summary }) + setFacts(prev => [...prev, fact]) + schedulePreviewRefresh(activeChatId) + } catch { + toast.error('Failed to add note') + } + } + + const handleUpdateFact = async (factId: string, text: string, summary: string | null) => { + if (!activeChatId) return + try { + const updated = await sessionFactsApi.update(activeChatId, factId, { text, summary }) + setFacts(prev => prev.map(f => f.id === factId ? updated : f)) + schedulePreviewRefresh(activeChatId) + } catch { + toast.error('Failed to update fact') + } + } + + const handleDeleteFact = async (factId: string) => { + if (!activeChatId) return + try { + await sessionFactsApi.remove(activeChatId, factId) + setFacts(prev => prev.filter(f => f.id !== factId)) + schedulePreviewRefresh(activeChatId) + } catch { + toast.error('Failed to remove fact') + } + } + const handleDismissFix = async () => { if (!activeChatId || !activeFix) return try {