Fix migration

Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
Émile Ré
2026-02-05 18:52:45 +04:00
parent ce0952e4ec
commit 91b6c6904a

View File

@@ -2,11 +2,11 @@
ALTER TABLE ALTER TABLE
iam_membership_profiles iam_membership_profiles
ADD ADD
COLUMN identity_id REFERENCES identities(id) NOT NULL, COLUMN identity_id TEXT REFERENCES identities(id),
ADD ADD
COLUMN additional_email_addresses CITEXT [] NOT NULL, COLUMN additional_email_addresses CITEXT [],
ADD ADD
COLUMN kind PEOPLE_KIND NOT NULL, COLUMN kind PEOPLE_KIND,
ADD ADD
COLUMN contract_start_date DATE, COLUMN contract_start_date DATE,
ADD ADD
@@ -23,72 +23,79 @@ FROM
WHERE WHERE
m.id = mp.membership_id; m.id = mp.membership_id;
ALTER TABLE
iam_membership_profiles
ALTER COLUMN
identity_id
SET
NOT NULL;
-- 2. Add profile references to all table referencing peoples -- 2. Add profile references to all table referencing peoples
-- was owner_id, NOT NULL -- was owner_id, NOT NULL
ALTER TABLE ALTER TABLE
assets assets
ADD ADD
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT; COLUMN owner_profile_id TEXT REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
-- was owner_id, NOT NULL -- was owner_id, NOT NULL
ALTER TABLE ALTER TABLE
continual_improvements continual_improvements
ADD ADD
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT; COLUMN owner_profile_id TEXT REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
-- was owner_id, NOT NULL -- was owner_id, NOT NULL
ALTER TABLE ALTER TABLE
data data
ADD ADD
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT; COLUMN owner_profile_id TEXT REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
-- was owner_id, NOT NULL -- was owner_id, NOT NULL
ALTER TABLE ALTER TABLE
document_versions document_versions
ADD ADD
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT; COLUMN owner_profile_id TEXT REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
-- was attendee_id, NOT NULL -- was attendee_id, NOT NULL
ALTER TABLE ALTER TABLE
meeting_attendees meeting_attendees
ADD ADD
COLUMN attendee_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE CASCADE; COLUMN attendee_profile_id TEXT REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE CASCADE;
-- was owner_id, NOT NULL -- was owner_id, NOT NULL
ALTER TABLE ALTER TABLE
nonconformities nonconformities
ADD ADD
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT; COLUMN owner_profile_id TEXT REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
-- was owner_id, NOT NULL -- was owner_id, NOT NULL
ALTER TABLE ALTER TABLE
obligations obligations
ADD ADD
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT; COLUMN owner_profile_id TEXT REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
-- was owner_id, can be null -- was owner_id, can be null
ALTER TABLE ALTER TABLE
documents documents
ADD ADD
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id); COLUMN owner_profile_id TEXT REFERENCES iam_membership_profiles(id);
-- was signed_by, NOT NULL -- was signed_by, NOT NULL
ALTER TABLE ALTER TABLE
document_version_signatures document_version_signatures
ADD ADD
COLUMN signed_by_profile_id REFERENCES iam_membership_profiles(id); COLUMN signed_by_profile_id TEXT REFERENCES iam_membership_profiles(id);
-- was data_protection_officer_id, can be null -- was data_protection_officer_id, can be null
ALTER TABLE ALTER TABLE
processing_activities processing_activities
ADD ADD
COLUMN dpo_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT; COLUMN dpo_profile_id TEXT REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
-- was owner_id, can be null -- was owner_id, can be null
ALTER TABLE ALTER TABLE
risks risks
ADD ADD
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE COLUMN owner_profile_id TEXT REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE
SET SET
NULL; NULL;
@@ -96,13 +103,13 @@ SET
ALTER TABLE ALTER TABLE
states_of_applicability states_of_applicability
ADD ADD
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT; COLUMN owner_profile_id TEXT REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
-- was assigned_to, can be null -- was assigned_to, can be null
ALTER TABLE ALTER TABLE
tasks tasks
ADD ADD
COLUMN assigned_to_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE COLUMN assigned_to_profile_id TEXT REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE
SET SET
NULL; NULL;
@@ -110,7 +117,7 @@ SET
ALTER TABLE ALTER TABLE
vendors vendors
ADD ADD
COLUMN business_owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE COLUMN business_owner_profile_id TEXT REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE
SET SET
NULL; NULL;
@@ -118,7 +125,7 @@ SET
ALTER TABLE ALTER TABLE
vendors vendors
ADD ADD
COLUMN security_owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE COLUMN security_owner_profile_id TEXT REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE
SET SET
NULL; NULL;
@@ -142,24 +149,18 @@ SELECT
FROM FROM
peoples p ON CONFLICT DO NOTHING; peoples p ON CONFLICT DO NOTHING;
-- 4. Create missing memberships & profiles -- 4. Create missing memberships
WITH people_identities AS ( WITH people_identities AS (
SELECT SELECT
i.id AS identity_id, i.id AS identity_id,
p.tenant_id AS tenant_id, p.tenant_id AS tenant_id,
p.organization_id AS organization_id, p.organization_id AS organization_id,
p.kind AS kind, p.contract_end_date AS contract_end_date
p.full_name AS full_name,
p.additional_email_addresses AS additional_email_addresses,
p.position AS position,
p.contract_start_date AS contract_start_date,
p.contract_end_date AS contract_end_date,
FROM FROM
peoples peoples p
JOIN identities i ON i.primary_email_address = p.primary_email_address INNER JOIN identities i ON i.email_address = p.primary_email_address
), )
people_memberships AS ( INSERT INTO
INSERT INTO
iam_memberships ( iam_memberships (
id, id,
tenant_id, tenant_id,
@@ -171,7 +172,7 @@ people_memberships AS (
created_at, created_at,
updated_at updated_at
) )
SELECT SELECT
generate_gid(decode_base64_unpadded(pi.tenant_id), 39), generate_gid(decode_base64_unpadded(pi.tenant_id), 39),
pi.tenant_id, pi.tenant_id,
pi.identity_id, pi.identity_id,
@@ -179,30 +180,39 @@ people_memberships AS (
'EMPLOYEE' :: authz_role, 'EMPLOYEE' :: authz_role,
'MANUAL', 'MANUAL',
CASE CASE
WHEN p.contract_end_date IS NOT NULL WHEN pi.contract_end_date IS NOT NULL
AND p.contract_end_date <= NOW() THEN 'INACTIVE' :: membership_state AND pi.contract_end_date <= NOW() THEN 'INACTIVE' :: membership_state
ELSE 'ACTIVE' :: membership_state ELSE 'ACTIVE' :: membership_state
END, END,
NOW(), NOW(),
NOW() NOW()
FROM
people_identities pi ON CONFLICT DO NOTHING;
-- 5. Create missing profiles
WITH people_memberships AS (
SELECT
i.id AS identity_id,
m.id AS membership_id,
p.tenant_id AS tenant_id,
p.kind AS kind,
p.full_name AS full_name,
p.additional_email_addresses AS additional_email_addresses,
p.position AS position,
p.contract_start_date AS contract_start_date,
p.contract_start_date AS contract_end_date
FROM FROM
people_identities pi ON CONFLICT DO NOTHING RETURNING id AS membership_id, peoples p
pi.identity_id AS identity_id, INNER JOIN identities i ON i.email_address = p.primary_email_address
pi.tenant_id AS tenant_id, INNER JOIN iam_memberships m ON m.identity_id = i.id
pi.organization_id AS organization_id, WHERE
pi.kind AS kind, p.organization_id = m.organization_id
pi.full_name AS full_name, )
pi.additional_email_addresses AS additional_email_addresses,
pi.position AS position,
pi.contract_start_date AS contract_start_date,
pi.contract_end_date AS contract_start_date,
) -- Create missing profiles
-- Note: we always have a profile for an existing membership (they are created together in the same TX),
-- So it is safe to create the missing profiles from the newly created memberships
INSERT INTO INSERT INTO
iam_membership_profiles ( iam_membership_profiles (
id, id,
tenant_id, tenant_id,
identity_id,
membership_id, membership_id,
full_name, full_name,
kind, kind,
@@ -216,6 +226,7 @@ INSERT INTO
SELECT SELECT
generate_gid(decode_base64_unpadded(pm.tenant_id), 51), generate_gid(decode_base64_unpadded(pm.tenant_id), 51),
pm.tenant_id, pm.tenant_id,
pm.identity_id,
pm.membership_id, pm.membership_id,
pm.full_name, pm.full_name,
pm.kind, pm.kind,
@@ -228,23 +239,26 @@ SELECT
FROM FROM
people_memberships pm ON CONFLICT DO NOTHING; people_memberships pm ON CONFLICT DO NOTHING;
-- 5. Update all profiles from peoples -- 6. Update all profiles from peoples
WITH people_memberships AS ( WITH people_memberships AS (
SELECT SELECT
m.id AS membership_id, m.id AS membership_id,
COALESCE(p.additional_email_addresses, [] :: CITEXT), COALESCE(
COALESCE(p.kind, 'EMPLOYEE' :: PEOPLE_KIND), p.additional_email_addresses,
'{}' :: CITEXT []
) AS additional_email_addresses,
COALESCE(p.kind, 'EMPLOYEE' :: PEOPLE_KIND) AS kind,
p.contract_start_date, p.contract_start_date,
p.contract_end_date, p.contract_end_date,
p.position, p.position
FROM FROM
iam_memberships m iam_memberships m
JOIN identities i ON i.id = m.identity_id INNER JOIN identities i ON i.id = m.identity_id
LEFT JOIN peoples p ON p.primary_email_address = i.email_address LEFT JOIN peoples p ON p.primary_email_address = i.email_address
AND p.organization_id = m.organization_id AND p.organization_id = m.organization_id
) )
UPDATE UPDATE
iam_membership_profiles iam_membership_profiles mp
SET SET
additional_email_addresses = pm.additional_email_addresses, additional_email_addresses = pm.additional_email_addresses,
kind = pm.kind, kind = pm.kind,
@@ -254,18 +268,30 @@ SET
FROM FROM
people_memberships pm people_memberships pm
WHERE WHERE
membership_id = pm.membership_id; mp.membership_id = pm.membership_id;
-- 6. Fill new references to profiles (e.g. previous references to peoples) ALTER TABLE
iam_membership_profiles
ALTER COLUMN
additional_email_addresses
SET
NOT NULL,
ALTER COLUMN
kind
SET
NOT NULL;
-- 7. Fill new references to profiles (e.g. previous references to peoples)
WITH people_profiles AS ( WITH people_profiles AS (
SELECT SELECT
mp.id AS membership_profile_id, mp.id AS membership_profile_id,
p.id AS people_id p.id AS people_id
FROM FROM
iam_membership_profiles mp iam_membership_profiles mp
JOIN iam_memberships m ON m.id = mp.membership_id INNER JOIN iam_memberships m ON m.id = mp.membership_id
JOIN identities i ON i.id = m.identity_id INNER JOIN identities i ON i.id = m.identity_id
LEFT JOIN peoples p ON p.primary_email_address = i.email_address LEFT JOIN peoples p ON p.primary_email_address = i.email_address
AND m.organization_id = p.organization_id
), ),
updated_assets AS ( updated_assets AS (
UPDATE UPDATE
@@ -416,7 +442,7 @@ FROM
WHERE WHERE
v.security_owner_id = pp.people_id; v.security_owner_id = pp.people_id;
-- 7. Now that references are filled, add the NOT NULL constraints to those who need it -- 8. Now that references are filled, add the NOT NULL constraints to those who need it
ALTER TABLE ALTER TABLE
assets assets
ALTER COLUMN ALTER COLUMN
@@ -480,11 +506,11 @@ ALTER COLUMN
SET SET
NOT NULL; NOT NULL;
-- 8. Expire any potential invitation that is now obsolete since we created memberships -- 9. Expire any potential invitation that is now obsolete since we created memberships
ALTER TABLE ALTER TABLE
iam_invitations iam_invitations
ALTER COLUMN ALTER COLUMN
email TYPE CITEXT []; email TYPE CITEXT;
WITH people_identities AS ( WITH people_identities AS (
SELECT SELECT