feat(FN-3626): migrate plugin storage to project-scoped storage

Migrated the dependency-graph plugin's storage layer to use the project's scoped storage API (`projectStorage`) and added canonical storage-key assertions. The ChatView.tsx utility reference was updated to match the new storage path.

Fusion-Task-Id: FN-3626
This commit is contained in:
Fusion
2026-05-06 22:11:09 -07:00
committed by gsxdsm
parent 1de4844369
commit f8abef2858
5 changed files with 22 additions and 11 deletions

View File

@@ -20,12 +20,22 @@ describe("storage", () => {
localStorage.clear();
});
it("builds project-scoped key", () => {
expect(projectScopedKey("proj_123")).toBe("kb:proj_123:dependency-graph-positions");
it("builds project-scoped key with canonical base key", () => {
expect(projectScopedKey("proj_123")).toBe("kb:proj_123:fusion-plugin-dependency-graph:positions");
});
it("falls back to unscoped key when projectId is missing or empty", () => {
expect(projectScopedKey()).toBe("fusion-plugin-dependency-graph:positions");
expect(projectScopedKey("")).toBe("fusion-plugin-dependency-graph:positions");
});
it("persists and restores positions", () => {
savePositions("proj_123", { "FN-1": { x: 10, y: 20 } });
expect(loadPositions("proj_123")).toEqual({ "FN-1": { x: 10, y: 20 } });
});
it("returns empty object for invalid JSON", () => {
localStorage.setItem("kb:proj_123:fusion-plugin-dependency-graph:positions", "not-json");
expect(loadPositions("proj_123")).toEqual({});
});
});

View File

@@ -1,14 +1,14 @@
const BASE_KEY = "dependency-graph-positions";
import { getScopedItem, scopedKey, setScopedItem } from "../../../packages/dashboard/app/utils/projectStorage";
const BASE_KEY = "fusion-plugin-dependency-graph:positions";
export function projectScopedKey(projectId?: string): string {
const suffix = projectId ?? "default";
return `kb:${suffix}:${BASE_KEY}`;
return scopedKey(BASE_KEY, projectId);
}
export function loadPositions(projectId?: string): Record<string, { x: number; y: number }> {
if (typeof window === "undefined") return {};
try {
const raw = window.localStorage.getItem(projectScopedKey(projectId));
const raw = getScopedItem(BASE_KEY, projectId);
if (!raw) return {};
const parsed = JSON.parse(raw) as Record<string, { x: number; y: number }>;
return parsed ?? {};
@@ -18,6 +18,5 @@ export function loadPositions(projectId?: string): Record<string, { x: number; y
}
export function savePositions(projectId: string | undefined, positions: Record<string, { x: number; y: number }>): void {
if (typeof window === "undefined") return;
window.localStorage.setItem(projectScopedKey(projectId), JSON.stringify(positions));
setScopedItem(BASE_KEY, JSON.stringify(positions), projectId);
}