fix: save button now fully persists canvas to DB
Root cause: handleAddNode/handleEdgeConfirm only updated Zustand store, never creating records in the DB. canvasApi.save() only updated positions of existing nodes, so nothing survived a page refresh. Fix: save now sends the full canvas state (all nodes + edges + data) and the backend does a full sync — upsert incoming, delete anything removed. This means Save is the single source of truth: no need to call individual create/update/delete APIs for every drag or edit.
This commit is contained in:
@@ -23,12 +23,40 @@ async def load_canvas(db: AsyncSession = Depends(get_db), _: str = Depends(get_c
|
||||
|
||||
@router.post("/save")
|
||||
async def save_canvas(body: CanvasSaveRequest, db: AsyncSession = Depends(get_db), _: str = Depends(get_current_user)):
|
||||
# Update node positions from canvas
|
||||
for node_pos in body.node_positions:
|
||||
node = await db.get(Node, node_pos.id)
|
||||
incoming_node_ids = {n.id for n in body.nodes}
|
||||
incoming_edge_ids = {e.id for e in body.edges}
|
||||
|
||||
# Delete nodes removed from canvas
|
||||
existing_nodes = (await db.execute(select(Node))).scalars().all()
|
||||
for node in existing_nodes:
|
||||
if node.id not in incoming_node_ids:
|
||||
await db.delete(node)
|
||||
|
||||
# Delete edges removed from canvas
|
||||
existing_edges = (await db.execute(select(Edge))).scalars().all()
|
||||
for edge in existing_edges:
|
||||
if edge.id not in incoming_edge_ids:
|
||||
await db.delete(edge)
|
||||
|
||||
await db.flush()
|
||||
|
||||
# Upsert nodes
|
||||
for node_data in body.nodes:
|
||||
node = await db.get(Node, node_data.id)
|
||||
if node:
|
||||
node.pos_x = node_pos.x
|
||||
node.pos_y = node_pos.y
|
||||
for field, value in node_data.model_dump().items():
|
||||
setattr(node, field, value)
|
||||
else:
|
||||
db.add(Node(**node_data.model_dump()))
|
||||
|
||||
# Upsert edges
|
||||
for edge_data in body.edges:
|
||||
edge = await db.get(Edge, edge_data.id)
|
||||
if edge:
|
||||
for field, value in edge_data.model_dump().items():
|
||||
setattr(edge, field, value)
|
||||
else:
|
||||
db.add(Edge(**edge_data.model_dump()))
|
||||
|
||||
# Upsert viewport
|
||||
state = await db.get(CanvasState, 1)
|
||||
|
||||
Reference in New Issue
Block a user