Retrofits the ON DELETE pattern learned after v1 shipped (CASCADE for tenant-scoped children, SET NULL for historical references, RESTRICT where the domain type is non-Option) onto tables from 0001-0006 and 0026. Two deliberate exceptions kept as NO ACTION: audit_log.workspace_id (audit is append-only and must outlive workspace deletes) and thread_messages.from_agent (history stays attributable via agents.deleted_at). Two stay NOT NULL as RESTRICT (agents.managed_by, installed_skills.installed_by) because the Rust domain type is UserId, not Option<UserId>. Also includes the previously-orphan .sqlx cache for the usage_events query in cm-runtime/tests/run_loop.rs, which needed re-recording after the FK changes touched the metadata.
202 lines
9.7 KiB
SQL
202 lines
9.7 KiB
SQL
-- Backfill ON DELETE clauses on FKs from 0001-0006 and 0026. The pattern
|
|
-- (CASCADE for tenant-scoped children, SET NULL for historical references)
|
|
-- was learned after v1 shipped and applied consistently from 0010 onward;
|
|
-- this migration retrofits the earlier tables so DELETEs succeed instead of
|
|
-- either failing with a FK violation or leaving orphans.
|
|
--
|
|
-- Two FKs stay as NO ACTION deliberately:
|
|
-- * audit_log.workspace_id — audit is append-only and must outlive any
|
|
-- workspace delete (the trigger blocks UPDATE/DELETE on audit rows).
|
|
-- * thread_messages.from_agent — history stays attributable via the
|
|
-- agents.deleted_at soft-delete already in schema.
|
|
--
|
|
-- Two FKs stay NOT NULL and become explicit RESTRICT rather than SET NULL:
|
|
-- * agents.managed_by — the Rust domain type is `UserId` (not Option).
|
|
-- Making it nullable would ripple through cm-domain/cm-db/cm-api/tests.
|
|
-- RESTRICT preserves current behavior (delete blocked) but documents it.
|
|
-- * installed_skills.installed_by — same reasoning.
|
|
-- To hard-delete a user in either case, reassign or hard-delete the
|
|
-- dependent rows first — which matches real org-ownership semantics.
|
|
|
|
-- ---- 0001_init: workspaces cascade -----------------------------------------
|
|
ALTER TABLE users
|
|
DROP CONSTRAINT IF EXISTS users_workspace_id_fkey,
|
|
ADD CONSTRAINT users_workspace_id_fkey
|
|
FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE agents
|
|
DROP CONSTRAINT IF EXISTS agents_workspace_id_fkey,
|
|
ADD CONSTRAINT agents_workspace_id_fkey
|
|
FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE agents
|
|
DROP CONSTRAINT IF EXISTS agents_managed_by_fkey,
|
|
ADD CONSTRAINT agents_managed_by_fkey
|
|
FOREIGN KEY (managed_by) REFERENCES users (id) ON DELETE RESTRICT;
|
|
|
|
ALTER TABLE sessions
|
|
DROP CONSTRAINT IF EXISTS sessions_agent_id_fkey,
|
|
ADD CONSTRAINT sessions_agent_id_fkey
|
|
FOREIGN KEY (agent_id) REFERENCES agents (id) ON DELETE CASCADE,
|
|
DROP CONSTRAINT IF EXISTS sessions_workspace_id_fkey,
|
|
ADD CONSTRAINT sessions_workspace_id_fkey
|
|
FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE messages
|
|
DROP CONSTRAINT IF EXISTS messages_session_id_fkey,
|
|
ADD CONSTRAINT messages_session_id_fkey
|
|
FOREIGN KEY (session_id) REFERENCES sessions (id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE steps
|
|
DROP CONSTRAINT IF EXISTS steps_message_id_fkey,
|
|
ADD CONSTRAINT steps_message_id_fkey
|
|
FOREIGN KEY (message_id) REFERENCES messages (id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE agent_runs
|
|
DROP CONSTRAINT IF EXISTS agent_runs_session_id_fkey,
|
|
ADD CONSTRAINT agent_runs_session_id_fkey
|
|
FOREIGN KEY (session_id) REFERENCES sessions (id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE approvals
|
|
DROP CONSTRAINT IF EXISTS approvals_workspace_id_fkey,
|
|
ADD CONSTRAINT approvals_workspace_id_fkey
|
|
FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE,
|
|
DROP CONSTRAINT IF EXISTS approvals_run_id_fkey,
|
|
ADD CONSTRAINT approvals_run_id_fkey
|
|
FOREIGN KEY (run_id) REFERENCES agent_runs (id) ON DELETE CASCADE,
|
|
DROP CONSTRAINT IF EXISTS approvals_requested_by_agent_fkey,
|
|
ADD CONSTRAINT approvals_requested_by_agent_fkey
|
|
FOREIGN KEY (requested_by_agent) REFERENCES agents (id) ON DELETE CASCADE,
|
|
DROP CONSTRAINT IF EXISTS approvals_decided_by_fkey,
|
|
ADD CONSTRAINT approvals_decided_by_fkey
|
|
FOREIGN KEY (decided_by) REFERENCES users (id) ON DELETE SET NULL;
|
|
|
|
-- Single-use execution grants: deleting the approval should drop the grant.
|
|
ALTER TABLE execution_grants
|
|
DROP CONSTRAINT IF EXISTS execution_grants_approval_id_fkey,
|
|
ADD CONSTRAINT execution_grants_approval_id_fkey
|
|
FOREIGN KEY (approval_id) REFERENCES approvals (id) ON DELETE CASCADE;
|
|
|
|
-- audit_log.workspace_id — intentionally left as NO ACTION.
|
|
|
|
ALTER TABLE skills
|
|
DROP CONSTRAINT IF EXISTS skills_workspace_id_fkey,
|
|
ADD CONSTRAINT skills_workspace_id_fkey
|
|
FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE installed_skills
|
|
DROP CONSTRAINT IF EXISTS installed_skills_skill_id_fkey,
|
|
ADD CONSTRAINT installed_skills_skill_id_fkey
|
|
FOREIGN KEY (skill_id) REFERENCES skills (id) ON DELETE CASCADE,
|
|
DROP CONSTRAINT IF EXISTS installed_skills_installed_by_fkey,
|
|
ADD CONSTRAINT installed_skills_installed_by_fkey
|
|
FOREIGN KEY (installed_by) REFERENCES users (id) ON DELETE RESTRICT;
|
|
|
|
ALTER TABLE secrets
|
|
DROP CONSTRAINT IF EXISTS secrets_workspace_id_fkey,
|
|
ADD CONSTRAINT secrets_workspace_id_fkey
|
|
FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE app_connections
|
|
DROP CONSTRAINT IF EXISTS app_connections_workspace_id_fkey,
|
|
ADD CONSTRAINT app_connections_workspace_id_fkey
|
|
FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE,
|
|
DROP CONSTRAINT IF EXISTS app_connections_agent_id_fkey,
|
|
ADD CONSTRAINT app_connections_agent_id_fkey
|
|
FOREIGN KEY (agent_id) REFERENCES agents (id) ON DELETE CASCADE,
|
|
DROP CONSTRAINT IF EXISTS app_connections_secret_ref_fkey,
|
|
ADD CONSTRAINT app_connections_secret_ref_fkey
|
|
FOREIGN KEY (secret_ref) REFERENCES secrets (id) ON DELETE SET NULL;
|
|
|
|
ALTER TABLE threads
|
|
DROP CONSTRAINT IF EXISTS threads_workspace_id_fkey,
|
|
ADD CONSTRAINT threads_workspace_id_fkey
|
|
FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE thread_participants
|
|
DROP CONSTRAINT IF EXISTS thread_participants_agent_id_fkey,
|
|
ADD CONSTRAINT thread_participants_agent_id_fkey
|
|
FOREIGN KEY (agent_id) REFERENCES agents (id) ON DELETE CASCADE;
|
|
|
|
-- thread_messages.thread_id → CASCADE; from_agent stays NO ACTION.
|
|
ALTER TABLE thread_messages
|
|
DROP CONSTRAINT IF EXISTS thread_messages_thread_id_fkey,
|
|
ADD CONSTRAINT thread_messages_thread_id_fkey
|
|
FOREIGN KEY (thread_id) REFERENCES threads (id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE file_nodes
|
|
DROP CONSTRAINT IF EXISTS file_nodes_workspace_id_fkey,
|
|
ADD CONSTRAINT file_nodes_workspace_id_fkey
|
|
FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE,
|
|
DROP CONSTRAINT IF EXISTS file_nodes_agent_id_fkey,
|
|
ADD CONSTRAINT file_nodes_agent_id_fkey
|
|
FOREIGN KEY (agent_id) REFERENCES agents (id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE credit_lots
|
|
DROP CONSTRAINT IF EXISTS credit_lots_workspace_id_fkey,
|
|
ADD CONSTRAINT credit_lots_workspace_id_fkey
|
|
FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE;
|
|
|
|
ALTER TABLE usage_events
|
|
DROP CONSTRAINT IF EXISTS usage_events_workspace_id_fkey,
|
|
ADD CONSTRAINT usage_events_workspace_id_fkey
|
|
FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE,
|
|
DROP CONSTRAINT IF EXISTS usage_events_agent_id_fkey,
|
|
ADD CONSTRAINT usage_events_agent_id_fkey
|
|
FOREIGN KEY (agent_id) REFERENCES agents (id) ON DELETE SET NULL,
|
|
DROP CONSTRAINT IF EXISTS usage_events_run_id_fkey,
|
|
ADD CONSTRAINT usage_events_run_id_fkey
|
|
FOREIGN KEY (run_id) REFERENCES agent_runs (id) ON DELETE SET NULL;
|
|
|
|
-- ---- 0002_auth_sessions ---------------------------------------------------
|
|
ALTER TABLE auth_sessions
|
|
DROP CONSTRAINT IF EXISTS auth_sessions_user_id_fkey,
|
|
ADD CONSTRAINT auth_sessions_user_id_fkey
|
|
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE;
|
|
|
|
-- ---- 0003_run_events ------------------------------------------------------
|
|
ALTER TABLE run_events
|
|
DROP CONSTRAINT IF EXISTS run_events_run_id_fkey,
|
|
ADD CONSTRAINT run_events_run_id_fkey
|
|
FOREIGN KEY (run_id) REFERENCES agent_runs (id) ON DELETE CASCADE;
|
|
|
|
-- ---- 0004_outbox ----------------------------------------------------------
|
|
ALTER TABLE outbox
|
|
DROP CONSTRAINT IF EXISTS outbox_workspace_id_fkey,
|
|
ADD CONSTRAINT outbox_workspace_id_fkey
|
|
FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE,
|
|
DROP CONSTRAINT IF EXISTS outbox_agent_id_fkey,
|
|
ADD CONSTRAINT outbox_agent_id_fkey
|
|
FOREIGN KEY (agent_id) REFERENCES agents (id) ON DELETE CASCADE;
|
|
|
|
-- ---- 0005_oauth_states ----------------------------------------------------
|
|
ALTER TABLE oauth_states
|
|
DROP CONSTRAINT IF EXISTS oauth_states_workspace_id_fkey,
|
|
ADD CONSTRAINT oauth_states_workspace_id_fkey
|
|
FOREIGN KEY (workspace_id) REFERENCES workspaces (id) ON DELETE CASCADE,
|
|
DROP CONSTRAINT IF EXISTS oauth_states_user_id_fkey,
|
|
ADD CONSTRAINT oauth_states_user_id_fkey
|
|
FOREIGN KEY (user_id) REFERENCES users (id) ON DELETE CASCADE,
|
|
DROP CONSTRAINT IF EXISTS oauth_states_agent_id_fkey,
|
|
ADD CONSTRAINT oauth_states_agent_id_fkey
|
|
FOREIGN KEY (agent_id) REFERENCES agents (id) ON DELETE CASCADE;
|
|
|
|
-- ---- 0006_promo_codes -----------------------------------------------------
|
|
ALTER TABLE promo_codes
|
|
DROP CONSTRAINT IF EXISTS promo_codes_redeemed_by_fkey,
|
|
ADD CONSTRAINT promo_codes_redeemed_by_fkey
|
|
FOREIGN KEY (redeemed_by) REFERENCES workspaces (id) ON DELETE SET NULL;
|
|
|
|
-- ---- 0026_group_rooms -----------------------------------------------------
|
|
-- The threads.created_by / thread_participants.added_by columns were added
|
|
-- nullable by 0026, so SET NULL is legal.
|
|
ALTER TABLE threads
|
|
DROP CONSTRAINT IF EXISTS threads_created_by_fkey,
|
|
ADD CONSTRAINT threads_created_by_fkey
|
|
FOREIGN KEY (created_by) REFERENCES agents (id) ON DELETE SET NULL;
|
|
|
|
ALTER TABLE thread_participants
|
|
DROP CONSTRAINT IF EXISTS thread_participants_added_by_fkey,
|
|
ADD CONSTRAINT thread_participants_added_by_fkey
|
|
FOREIGN KEY (added_by) REFERENCES agents (id) ON DELETE SET NULL;
|