99from config import MAX_BACKUPS_PER_USER , MIN_INTERVAL_MINUTES , DEFAULT_PAD_NAME , DEFAULT_TEMPLATE_NAME
1010pad_router = APIRouter ()
1111
12+ def ensure_pad_metadata (data : Dict [str , Any ], pad_id : str , display_name : str ) -> Dict [str , Any ]:
13+ """
14+ Ensure the pad metadata (uniqueId and displayName) is set in the data.
15+
16+ Args:
17+ data: The pad data to modify
18+ pad_id: The pad ID to set as uniqueId
19+ display_name: The display name to set
20+
21+ Returns:
22+ The modified data
23+ """
24+ # Ensure the appState and pad objects exist
25+ if "appState" not in data :
26+ data ["appState" ] = {}
27+ if "pad" not in data ["appState" ]:
28+ data ["appState" ]["pad" ] = {}
29+
30+ # Set the uniqueId to match the database ID
31+ data ["appState" ]["pad" ]["uniqueId" ] = str (pad_id )
32+ data ["appState" ]["pad" ]["displayName" ] = display_name
33+
34+ return data
35+
1236
13- @pad_router .post ("" )
14- async def save_pad (
37+ @pad_router .post ("/{pad_id}" )
38+ async def update_specific_pad (
39+ pad_id : UUID ,
1540 data : Dict [str , Any ],
1641 user : UserSession = Depends (require_auth ),
1742 pad_service : PadService = Depends (get_pad_service ),
1843 backup_service : BackupService = Depends (get_backup_service ),
1944):
20- """Save pad data for the authenticated user"""
45+ """Update a specific pad's data for the authenticated user"""
2146 try :
22- # Check if user already has a pad
23- user_pads = await pad_service .get_pads_by_owner ( user . id )
47+ # Get the pad to verify ownership
48+ pad = await pad_service .get_pad ( pad_id )
2449
25- if not user_pads :
26- # Create a new pad if user doesn't have one
27- pad = await pad_service .create_pad (
28- owner_id = user .id ,
29- display_name = DEFAULT_PAD_NAME ,
30- data = data ,
31- user_session = user
32- )
33- else :
34- # Update existing pad
35- pad = user_pads [0 ] # Use the first pad (assuming one pad per user for now)
36- await pad_service .update_pad_data (pad ["id" ], data )
50+ if not pad :
51+ raise HTTPException (status_code = 404 , detail = "Pad not found" )
3752
38- # Create a backup only if needed (if none exist or latest is > 5 min old)
53+ # Verify the user owns this pad
54+ if str (pad ["owner_id" ]) != str (user .id ):
55+ raise HTTPException (status_code = 403 , detail = "You don't have permission to update this pad" )
56+
57+ # Ensure the uniqueId and displayName are set in the data
58+ data = ensure_pad_metadata (data , str (pad_id ), pad ["display_name" ])
59+
60+ # Update the pad
61+ await pad_service .update_pad_data (pad_id , data )
62+
63+ # Create a backup if needed
3964 await backup_service .create_backup_if_needed (
40- source_id = pad [ "id" ] ,
65+ source_id = pad_id ,
4166 data = data ,
4267 min_interval_minutes = MIN_INTERVAL_MINUTES ,
4368 max_backups = MAX_BACKUPS_PER_USER
4469 )
4570
4671 return {"status" : "success" }
4772 except Exception as e :
48- print (f"Error saving pad data: { str (e )} " )
49- raise HTTPException (status_code = 500 , detail = f"Failed to save canvas data: { str (e )} " )
73+ print (f"Error updating pad: { str (e )} " )
74+ raise HTTPException (status_code = 500 , detail = f"Failed to update pad: { str (e )} " )
75+
76+
77+ @pad_router .patch ("/{pad_id}" )
78+ async def rename_pad (
79+ pad_id : UUID ,
80+ data : Dict [str , str ],
81+ user : UserSession = Depends (require_auth ),
82+ pad_service : PadService = Depends (get_pad_service ),
83+ ):
84+ """Rename a pad for the authenticated user"""
85+ try :
86+ # Get the pad to verify ownership
87+ pad = await pad_service .get_pad (pad_id )
88+
89+ if not pad :
90+ raise HTTPException (status_code = 404 , detail = "Pad not found" )
91+
92+ # Verify the user owns this pad
93+ if str (pad ["owner_id" ]) != str (user .id ):
94+ raise HTTPException (status_code = 403 , detail = "You don't have permission to rename this pad" )
95+
96+ # Check if display_name is provided
97+ if "display_name" not in data :
98+ raise HTTPException (status_code = 400 , detail = "display_name is required" )
99+
100+ # Update the pad's display name
101+ update_data = {"display_name" : data ["display_name" ]}
102+ updated_pad = await pad_service .update_pad (pad_id , update_data )
103+
104+ return {"status" : "success" , "pad" : updated_pad }
105+ except ValueError as e :
106+ print (f"Error renaming pad: { str (e )} " )
107+ raise HTTPException (status_code = 400 , detail = str (e ))
108+ except Exception as e :
109+ print (f"Error renaming pad: { str (e )} " )
110+ raise HTTPException (status_code = 500 , detail = f"Failed to rename pad: { str (e )} " )
111+
112+
113+ @pad_router .delete ("/{pad_id}" )
114+ async def delete_pad (
115+ pad_id : UUID ,
116+ user : UserSession = Depends (require_auth ),
117+ pad_service : PadService = Depends (get_pad_service ),
118+ ):
119+ """Delete a pad for the authenticated user"""
120+ try :
121+ # Get the pad to verify ownership
122+ pad = await pad_service .get_pad (pad_id )
123+
124+ if not pad :
125+ raise HTTPException (status_code = 404 , detail = "Pad not found" )
126+
127+ # Verify the user owns this pad
128+ if str (pad ["owner_id" ]) != str (user .id ):
129+ raise HTTPException (status_code = 403 , detail = "You don't have permission to delete this pad" )
130+
131+ # Delete the pad
132+ success = await pad_service .delete_pad (pad_id )
133+
134+ if not success :
135+ raise HTTPException (status_code = 500 , detail = "Failed to delete pad" )
136+
137+ return {"status" : "success" }
138+ except ValueError as e :
139+ print (f"Error deleting pad: { str (e )} " )
140+ raise HTTPException (status_code = 400 , detail = str (e ))
141+ except Exception as e :
142+ print (f"Error deleting pad: { str (e )} " )
143+ raise HTTPException (status_code = 500 , detail = f"Failed to delete pad: { str (e )} " )
50144
51145
52146@pad_router .get ("" )
53- async def get_pad (
147+ async def get_all_pads (
54148 user : UserSession = Depends (require_auth ),
55149 pad_service : PadService = Depends (get_pad_service ),
56150 template_pad_service : TemplatePadService = Depends (get_template_pad_service ),
57151 backup_service : BackupService = Depends (get_backup_service )
58152):
59- """Get pad data for the authenticated user"""
153+ """Get all pads for the authenticated user"""
60154 try :
61155 # Get user's pads
62156 user_pads = await pad_service .get_pads_by_owner (user .id )
63157
64158 if not user_pads :
65- # Return default canvas if user doesn't have a pad
66- return await create_pad_from_template (
159+ # Create a default pad if user doesn't have any
160+ new_pad = await create_pad_from_template (
67161 name = DEFAULT_TEMPLATE_NAME ,
68162 display_name = DEFAULT_PAD_NAME ,
69163 user = user ,
70164 pad_service = pad_service ,
71165 template_pad_service = template_pad_service ,
72166 backup_service = backup_service
73167 )
168+
169+ # Return the new pad in a list
170+ return [new_pad ]
74171
75- # Return the first pad's data (assuming one pad per user for now)
76- return user_pads [0 ]["data" ]
172+ # Ensure each pad's data has the uniqueId and displayName set
173+ for pad in user_pads :
174+ pad_data = pad ["data" ]
175+
176+ # Ensure the uniqueId and displayName are set in the data
177+ pad_data = ensure_pad_metadata (pad_data , str (pad ["id" ]), pad ["display_name" ])
178+
179+ # Return all pads
180+ return user_pads
77181 except Exception as e :
78182 print (f"Error getting pad data: { str (e )} " )
79183 raise HTTPException (status_code = 500 , detail = f"Failed to get pad data: { str (e )} " )
@@ -96,18 +200,30 @@ async def create_pad_from_template(
96200 if not template :
97201 raise HTTPException (status_code = 404 , detail = "Template not found" )
98202
203+ # Get the template data
204+ template_data = template ["data" ]
205+
206+ # Before creating, ensure the pad object exists in the data
207+ template_data = ensure_pad_metadata (template_data , "" , "" )
208+
99209 # Create a new pad using the template data
100210 pad = await pad_service .create_pad (
101211 owner_id = user .id ,
102212 display_name = display_name ,
103- data = template [ "data" ] ,
213+ data = template_data ,
104214 user_session = user
105215 )
106216
217+ # Set the uniqueId and displayName to match the database ID and display name
218+ template_data = ensure_pad_metadata (template_data , str (pad ["id" ]), display_name )
219+
220+ # Update the pad with the modified data
221+ await pad_service .update_pad_data (pad ["id" ], template_data )
222+
107223 # Create an initial backup for the new pad
108224 await backup_service .create_backup_if_needed (
109225 source_id = pad ["id" ],
110- data = template [ "data" ] ,
226+ data = template_data ,
111227 min_interval_minutes = 0 , # Always create initial backup
112228 max_backups = MAX_BACKUPS_PER_USER
113229 )
0 commit comments