mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-10 05:12:14 +00:00
coach: reopen an interrupted conversation with a visible retry
An aborted stream now leaves a trace on both ends. The unmount cleanup records the interrupted conversation (sessionStorage, one-shot) before the abort fires, and invalidates the cached thread + rail so the return visit refetches the advanced server state. The /coach page consumes the record on its next mount: a known id reopens that thread, a first-turn abort resolves via most-recent; every explicit entry intent (?c=, ?doc=, ?workout=, ?scope=, ?ask=) wins over the resume. The persisted cancelled marker renders as a muted interrupted note with an Ask-again action that resubmits the question through the normal send path and its gates. Localised in all six languages. Refs #781
This commit is contained in:
1 parent
9a631c8f8b
commit
13b7d0379b
13 files changed
+713
-230
No files matched your search
@@ -77,6 +77,35 @@ describe("Coach streaming lifecycle", () => {
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("the unmount cleanup records the interrupted conversation before the abort (#781)", () => {
|
||||
const source = read("components/insights/coach-panel/use-coach.ts");
|
||||
|
||||
// A cleanup that writes the resume value under the storage key. Without
|
||||
// it the unmount abort is silent again: the user returns to a blank new
|
||||
// chat with no route back to the interrupted thread.
|
||||
const recordsInterruption =
|
||||
/return\s*\(\)\s*=>\s*\{[\s\S]*?interruptedResumeValue\(\s*active\s*\)[\s\S]*?sessionStorage\.setItem\(\s*COACH_INTERRUPTED_STORAGE_KEY/.test(
|
||||
source,
|
||||
);
|
||||
expect(
|
||||
recordsInterruption,
|
||||
"use-coach.ts must record the interrupted conversation " +
|
||||
"(COACH_INTERRUPTED_STORAGE_KEY) in an unmount cleanup",
|
||||
).toBe(true);
|
||||
|
||||
// And the recording effect must be defined BEFORE the abort effect so
|
||||
// the flag is written while the send is still marked in flight.
|
||||
const recordIndex = source.indexOf("COACH_INTERRUPTED_STORAGE_KEY,\n");
|
||||
const abortIndex = source.indexOf("abortRef.current?.abort();\n };");
|
||||
expect(recordIndex).toBeGreaterThan(-1);
|
||||
expect(abortIndex).toBeGreaterThan(-1);
|
||||
expect(
|
||||
recordIndex < abortIndex,
|
||||
"the interruption-recording cleanup must be defined before the " +
|
||||
"mount-scoped abort cleanup",
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
it("handleNewChat still resets too — the two paths must not diverge again", () => {
|
||||
const source = read(
|
||||
"components/insights/coach-panel/coach-conversation.tsx",
|
||||
|
||||
Reference in new issue
Block a user