Skip to content

Commit 72fe590

Browse files
committed
Fix supabase reverse
1 parent a6951c3 commit 72fe590

2 files changed

Lines changed: 41 additions & 4 deletions

File tree

mcp/main.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -827,12 +827,16 @@ async def revert_supabase_row(change_id: str, skip_tracking: bool = False):
827827
restored_row = None
828828

829829
if operation == "INSERT":
830-
# Revert INSERT by DELETING the row
830+
# Revert INSERT by DELETING the row (with CASCADE for clients table)
831831
print(f" → Deleting inserted row...")
832832
try:
833-
api.delete_row(table_name, row_id)
833+
# Use CASCADE delete for clients table to automatically delete child records
834+
cascade = (table_name == "clients")
835+
api.delete_row(table_name, row_id, cascade=cascade)
834836
restored_row = {"deleted": True}
835837
status_msg = f"Row {row_id} deleted (reverted INSERT)"
838+
if cascade:
839+
status_msg += " with CASCADE"
836840
except requests.exceptions.HTTPError as e:
837841
if e.response.status_code == 409:
838842
# Foreign key constraint violation

mcp/supabase_api.py

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,18 +113,24 @@ def update_row(
113113
result = response.json()
114114
return result[0] if result else {}
115115

116-
def delete_row(self, table_name: str, row_id: int, id_column: str = "id") -> bool:
116+
def delete_row(self, table_name: str, row_id: int, id_column: str = "id", cascade: bool = False) -> bool:
117117
"""
118-
Delete a row
118+
Delete a row, optionally with CASCADE behavior
119119
120120
Args:
121121
table_name: Name of the table
122122
row_id: Row ID
123123
id_column: Name of the ID column (default: id)
124+
cascade: If True, delete child records first (default: False)
124125
125126
Returns:
126127
True if successful
127128
"""
129+
# If cascade is enabled and this is the clients table, delete child records first
130+
if cascade and table_name == "clients":
131+
print(f"🔄 CASCADE delete enabled for clients table")
132+
self._cascade_delete_client(row_id)
133+
128134
url = f"{self.rest_url}/{table_name}?{id_column}=eq.{row_id}"
129135

130136
print(f"🔧 Supabase DELETE request:")
@@ -138,6 +144,33 @@ def delete_row(self, table_name: str, row_id: int, id_column: str = "id") -> boo
138144
response.raise_for_status()
139145
return True
140146

147+
def _cascade_delete_client(self, client_id: int) -> None:
148+
"""
149+
Delete all child records for a client before deleting the client itself
150+
151+
Args:
152+
client_id: Client ID
153+
"""
154+
# Define child tables that reference clients
155+
child_tables = ["transactions", "accounts", "alerts"]
156+
157+
for table in child_tables:
158+
try:
159+
url = f"{self.rest_url}/{table}?client_id=eq.{client_id}"
160+
print(f" → Deleting {table} for client {client_id}...")
161+
response = requests.delete(url, headers=self.headers)
162+
163+
if response.status_code == 200 or response.status_code == 204:
164+
# Count how many were deleted
165+
deleted_count = len(response.json()) if response.text else 0
166+
if deleted_count > 0:
167+
print(f" ✓ Deleted {deleted_count} {table} record(s)")
168+
else:
169+
print(f" ⚠ Status {response.status_code} for {table}")
170+
except Exception as e:
171+
print(f" ⚠ Error deleting {table}: {e}")
172+
# Continue with other tables even if one fails
173+
141174
def insert_row(self, table_name: str, data: Dict[str, Any]) -> Dict[str, Any]:
142175
"""
143176
Insert a new row

0 commit comments

Comments
 (0)