Quick Chat now restores the persisted session id without same-target auto-init replacing it. - Wait for persisted session lookup before auto-initializing the selected quick chat target. - Skip the first same-target switch after restoring an existing session so the restored id remains authoritative. - Prefer message activity over metadata-only updates when falling back from stale persisted sessions. - Cover model, agent, and mobile restoration paths plus hook-level same-target replay behavior. - Document the quick chat last-session restoration regression and invariant. Files changed: docs/solutions/ui-bugs/quick-chat-last-opened-session-restore.md | 60 ++++++++++ packages/dashboard/app/components/QuickChatFAB.tsx | 23 +++- packages/dashboard/app/components/__tests__/QuickChatFAB.test.tsx | 130 ++++++++++++++++++++- packages/dashboard/app/hooks/__tests__/useQuickChat.test.ts | 38 ++++++ 4 files changed, 246 insertions(+), 5 deletions(-) Fusion-Task-Id: FN-6510 Fusion-Task-Lineage: 135807dd-30f3-4032-9de8-f34927e5c44d
3.2 KiB
title, date, category, module, problem_type, component, applies_when, symptoms, root_cause, resolution_type, severity, related_components, tags
| title | date | category | module | problem_type | component | applies_when | symptoms | root_cause | resolution_type | severity | related_components | tags | |||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Quick Chat last-opened session restore | 2026-06-17 | ui-bugs | packages/dashboard/app/components/QuickChatFAB | ui_bug | frontend_quick_chat | Quick Chat restores direct chat sessions after reloads, project switches, or a cold FAB open while session fetching is still in flight. |
|
automatic_same_target_resolution_raced_persisted_id_restore | code_fix | medium |
|
|
Quick Chat last-opened session restore
Problem
Quick Chat stores the last opened direct session in fusion:quick-chat-last-session:<projectId>. A cold open can request sessions and models at the same time. If automatic target initialization (switchSession / startModelChat) runs before the session list returns, it can resolve a same-target session from the server, set it active, and trigger the hook's active-session persistence effect. That overwrites the persisted id before the restore effect can find the user's exact last-opened session.
This failure is easy to miss when tests only use different targets. The important repro has two active sessions sharing the same agent or model target, with the persisted session not being the newest/touched one for that target.
Solution
Treat the persisted id as the source of truth until the initial direct-session restore has either used it or proven it stale.
- While a persisted last-session id exists and the initial session fetch is still loading, do not run automatic target initialization.
- When a session is restored from the list, skip the first automatic same-target switch. Restore is id-specific; same target is not equivalent.
- For stale or missing persisted ids, rank fallback sessions by
lastMessageAtbeforeupdatedAtso metadata-only updates do not displace the latest real conversation. - Keep chat rooms separate from direct-session restore; room active state should not feed the last direct-session key.
Regression coverage
Use DOM tests around QuickChatFAB for the real symptom because the race spans component restore effects, model/agent target selection, and the useQuickChat persistence effect.
Cover:
- Agent-backed and model-backed same-target collisions.
- Delayed session fetches where auto-init would previously clobber
localStorage. - Valid, stale/missing, and archived persisted ids.
- Empty/single/multiple session lists.
- Fresh render, warm close/reopen, project switch, desktop FAB, and mobile FAB paths.
- Hook-level same-target replay (
selectSessionfollowed byswitchSessionfor the same target) so the active id and persisted id remain the selected session.