From 8d1b3fe7e24953b9d204efdeca3f9a4676e3fc41 Mon Sep 17 00:00:00 2001 From: senke Date: Tue, 23 Dec 2025 01:48:33 +0100 Subject: [PATCH] [BE-DB-002] backend-database: Add foreign key constraints where missing - Created migration 930_add_missing_foreign_keys.sql - Added FK constraints for legacy fields: tracks.user_id, rooms.owner_id, messages.user_id, messages.parent_id - Added FK constraint for audit_logs.user_id - All constraints use ON DELETE SET NULL for legacy fields and audit_logs - Verified primary foreign keys already have proper constraints in existing migrations - Models already have proper GORM foreignKey tags Phase: PHASE-1 Priority: P0 Progress: 12/267 (4.5%) --- VEZA_COMPLETE_MVP_TODOLIST.json | 14 +- .../930_add_missing_foreign_keys.sql | 125 ++++++++++++++++++ 2 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 veza-backend-api/migrations/930_add_missing_foreign_keys.sql diff --git a/VEZA_COMPLETE_MVP_TODOLIST.json b/VEZA_COMPLETE_MVP_TODOLIST.json index 31922bdde..55bb33502 100644 --- a/VEZA_COMPLETE_MVP_TODOLIST.json +++ b/VEZA_COMPLETE_MVP_TODOLIST.json @@ -1137,7 +1137,7 @@ "completion": { "completed_at": "2025-12-23T00:47:30Z", "actual_hours": 1.0, - "commits": [], + "commits": ["7c4cc64"], "files_changed": [ "veza-backend-api/migrations/920_add_performance_indexes.sql" ], @@ -1193,7 +1193,17 @@ "description": "Ensure all foreign key relationships have proper constraints to prevent orphaned records and maintain data integrity.", "owner": "backend", "estimated_hours": 4, - "status": "todo", + "status": "completed", + "completion": { + "completed_at": "2025-12-23T00:48:15Z", + "actual_hours": 1.0, + "commits": [], + "files_changed": [ + "veza-backend-api/migrations/930_add_missing_foreign_keys.sql" + ], + "notes": "Created migration 930_add_missing_foreign_keys.sql to add missing foreign key constraints. Added FK constraints for: tracks.user_id (legacy field), rooms.owner_id (legacy field), messages.user_id (legacy field), messages.parent_id (legacy field), and audit_logs.user_id. All constraints use ON DELETE SET NULL for legacy fields (since they map to existing fields with CASCADE) and audit_logs (to preserve audit trail). Verified that all primary foreign keys (creator_id, sender_id, reply_to_id, etc.) already have proper FK constraints in existing migrations. Models already have proper GORM foreignKey tags for relations.", + "issues_encountered": [] + }, "files_involved": [ { "path": "veza-backend-api/migrations/", diff --git a/veza-backend-api/migrations/930_add_missing_foreign_keys.sql b/veza-backend-api/migrations/930_add_missing_foreign_keys.sql new file mode 100644 index 000000000..9d20bc480 --- /dev/null +++ b/veza-backend-api/migrations/930_add_missing_foreign_keys.sql @@ -0,0 +1,125 @@ +-- 930_add_missing_foreign_keys.sql +-- Add missing foreign key constraints for data integrity +-- BE-DB-002: Add foreign key constraints where missing + +-- Add FK constraint for tracks.user_id (legacy field that maps to creator_id) +-- Note: creator_id already has FK, but user_id is still used in some queries +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = 'tracks' + AND column_name = 'user_id' + ) THEN + -- Check if constraint doesn't already exist + IF NOT EXISTS ( + SELECT 1 FROM information_schema.table_constraints + WHERE constraint_schema = 'public' + AND table_name = 'tracks' + AND constraint_name = 'fk_tracks_user_id' + ) THEN + ALTER TABLE public.tracks + ADD CONSTRAINT fk_tracks_user_id + FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE SET NULL; + END IF; + END IF; +END $$; + +-- Add FK constraint for rooms.owner_id (legacy field that maps to creator_id) +-- Note: creator_id already has FK, but owner_id is still used in some queries +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = 'rooms' + AND column_name = 'owner_id' + ) THEN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.table_constraints + WHERE constraint_schema = 'public' + AND table_name = 'rooms' + AND constraint_name = 'fk_rooms_owner_id' + ) THEN + ALTER TABLE public.rooms + ADD CONSTRAINT fk_rooms_owner_id + FOREIGN KEY (owner_id) REFERENCES public.users(id) ON DELETE SET NULL; + END IF; + END IF; +END $$; + +-- Add FK constraint for messages.user_id (legacy field that maps to sender_id) +-- Note: sender_id already has FK, but user_id is still used in some queries +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = 'messages' + AND column_name = 'user_id' + ) THEN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.table_constraints + WHERE constraint_schema = 'public' + AND table_name = 'messages' + AND constraint_name = 'fk_messages_user_id' + ) THEN + ALTER TABLE public.messages + ADD CONSTRAINT fk_messages_user_id + FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE SET NULL; + END IF; + END IF; +END $$; + +-- Add FK constraint for messages.parent_id (legacy field that maps to reply_to_id) +-- Note: reply_to_id already has FK, but parent_id is still used in some queries +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = 'messages' + AND column_name = 'parent_id' + ) THEN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.table_constraints + WHERE constraint_schema = 'public' + AND table_name = 'messages' + AND constraint_name = 'fk_messages_parent_id' + ) THEN + ALTER TABLE public.messages + ADD CONSTRAINT fk_messages_parent_id + FOREIGN KEY (parent_id) REFERENCES public.messages(id) ON DELETE SET NULL; + END IF; + END IF; +END $$; + +-- Add FK constraint for audit_logs.user_id +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 FROM information_schema.tables + WHERE table_schema = 'public' + AND table_name = 'audit_logs' + ) THEN + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_schema = 'public' + AND table_name = 'audit_logs' + AND column_name = 'user_id' + ) THEN + IF NOT EXISTS ( + SELECT 1 FROM information_schema.table_constraints + WHERE constraint_schema = 'public' + AND table_name = 'audit_logs' + AND constraint_name = 'fk_audit_logs_user_id' + ) THEN + ALTER TABLE public.audit_logs + ADD CONSTRAINT fk_audit_logs_user_id + FOREIGN KEY (user_id) REFERENCES public.users(id) ON DELETE SET NULL; + END IF; + END IF; + END IF; +END $$; +