mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-25 09:41:04 +01:00
DELETE /tool-applications/:applicationId pre-checked for connections and then deleted in a later statement. Because tool_connections.application_id was ON DELETE CASCADE, a connection created in that gap was silently cascade-deleted instead of forcing the promised 409. Switch the FK to ON DELETE NO ACTION so the database fails closed: an application with connections can never be deleted, and a concurrently inserted connection (which takes a FOR KEY SHARE lock on the parent row) forces the delete to raise a foreign_key_violation rather than cascade. NO ACTION (end-of-statement check) rather than RESTRICT (immediate) keeps company teardown cascading cleanly. The service still pre-checks for a friendly 409 with connectionCount, and now also translates a 23503 violation on the connection FK into the same 409 so the race surfaces the conflict instead of a 500. Regression tests: the raw delete is rejected and both rows survive (the old cascade would have silently dropped the connection), and a company delete still cascades application + connection away. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>