Gallery→Workspace→Editor→Save creates a duplicate gallery row instead of updating the original — sessionStorage bridge carries the snapshot but not the design id #152
Labels
No labels
blocked:commit-ready-failed
blocked:gate-fetch
blocked:gate-lint
blocked:gate-plan
blocked:gate-research
blocked:needs-attention
blocked:needs-decision
blocked:needs-human
blocked:no-changes
blocked:verify-failed
bug
deferred
feature-request
in-progress
needs-decompose
needs-triage
quickfix
security/medium
triage-approved
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Mark/Kimi_Agent_Brother_10_Digitizing_App#152
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Finding
The Gallery → Workspace → Editor → Save flow creates a duplicate gallery row instead of updating the original. The root cause is that the bridge between Gallery and Workspace (
sessionStoragekeytc_load_design_snapshot) carries the design'ssnapshot(stitch geometry) but not the design'sid(gallery row identifier).The flow:
design-1737000000)sessionStorage(tc_load_design_snapshot), navigates to/workspace(src/pages/Gallery.tsx:158-168)LOAD_DESIGN(src/components/workspace/useWorkspace.ts:551-590); the design ID is lost/editortc_workspace_snapshot, per #110)saveCurrentDesignatsrc/components/workspace/useWorkspace.ts:1045-1140); the save constructs a new design withid: 'design-${Date.now()}'(line 1096)If the user opens design A, edits, saves, opens B from gallery, edits, saves — they have A, B, C, D. The gallery fills with one-off rows that aren't connected to their lineage.
Where
src/pages/Gallery.tsx:158-168src/components/workspace/useWorkspace.ts:551-590src/pages/Editor.tsx:188-210src/components/workspace/useWorkspace.ts:1096Suggested fix shape
Three changes:
Extend the Gallery→Workspace bridge to carry the design id. In
Gallery.tsx:158-168, write{ id, snapshot, designSettings }instead of just the snapshot. Update the Workspace's mount effect atuseWorkspace.ts:551-590to dispatch the id into state.Add a
loadedDesignIdfield toWorkspaceState(or a transientlastLoadedDesignIdthat the save handler reads). WhensaveCurrentDesignruns, if the workspace has aloadedDesignId:folderId,isFavorite,createdAt).loadedDesignIdafter the save so subsequent saves create new rows.Same change for the Editor→Workspace bridge at #110: have the Editor carry the id through its sessionStorage write so a round-trip from Gallery → Editor → Save updates the original row, not a new one.
Severity
High. Every save from the editor creates a gallery row that's a near-duplicate of its parent. The gallery fills with stale copies.
Discovered by
Gap analysis (2026-10-02) of editor/gallery/save integration.
Related
Fixed in commit
91a00aaon origin/main.Three coordinated changes:
Bridge payloads now carry the gallery row id. Gallery→Workspace writes
{ id, snapshot }instead of baresnapshot; same envelope for Gallery→Editor and the Editor→Workspace round-trip. The Workspace mount effect accepts both shapes (id optional, snapshot may be nested or top-level) for back-compat with the existing #74 / #110 tests.WorkspaceStatecarriesloadedDesignId: string | nullset byLOAD_DESIGN. A newSET_LOADED_DESIGN_IDaction clears the binding after success so a follow-up save creates a fresh row (save-as).saveDesignToGallery(the helper #150 extracted for the Editor Save button) now threadsloadedDesignIdand routes the save through a newupdateDesignhelper when the id matches an existing row. The result carriesupdated: booleanso callers can surface an "Updated" vs "Saved" toast. BothWorkspace.saveCurrentDesignandEditor.handleSavenow share this primitive.Backwards compat: bare-snapshot payloads (no id, no envelope) still accepted by both Workspace mount bridges — #74 and #110 tests still pass unchanged. The 3 existing Gallery bridge tests were updated to assert the new envelope shape.
Tests: 12 new #152 cases pin the bridge envelopes, the loadedDesignId field, the in-place update path, the fall-through-to-create path, the save-as semantics, and the folder/favorite preservation. Updated fixtures in 4 mock-state helpers. Total suite: 634/634 pass, lint clean, tsc -b clean.