This guide helps you diagnose and fix common database issues in the FindU ecosystem. Each section includes symptoms, causes, and step-by-step solutions.
Never modify a migration that has been deployed. Create a new migration to fix issues.
1
Check migration status
Copy
supabase migration list
2
If local only
Copy
# Remove the local migration filerm supabase/migrations/[timestamp]_migration_name.sql# Create new one with different namesupabase migration new fixed_migration_name
3
If already deployed
Copy
# Create a fix migrationsupabase migration new fix_previous_migration# Add your fixes to the new migration
-- Error: relation "table_name" already exists-- Fix: Use IF NOT EXISTSCREATE TABLE IF NOT EXISTS public.table_name ( id uuid PRIMARY KEY DEFAULT gen_random_uuid());-- For columnsALTER TABLE public.table_name ADD COLUMN IF NOT EXISTS new_column text;-- For constraintsDO $$ BEGIN IF NOT EXISTS ( SELECT 1 FROM pg_constraint WHERE conname = 'constraint_name' ) THEN ALTER TABLE public.table_name ADD CONSTRAINT constraint_name CHECK (column > 0); END IF;END $$;
SELECT schemaname, tablename, rowsecurity FROM pg_tables WHERE schemaname = 'public' AND tablename = 'your_table';
2
Check policies exist
Copy
SELECT pol.polname as policy_name, pol.polcmd as command, pol.polroles as roles, CASE WHEN pol.polpermissive THEN 'PERMISSIVE' ELSE 'RESTRICTIVE' END as typeFROM pg_policies polWHERE pol.schemaname = 'public' AND pol.tablename = 'your_table';
3
Test as specific user
Copy
-- Set user contextSET request.jwt.claim.sub TO 'user-uuid-here';-- Test querySELECT * FROM public.your_table;-- Reset contextRESET request.jwt.claim.sub;
4
Debug policy
Copy
-- Create debug policyCREATE POLICY "debug_policy" ON public.your_table FOR SELECT USING ( RAISE NOTICE 'User ID: %, Row ID: %', auth.uid(), id RETURNING true );
-- Find and fix common inconsistencies-- Mismatched countsWITH counts AS ( SELECT c.id, c.message_count, COUNT(m.id) as actual_count FROM public.conversations c LEFT JOIN public.messages m ON c.id = m.conversation_id GROUP BY c.id, c.message_count)UPDATE public.conversationsSET message_count = counts.actual_countFROM countsWHERE conversations.id = counts.id AND counts.message_count != counts.actual_count;-- Orphaned recordsDELETE FROM public.conversation_participantsWHERE conversation_id NOT IN ( SELECT id FROM public.conversations);-- Circular referencesWITH RECURSIVE hierarchy AS ( SELECT id, parent_id, 1 as level FROM public.categories WHERE parent_id IS NULL UNION ALL SELECT c.id, c.parent_id, h.level + 1 FROM public.categories c JOIN hierarchy h ON c.parent_id = h.id WHERE h.level < 10 -- Prevent infinite recursion)SELECT * FROM hierarchyORDER BY level, id;
-- Check storage usageSELECT auth.uid() as user_id, bucket_id, COUNT(*) as file_count, pg_size_pretty(SUM(COALESCE(metadata->>'size', '0')::bigint)) as total_sizeFROM storage.objectsGROUP BY auth.uid(), bucket_id;-- Clean up orphaned filesDELETE FROM storage.objectsWHERE owner NOT IN ( SELECT id FROM auth.users);
-- Check auth configurationSELECT * FROM auth.users WHERE email = '[email protected]';-- Verify user metadataSELECT id, email, raw_user_meta_data, created_at, last_sign_in_atFROM auth.usersORDER BY created_at DESCLIMIT 10;-- Fix missing profilesINSERT INTO public.profiles (id, role)SELECT id as id, 'student' as roleFROM auth.usersWHERE id NOT IN ( SELECT id FROM public.profiles);
-- Create restore point (before risky operation)SELECT pg_create_restore_point('before_risky_change');-- Use transactionsBEGIN;-- Your risky operationsSAVEPOINT my_savepoint;-- More operations-- If something goes wrong:ROLLBACK TO my_savepoint;-- Or if all good:COMMIT;-- Restore from backup (contact Supabase support for production)