Files
fusion/packages/dashboard/app/components/__tests__/PlanningModeModal.dedupeSessionsById.test.ts
gsxdsm dab1569ac3 FN-5892: dedupe planning sessions and persist history deletion
Prevent duplicate planning-history rows and keep deletions visible only after the backend confirms persistence.

- dedupe Planning Mode history by session id across initial loads, live updates, archive toggles, and draft creation
- make deleteAiSession surface backend/content-type errors instead of silently succeeding on failed deletes
- keep failed history deletions visible, refresh the list, and show an error toast when persistence fails
- add dashboard tests covering session deduplication, delete API failures, and persistence-aware Planning Mode deletion behavior
- document the history dedupe/delete semantics and add a patch changeset for @runfusion/fusion

Files changed:
 .changeset/fn-5892-planning-history-fix.md         |   5 +
 docs/dashboard-guide.md                            |   2 +-
 packages/dashboard/app/api/__tests__/deleteAiSession.test.ts      |  54 +++++
 packages/dashboard/app/api/legacy.ts               |  41 +++-
 packages/dashboard/app/components/PlanningModeModal.tsx |  70 ++++---
 packages/dashboard/app/components/__tests__/PlanningModeModal.autosize.test.tsx  |  11 +
 packages/dashboard/app/components/__tests__/PlanningModeModal.dedupeSessionsById.test.ts   |  44 ++++
 packages/dashboard/app/components/__tests__/PlanningModeModal.initial.test.tsx   |  11 +
 packages/dashboard/app/components/__tests__/PlanningModeModal.planning-flow.test.tsx       | 226 ++++++++++++++++++++-
 packages/dashboard/app/components/__tests__/PlanningModeModal.test-helpers.ts    |   1 +
 10 files changed, 439 insertions(+), 26 deletions(-)

Fusion-Task-Id: FN-5892

Fusion-Task-Lineage: 7453bc34-6d57-4d67-ac92-8fb50084fbee
2026-06-02 12:42:04 -07:00

45 lines
1.5 KiB
TypeScript

import { describe, expect, it } from "vitest";
import type { AiSessionSummary } from "../../api";
import { dedupeSessionsById } from "../PlanningModeModal";
function makeSession(id: string, updatedAt: string, title = id): AiSessionSummary {
return {
id,
type: "planning",
status: "complete",
title,
projectId: null,
lockedByTab: null,
updatedAt,
archived: false,
};
}
describe("dedupeSessionsById", () => {
it("keeps the most recently updated session for duplicate ids", () => {
const sessions = [
makeSession("session-1", "2026-01-01T00:00:00.000Z", "older"),
makeSession("session-2", "2026-01-03T00:00:00.000Z", "second"),
makeSession("session-1", "2026-01-04T00:00:00.000Z", "newer"),
];
expect(dedupeSessionsById(sessions)).toEqual([
makeSession("session-1", "2026-01-04T00:00:00.000Z", "newer"),
makeSession("session-2", "2026-01-03T00:00:00.000Z", "second"),
]);
});
it("preserves stable newest-first ordering when timestamps tie", () => {
const sessions = [
makeSession("session-a", "2026-01-02T00:00:00.000Z", "first"),
makeSession("session-b", "2026-01-02T00:00:00.000Z", "second"),
makeSession("session-a", "2026-01-02T00:00:00.000Z", "ignored duplicate"),
];
expect(dedupeSessionsById(sessions)).toEqual([
makeSession("session-a", "2026-01-02T00:00:00.000Z", "first"),
makeSession("session-b", "2026-01-02T00:00:00.000Z", "second"),
]);
});
});