mirror of https://github.com/docusealco/docuseal
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.9 KiB
87 lines
2.9 KiB
# frozen_string_literal: true
|
|
|
|
# Migration 5: Backfill institution data
|
|
# Part of Winston's 4-layer data isolation foundation
|
|
# This migration backfills existing data and makes institution_id non-nullable
|
|
class BackfillInstitutionData < ActiveRecord::Migration[7.0]
|
|
def up
|
|
# For existing installations, we need to:
|
|
# 1. Create default institutions for each account
|
|
# 2. Link existing users to their institutions via account_access
|
|
# 3. Make institution_id non-nullable
|
|
|
|
# Note: This is a data migration that should be run carefully in production
|
|
# We'll use raw SQL for performance on large datasets
|
|
|
|
execute <<-SQL
|
|
-- Step 1: Create default institutions for accounts that don't have them
|
|
INSERT INTO institutions (
|
|
account_id,
|
|
super_admin_id,
|
|
name,
|
|
registration_number,
|
|
address,
|
|
contact_email,
|
|
contact_phone,
|
|
settings,
|
|
created_at,
|
|
updated_at
|
|
)
|
|
SELECT DISTINCT
|
|
a.id as account_id,
|
|
(
|
|
SELECT u.id
|
|
FROM users u
|
|
WHERE u.account_id = a.id
|
|
AND u.role = 'admin'
|
|
ORDER BY u.created_at
|
|
LIMIT 1
|
|
) as super_admin_id,
|
|
COALESCE(a.name, 'Default Institution') as name,
|
|
NULL as registration_number,
|
|
NULL as address,
|
|
NULL as contact_email,
|
|
NULL as contact_phone,
|
|
'{}'::jsonb as settings,
|
|
NOW() as created_at,
|
|
NOW() as updated_at
|
|
FROM accounts a
|
|
LEFT JOIN institutions i ON a.id = i.account_id
|
|
WHERE i.id IS NULL;
|
|
|
|
-- Step 2: Update account_accesses with institution_id
|
|
UPDATE account_accesses aa
|
|
SET institution_id = i.id
|
|
FROM institutions i
|
|
WHERE aa.account_id = i.account_id;
|
|
|
|
-- Step 3: Add default role for existing records
|
|
UPDATE account_accesses
|
|
SET role = 'cohort_super_admin'
|
|
WHERE institution_id IS NOT NULL;
|
|
|
|
-- Step 4: Add unique index for [user_id, institution_id]
|
|
-- This will prevent duplicate roles
|
|
CREATE UNIQUE INDEX index_account_accesses_on_user_id_and_institution_id
|
|
ON account_accesses(user_id, institution_id)
|
|
WHERE institution_id IS NOT NULL;
|
|
SQL
|
|
|
|
# Step 5: Make institution_id non-nullable
|
|
change_column_null :account_accesses, :institution_id, false
|
|
|
|
# Step 6: Add foreign key constraint
|
|
add_foreign_key :account_accesses, :institutions, name: 'fk_account_accesses_to_institutions'
|
|
end
|
|
|
|
def down
|
|
# Reverse operations
|
|
remove_foreign_key :account_accesses, name: 'fk_account_accesses_to_institutions'
|
|
change_column_null :account_accesses, :institution_id, true
|
|
remove_index :account_accesses, name: 'index_account_accesses_on_user_id_and_institution_id'
|
|
|
|
# Don't delete institutions as they may contain important data
|
|
# Instead, just nullify the institution_id in account_accesses
|
|
execute 'UPDATE account_accesses SET institution_id = NULL'
|
|
end
|
|
end |