164 lines
7.7 KiB
SQL
164 lines
7.7 KiB
SQL
-- Migration: Migrate roles, permissions, user_roles, and role_permissions to UUID
|
|
-- Date: 2025-01-27
|
|
-- Reference: GO-004, GO-001, GO-005, GO-006
|
|
--
|
|
-- This migration converts all RBAC tables from BIGINT to UUID to align with the models
|
|
-- and ensure consistency with the rest of the application.
|
|
|
|
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
|
|
|
|
-- ==========================================
|
|
-- TABLE: roles
|
|
-- ==========================================
|
|
|
|
DO $$
|
|
BEGIN
|
|
-- Check if roles table exists and has BIGINT ID
|
|
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'roles') THEN
|
|
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'roles' AND column_name = 'id' AND data_type = 'bigint') THEN
|
|
RAISE NOTICE 'Migrating roles.id from BIGINT to UUID';
|
|
|
|
-- Add UUID column
|
|
ALTER TABLE roles ADD COLUMN IF NOT EXISTS id_uuid UUID DEFAULT gen_random_uuid();
|
|
|
|
-- Update role_permissions to use UUID (temporary mapping)
|
|
ALTER TABLE role_permissions ADD COLUMN IF NOT EXISTS role_id_uuid UUID;
|
|
UPDATE role_permissions rp
|
|
SET role_id_uuid = r.id_uuid
|
|
FROM roles r
|
|
WHERE rp.role_id = r.id;
|
|
|
|
-- Update user_roles to use UUID (temporary mapping)
|
|
ALTER TABLE user_roles ADD COLUMN IF NOT EXISTS role_id_uuid UUID;
|
|
UPDATE user_roles ur
|
|
SET role_id_uuid = r.id_uuid
|
|
FROM roles r
|
|
WHERE ur.role_id = r.id;
|
|
|
|
-- Drop foreign key constraints
|
|
ALTER TABLE role_permissions DROP CONSTRAINT IF EXISTS role_permissions_role_id_fkey;
|
|
ALTER TABLE user_roles DROP CONSTRAINT IF EXISTS user_roles_role_id_fkey;
|
|
|
|
-- Drop old ID column and rename UUID column
|
|
ALTER TABLE roles DROP CONSTRAINT IF EXISTS roles_pkey;
|
|
ALTER TABLE roles DROP COLUMN id;
|
|
ALTER TABLE roles RENAME COLUMN id_uuid TO id;
|
|
ALTER TABLE roles ADD PRIMARY KEY (id);
|
|
|
|
-- Update role_permissions
|
|
ALTER TABLE role_permissions DROP COLUMN role_id;
|
|
ALTER TABLE role_permissions RENAME COLUMN role_id_uuid TO role_id;
|
|
ALTER TABLE role_permissions ADD CONSTRAINT role_permissions_role_id_fkey
|
|
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE;
|
|
|
|
-- Update user_roles
|
|
ALTER TABLE user_roles DROP COLUMN role_id;
|
|
ALTER TABLE user_roles RENAME COLUMN role_id_uuid TO role_id;
|
|
ALTER TABLE user_roles ADD CONSTRAINT user_roles_role_id_fkey
|
|
FOREIGN KEY (role_id) REFERENCES roles(id) ON DELETE CASCADE;
|
|
END IF;
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ==========================================
|
|
-- TABLE: permissions
|
|
-- ==========================================
|
|
|
|
DO $$
|
|
BEGIN
|
|
-- Check if permissions table exists and has BIGINT ID
|
|
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'permissions') THEN
|
|
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'permissions' AND column_name = 'id' AND data_type = 'bigint') THEN
|
|
RAISE NOTICE 'Migrating permissions.id from BIGINT to UUID';
|
|
|
|
-- Add UUID column
|
|
ALTER TABLE permissions ADD COLUMN IF NOT EXISTS id_uuid UUID DEFAULT gen_random_uuid();
|
|
|
|
-- Update role_permissions to use UUID (temporary mapping)
|
|
ALTER TABLE role_permissions ADD COLUMN IF NOT EXISTS permission_id_uuid UUID;
|
|
UPDATE role_permissions rp
|
|
SET permission_id_uuid = p.id_uuid
|
|
FROM permissions p
|
|
WHERE rp.permission_id = p.id;
|
|
|
|
-- Drop foreign key constraint
|
|
ALTER TABLE role_permissions DROP CONSTRAINT IF EXISTS role_permissions_permission_id_fkey;
|
|
|
|
-- Drop old ID column and rename UUID column
|
|
ALTER TABLE permissions DROP CONSTRAINT IF EXISTS permissions_pkey;
|
|
ALTER TABLE permissions DROP COLUMN id;
|
|
ALTER TABLE permissions RENAME COLUMN id_uuid TO id;
|
|
ALTER TABLE permissions ADD PRIMARY KEY (id);
|
|
|
|
-- Update role_permissions
|
|
ALTER TABLE role_permissions DROP COLUMN permission_id;
|
|
ALTER TABLE role_permissions RENAME COLUMN permission_id_uuid TO permission_id;
|
|
ALTER TABLE role_permissions ADD CONSTRAINT role_permissions_permission_id_fkey
|
|
FOREIGN KEY (permission_id) REFERENCES permissions(id) ON DELETE CASCADE;
|
|
|
|
-- Recreate composite primary key
|
|
ALTER TABLE role_permissions DROP CONSTRAINT IF EXISTS role_permissions_pkey;
|
|
ALTER TABLE role_permissions ADD PRIMARY KEY (role_id, permission_id);
|
|
END IF;
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ==========================================
|
|
-- TABLE: user_roles
|
|
-- ==========================================
|
|
|
|
DO $$
|
|
BEGIN
|
|
-- Check if user_roles table exists and has BIGINT ID
|
|
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'user_roles') THEN
|
|
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'user_roles' AND column_name = 'id' AND data_type = 'bigint') THEN
|
|
RAISE NOTICE 'Migrating user_roles.id from BIGINT to UUID';
|
|
|
|
-- Add UUID column
|
|
ALTER TABLE user_roles ADD COLUMN IF NOT EXISTS id_uuid UUID DEFAULT gen_random_uuid();
|
|
|
|
-- Drop old ID column and rename UUID column
|
|
ALTER TABLE user_roles DROP CONSTRAINT IF EXISTS user_roles_pkey;
|
|
ALTER TABLE user_roles DROP COLUMN id;
|
|
ALTER TABLE user_roles RENAME COLUMN id_uuid TO id;
|
|
ALTER TABLE user_roles ADD PRIMARY KEY (id);
|
|
END IF;
|
|
|
|
-- Ensure user_id is UUID (should already be done by migration 047, but double-check)
|
|
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'user_roles' AND column_name = 'user_id' AND data_type = 'bigint') THEN
|
|
RAISE NOTICE 'user_roles.user_id is still BIGINT, should have been migrated by 047. This is unexpected.';
|
|
END IF;
|
|
|
|
-- Ensure assigned_by is UUID if it exists
|
|
IF EXISTS (SELECT 1 FROM information_schema.columns WHERE table_name = 'user_roles' AND column_name = 'assigned_by' AND data_type = 'bigint') THEN
|
|
RAISE NOTICE 'Migrating user_roles.assigned_by from BIGINT to UUID';
|
|
ALTER TABLE user_roles ADD COLUMN IF NOT EXISTS assigned_by_uuid UUID;
|
|
UPDATE user_roles ur
|
|
SET assigned_by_uuid = u.id
|
|
FROM users u
|
|
WHERE ur.assigned_by = u.id::bigint AND u.id IS NOT NULL;
|
|
ALTER TABLE user_roles DROP COLUMN assigned_by;
|
|
ALTER TABLE user_roles RENAME COLUMN assigned_by_uuid TO assigned_by;
|
|
END IF;
|
|
END IF;
|
|
END $$;
|
|
|
|
-- ==========================================
|
|
-- INDEXES
|
|
-- ==========================================
|
|
|
|
-- Recreate indexes if they don't exist
|
|
CREATE INDEX IF NOT EXISTS idx_user_roles_user_id ON user_roles(user_id);
|
|
CREATE INDEX IF NOT EXISTS idx_user_roles_role_id ON user_roles(role_id);
|
|
CREATE INDEX IF NOT EXISTS idx_role_permissions_role_id ON role_permissions(role_id);
|
|
CREATE INDEX IF NOT EXISTS idx_role_permissions_permission_id ON role_permissions(permission_id);
|
|
|
|
-- ==========================================
|
|
-- COMMENTS
|
|
-- ==========================================
|
|
|
|
COMMENT ON TABLE roles IS 'System roles for RBAC (migrated to UUID)';
|
|
COMMENT ON TABLE permissions IS 'System permissions for RBAC (migrated to UUID)';
|
|
COMMENT ON TABLE user_roles IS 'User role assignments (migrated to UUID)';
|
|
COMMENT ON TABLE role_permissions IS 'Role permission mappings (migrated to UUID)';
|
|
|