feat: FlowPilot migration — Phase 1-9 + Phase 9 bug fixes + QA fixture harness #147
@@ -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.
|
// 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) => {
|
const refreshActiveFix = useCallback(async (chatId: string) => {
|
||||||
try {
|
try {
|
||||||
const fix = await sessionSuggestedFixesApi.getActive(chatId)
|
const fix = await sessionSuggestedFixesApi.getActive(chatId)
|
||||||
@@ -351,6 +312,47 @@ export default function AssistantChatPage() {
|
|||||||
}, 500)
|
}, 500)
|
||||||
}, [previewOpen, refreshPreview])
|
}, [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 () => {
|
const handleDismissFix = async () => {
|
||||||
if (!activeChatId || !activeFix) return
|
if (!activeChatId || !activeFix) return
|
||||||
try {
|
try {
|
||||||
|
|||||||
Reference in New Issue
Block a user