Migrate people to identities / memberships / profiles
Signed-off-by: Émile Ré <emile@getprobo.com>
This commit is contained in:
@@ -24,15 +24,21 @@ import (
|
|||||||
"github.com/jackc/pgx/v5"
|
"github.com/jackc/pgx/v5"
|
||||||
"go.gearno.de/kit/pg"
|
"go.gearno.de/kit/pg"
|
||||||
"go.probo.inc/probo/pkg/gid"
|
"go.probo.inc/probo/pkg/gid"
|
||||||
|
"go.probo.inc/probo/pkg/mail"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
MembershipProfile struct {
|
MembershipProfile struct {
|
||||||
ID gid.GID `db:"id"`
|
ID gid.GID `db:"id"`
|
||||||
MembershipID gid.GID `db:"membership_id"`
|
MembershipID gid.GID `db:"membership_id"`
|
||||||
FullName string `db:"full_name"`
|
FullName string `db:"full_name"`
|
||||||
CreatedAt time.Time `db:"created_at"`
|
Kind PeopleKind `db:"kind"`
|
||||||
UpdatedAt time.Time `db:"updated_at"`
|
AdditionalEmailAddresses mail.Addrs `db:"additional_email_addresses"`
|
||||||
|
Position *string `db:"position"`
|
||||||
|
ContractStartDate *time.Time `db:"contract_start_date"`
|
||||||
|
ContractEndDate *time.Time `db:"contract_end_date"`
|
||||||
|
CreatedAt time.Time `db:"created_at"`
|
||||||
|
UpdatedAt time.Time `db:"updated_at"`
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -61,12 +67,17 @@ SELECT
|
|||||||
id,
|
id,
|
||||||
membership_id,
|
membership_id,
|
||||||
full_name,
|
full_name,
|
||||||
|
kind,
|
||||||
|
additionalEmailAddresses,
|
||||||
|
position,
|
||||||
|
contract_start_date,
|
||||||
|
contract_end_date,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM
|
FROM
|
||||||
iam_membership_profiles
|
iam_membership_profiles
|
||||||
WHERE
|
WHERE
|
||||||
%s
|
%s
|
||||||
AND membership_id = @membership_id
|
AND membership_id = @membership_id
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
`
|
`
|
||||||
@@ -106,12 +117,17 @@ SELECT
|
|||||||
id,
|
id,
|
||||||
membership_id,
|
membership_id,
|
||||||
full_name,
|
full_name,
|
||||||
|
kind,
|
||||||
|
additionalEmailAddresses,
|
||||||
|
position,
|
||||||
|
contract_start_date,
|
||||||
|
contract_end_date,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
FROM
|
FROM
|
||||||
iam_membership_profiles
|
iam_membership_profiles
|
||||||
WHERE
|
WHERE
|
||||||
%s
|
%s
|
||||||
AND id = @profile_id
|
AND id = @profile_id
|
||||||
LIMIT 1;
|
LIMIT 1;
|
||||||
`
|
`
|
||||||
@@ -151,6 +167,11 @@ INSERT INTO
|
|||||||
id,
|
id,
|
||||||
membership_id,
|
membership_id,
|
||||||
full_name,
|
full_name,
|
||||||
|
kind,
|
||||||
|
additionalEmailAddresses,
|
||||||
|
position,
|
||||||
|
contract_start_date,
|
||||||
|
contract_end_date,
|
||||||
created_at,
|
created_at,
|
||||||
updated_at
|
updated_at
|
||||||
)
|
)
|
||||||
@@ -159,18 +180,28 @@ VALUES (
|
|||||||
@id,
|
@id,
|
||||||
@membership_id,
|
@membership_id,
|
||||||
@full_name,
|
@full_name,
|
||||||
|
@kind,
|
||||||
|
@additionalEmailAddresses,
|
||||||
|
@position,
|
||||||
|
@contract_start_date,
|
||||||
|
@contract_end_date,
|
||||||
@created_at,
|
@created_at,
|
||||||
@updated_at
|
@updated_at
|
||||||
)
|
)
|
||||||
`
|
`
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
args := pgx.StrictNamedArgs{
|
||||||
"tenant_id": p.ID.TenantID().String(),
|
"tenant_id": p.ID.TenantID().String(),
|
||||||
"id": p.ID,
|
"id": p.ID,
|
||||||
"membership_id": p.MembershipID,
|
"membership_id": p.MembershipID,
|
||||||
"full_name": p.FullName,
|
"full_name": p.FullName,
|
||||||
"created_at": p.CreatedAt,
|
"kind": p.Kind,
|
||||||
"updated_at": p.UpdatedAt,
|
"additionalEmailAddresses": p.AdditionalEmailAddresses,
|
||||||
|
"position": p.Position,
|
||||||
|
"contract_start_date": p.ContractStartDate,
|
||||||
|
"contract_end_date": p.ContractEndDate,
|
||||||
|
"created_at": p.CreatedAt,
|
||||||
|
"updated_at": p.UpdatedAt,
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := conn.Exec(ctx, q, args)
|
_, err := conn.Exec(ctx, q, args)
|
||||||
@@ -191,6 +222,11 @@ UPDATE
|
|||||||
iam_membership_profiles
|
iam_membership_profiles
|
||||||
SET
|
SET
|
||||||
full_name = @full_name,
|
full_name = @full_name,
|
||||||
|
kind = @kind,
|
||||||
|
additionalEmailAddresses = @additionalEmailAddresses,
|
||||||
|
position = @position,
|
||||||
|
contract_start_date = @contract_start_date,
|
||||||
|
contract_end_date = @contract_end_date,
|
||||||
updated_at = @updated_at
|
updated_at = @updated_at
|
||||||
WHERE
|
WHERE
|
||||||
id = @id
|
id = @id
|
||||||
@@ -200,9 +236,14 @@ WHERE
|
|||||||
q = fmt.Sprintf(q, scope.SQLFragment())
|
q = fmt.Sprintf(q, scope.SQLFragment())
|
||||||
|
|
||||||
args := pgx.StrictNamedArgs{
|
args := pgx.StrictNamedArgs{
|
||||||
"id": p.ID,
|
"id": p.ID,
|
||||||
"full_name": p.FullName,
|
"full_name": p.FullName,
|
||||||
"updated_at": p.UpdatedAt,
|
"kind": p.Kind,
|
||||||
|
"additionalEmailAddresses": p.AdditionalEmailAddresses,
|
||||||
|
"position": p.Position,
|
||||||
|
"contract_start_date": p.ContractStartDate,
|
||||||
|
"contract_end_date": p.ContractEndDate,
|
||||||
|
"updated_at": p.UpdatedAt,
|
||||||
}
|
}
|
||||||
maps.Copy(args, scope.SQLArguments())
|
maps.Copy(args, scope.SQLArguments())
|
||||||
|
|
||||||
|
|||||||
498
pkg/coredata/migrations/20260203T132700Z.sql
Normal file
498
pkg/coredata/migrations/20260203T132700Z.sql
Normal file
@@ -0,0 +1,498 @@
|
|||||||
|
-- 1. Add peoples column onto profiles
|
||||||
|
ALTER TABLE
|
||||||
|
iam_membership_profiles
|
||||||
|
ADD
|
||||||
|
COLUMN additional_email_addresses CITEXT [] NOT NULL,
|
||||||
|
ADD
|
||||||
|
COLUMN kind PEOPLE_KIND NOT NULL,
|
||||||
|
ADD
|
||||||
|
COLUMN contract_start_date DATE,
|
||||||
|
ADD
|
||||||
|
COLUMN contract_end_date DATE,
|
||||||
|
ADD
|
||||||
|
COLUMN position TEXT;
|
||||||
|
|
||||||
|
-- 2. Add profile references to all table referencing peoples
|
||||||
|
-- was owner_id, NOT NULL
|
||||||
|
ALTER TABLE
|
||||||
|
assets
|
||||||
|
ADD
|
||||||
|
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
|
||||||
|
|
||||||
|
-- was owner_id, NOT NULL
|
||||||
|
ALTER TABLE
|
||||||
|
continual_improvements
|
||||||
|
ADD
|
||||||
|
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
|
||||||
|
|
||||||
|
-- was owner_id, NOT NULL
|
||||||
|
ALTER TABLE
|
||||||
|
data
|
||||||
|
ADD
|
||||||
|
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
|
||||||
|
|
||||||
|
-- was owner_id, NOT NULL
|
||||||
|
ALTER TABLE
|
||||||
|
document_versions
|
||||||
|
ADD
|
||||||
|
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
|
||||||
|
|
||||||
|
-- was attendee_id, NOT NULL
|
||||||
|
ALTER TABLE
|
||||||
|
meeting_attendees
|
||||||
|
ADD
|
||||||
|
COLUMN attendee_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE CASCADE;
|
||||||
|
|
||||||
|
-- was owner_id, NOT NULL
|
||||||
|
ALTER TABLE
|
||||||
|
nonconformities
|
||||||
|
ADD
|
||||||
|
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
|
||||||
|
|
||||||
|
-- was owner_id, NOT NULL
|
||||||
|
ALTER TABLE
|
||||||
|
obligations
|
||||||
|
ADD
|
||||||
|
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
|
||||||
|
|
||||||
|
-- was owner_id, can be null
|
||||||
|
ALTER TABLE
|
||||||
|
documents
|
||||||
|
ADD
|
||||||
|
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id);
|
||||||
|
|
||||||
|
-- was signed_by, NOT NULL
|
||||||
|
ALTER TABLE
|
||||||
|
document_version_signatures
|
||||||
|
ADD
|
||||||
|
COLUMN signed_by_profile_id REFERENCES iam_membership_profiles(id);
|
||||||
|
|
||||||
|
-- was data_protection_officer_id, can be null
|
||||||
|
ALTER TABLE
|
||||||
|
processing_activities
|
||||||
|
ADD
|
||||||
|
COLUMN dpo_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
|
||||||
|
|
||||||
|
-- was owner_id, can be null
|
||||||
|
ALTER TABLE
|
||||||
|
risks
|
||||||
|
ADD
|
||||||
|
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE
|
||||||
|
SET
|
||||||
|
NULL;
|
||||||
|
|
||||||
|
-- was owner_id, NOT NULL
|
||||||
|
ALTER TABLE
|
||||||
|
states_of_applicability
|
||||||
|
ADD
|
||||||
|
COLUMN owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE RESTRICT;
|
||||||
|
|
||||||
|
-- was assigned_to, can be null
|
||||||
|
ALTER TABLE
|
||||||
|
tasks
|
||||||
|
ADD
|
||||||
|
COLUMN assigned_to_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE
|
||||||
|
SET
|
||||||
|
NULL;
|
||||||
|
|
||||||
|
-- was business_owner_id, can be null
|
||||||
|
ALTER TABLE
|
||||||
|
vendors
|
||||||
|
ADD
|
||||||
|
COLUMN business_owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE
|
||||||
|
SET
|
||||||
|
NULL;
|
||||||
|
|
||||||
|
-- was security_owner_id, can be null
|
||||||
|
ALTER TABLE
|
||||||
|
vendors
|
||||||
|
ADD
|
||||||
|
COLUMN security_owner_profile_id REFERENCES iam_membership_profiles(id) ON UPDATE CASCADE ON DELETE
|
||||||
|
SET
|
||||||
|
NULL;
|
||||||
|
|
||||||
|
-- 3. Create missing identities
|
||||||
|
INSERT INTO
|
||||||
|
identities (
|
||||||
|
id,
|
||||||
|
created_at,
|
||||||
|
updated_at,
|
||||||
|
email_address,
|
||||||
|
email_address_verified,
|
||||||
|
full_name
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
generate_gid('\x0000000000000000' :: bytea, 11),
|
||||||
|
NOW(),
|
||||||
|
NOW(),
|
||||||
|
p.primary_email_address,
|
||||||
|
FALSE,
|
||||||
|
p.full_name
|
||||||
|
FROM
|
||||||
|
peoples p ON CONFLICT DO NOTHING;
|
||||||
|
|
||||||
|
-- 4. Create missing memberships & profiles
|
||||||
|
WITH people_identities AS (
|
||||||
|
SELECT
|
||||||
|
i.id AS identity_id,
|
||||||
|
p.tenant_id AS tenant_id,
|
||||||
|
p.organization_id AS organization_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_end_date AS contract_end_date,
|
||||||
|
sc.id IS NOT NULL AS scim
|
||||||
|
FROM
|
||||||
|
peoples
|
||||||
|
JOIN identities i ON i.primary_email_address = p.primary_email_address
|
||||||
|
JOIN organizations o ON o.id = p.organization_id
|
||||||
|
LEFT JOIN iam_scim_configurations sc ON sc.organization_id = o.id
|
||||||
|
),
|
||||||
|
people_memberships AS (
|
||||||
|
INSERT INTO
|
||||||
|
iam_memberships (
|
||||||
|
id,
|
||||||
|
tenant_id,
|
||||||
|
identity_id,
|
||||||
|
organization_id,
|
||||||
|
role,
|
||||||
|
source,
|
||||||
|
state,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
generate_gid(decode_base64_unpadded(pi.tenant_id), 39),
|
||||||
|
pi.tenant_id,
|
||||||
|
pi.identity_id,
|
||||||
|
pi.organization_id,
|
||||||
|
'EMPLOYEE' :: authz_role,
|
||||||
|
'MANUAL',
|
||||||
|
CASE
|
||||||
|
WHEN pi.scim THEN 'INACTIVE' :: membership_state
|
||||||
|
ELSE 'ACTIVE' :: membership_state
|
||||||
|
END,
|
||||||
|
NOW(),
|
||||||
|
NOW()
|
||||||
|
FROM
|
||||||
|
people_identities pi ON CONFLICT DO NOTHING RETURNING id AS membership_id,
|
||||||
|
pi.identity_id AS identity_id,
|
||||||
|
pi.tenant_id AS tenant_id,
|
||||||
|
pi.organization_id AS organization_id,
|
||||||
|
pi.kind AS kind,
|
||||||
|
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
|
||||||
|
iam_membership_profiles (
|
||||||
|
id,
|
||||||
|
tenant_id,
|
||||||
|
membership_id,
|
||||||
|
full_name,
|
||||||
|
kind,
|
||||||
|
additional_email_addresses,
|
||||||
|
position,
|
||||||
|
contract_start_date,
|
||||||
|
contract_end_date,
|
||||||
|
created_at,
|
||||||
|
updated_at
|
||||||
|
)
|
||||||
|
SELECT
|
||||||
|
generate_gid(decode_base64_unpadded(pm.tenant_id), 51),
|
||||||
|
pm.tenant_id,
|
||||||
|
pm.membership_id,
|
||||||
|
pm.full_name,
|
||||||
|
pm.kind,
|
||||||
|
pm.additional_email_addresses,
|
||||||
|
pm.position,
|
||||||
|
pm.contract_start_date,
|
||||||
|
pm.contract_end_date,
|
||||||
|
NOW(),
|
||||||
|
NOW()
|
||||||
|
FROM
|
||||||
|
people_memberships pm ON CONFLICT DO NOTHING;
|
||||||
|
|
||||||
|
-- 5. Update all profiles from peoples
|
||||||
|
WITH people_memberships AS (
|
||||||
|
SELECT
|
||||||
|
m.id AS membership_id,
|
||||||
|
COALESCE(p.additional_email_addresses, [] :: CITEXT),
|
||||||
|
COALESCE(p.kind, 'EMPLOYEE' :: PEOPLE_KIND),
|
||||||
|
p.contract_start_date,
|
||||||
|
p.contract_end_date,
|
||||||
|
p.position,
|
||||||
|
FROM
|
||||||
|
iam_memberships m
|
||||||
|
JOIN identities i ON i.id = m.identity_id
|
||||||
|
LEFT JOIN peoples p ON p.primary_email_address = i.email_address
|
||||||
|
AND p.organization_id = m.organization_id
|
||||||
|
)
|
||||||
|
UPDATE
|
||||||
|
iam_membership_profiles
|
||||||
|
SET
|
||||||
|
additional_email_addresses = pm.additional_email_addresses,
|
||||||
|
kind = pm.kind,
|
||||||
|
contract_start_date = pm.contract_start_date,
|
||||||
|
contract_end_date = pm.contract_end_date,
|
||||||
|
position = pm.position
|
||||||
|
FROM
|
||||||
|
people_memberships pm
|
||||||
|
WHERE
|
||||||
|
membership_id = pm.membership_id;
|
||||||
|
|
||||||
|
-- 6. Fill new references to profiles (e.g. previous references to peoples)
|
||||||
|
WITH people_profiles AS (
|
||||||
|
SELECT
|
||||||
|
mp.id AS membership_profile_id,
|
||||||
|
p.id AS people_id
|
||||||
|
FROM
|
||||||
|
iam_membership_profiles mp
|
||||||
|
JOIN iam_memberships m ON m.id = mp.membership_id
|
||||||
|
JOIN identities i ON i.id = m.identity_id
|
||||||
|
LEFT JOIN peoples p ON p.primary_email_address = i.email_address
|
||||||
|
),
|
||||||
|
updated_assets AS (
|
||||||
|
UPDATE
|
||||||
|
assets a
|
||||||
|
SET
|
||||||
|
owner_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
a.owner_id = pp.people_id
|
||||||
|
),
|
||||||
|
updated_ci AS (
|
||||||
|
UPDATE
|
||||||
|
continual_improvements ci
|
||||||
|
SET
|
||||||
|
owner_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
ci.owner_id = pp.people_id
|
||||||
|
),
|
||||||
|
updated_data AS (
|
||||||
|
UPDATE
|
||||||
|
data d
|
||||||
|
SET
|
||||||
|
owner_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
d.owner_id = pp.people_id
|
||||||
|
),
|
||||||
|
updated_dv AS (
|
||||||
|
UPDATE
|
||||||
|
document_versions dv
|
||||||
|
SET
|
||||||
|
owner_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
dv.owner_id = pp.people_id
|
||||||
|
),
|
||||||
|
updated_ma AS (
|
||||||
|
UPDATE
|
||||||
|
meeting_attendees ma
|
||||||
|
SET
|
||||||
|
attendee_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
ma.attendee_id = pp.people_id
|
||||||
|
),
|
||||||
|
updated_nc AS (
|
||||||
|
UPDATE
|
||||||
|
nonconformities nc
|
||||||
|
SET
|
||||||
|
owner_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
nc.owner_id = pp.people_id
|
||||||
|
),
|
||||||
|
updated_obligations AS (
|
||||||
|
UPDATE
|
||||||
|
obligations o
|
||||||
|
SET
|
||||||
|
owner_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
o.owner_id = pp.people_id
|
||||||
|
),
|
||||||
|
updated_documents AS (
|
||||||
|
UPDATE
|
||||||
|
documents d
|
||||||
|
SET
|
||||||
|
owner_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
d.owner_id = pp.people_id
|
||||||
|
),
|
||||||
|
updated_dvs AS (
|
||||||
|
UPDATE
|
||||||
|
document_version_signatures dvs
|
||||||
|
SET
|
||||||
|
signed_by_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
dvs.signed_by = pp.people_id
|
||||||
|
),
|
||||||
|
updated_pa AS (
|
||||||
|
UPDATE
|
||||||
|
processing_activities pa
|
||||||
|
SET
|
||||||
|
dpo_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
pa.data_protection_officer_id = pp.people_id
|
||||||
|
),
|
||||||
|
updated_risks AS (
|
||||||
|
UPDATE
|
||||||
|
risks r
|
||||||
|
SET
|
||||||
|
owner_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
r.owner_id = pp.people_id
|
||||||
|
),
|
||||||
|
updated_soa AS (
|
||||||
|
UPDATE
|
||||||
|
states_of_applicability soa
|
||||||
|
SET
|
||||||
|
owner_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
soa.owner_id = pp.people_id
|
||||||
|
),
|
||||||
|
updated_tasks AS (
|
||||||
|
UPDATE
|
||||||
|
tasks t
|
||||||
|
SET
|
||||||
|
assigned_to_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
t.assigned_to = pp.people_id
|
||||||
|
),
|
||||||
|
updated_vendors AS (
|
||||||
|
UPDATE
|
||||||
|
vendors v
|
||||||
|
SET
|
||||||
|
business_owner_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
v.business_owner_id = pp.people_id
|
||||||
|
)
|
||||||
|
UPDATE
|
||||||
|
vendors v
|
||||||
|
SET
|
||||||
|
security_owner_profile_id = pp.membership_profile_id
|
||||||
|
FROM
|
||||||
|
people_profiles pp
|
||||||
|
WHERE
|
||||||
|
v.security_owner_id = pp.people_id;
|
||||||
|
|
||||||
|
-- 7. Now that references are filled, add the NOT NULL constraints to those who need it
|
||||||
|
ALTER TABLE
|
||||||
|
assets
|
||||||
|
ALTER COLUMN
|
||||||
|
owner_profile_id
|
||||||
|
SET
|
||||||
|
NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE
|
||||||
|
continual_improvements
|
||||||
|
ALTER COLUMN
|
||||||
|
owner_profile_id
|
||||||
|
SET
|
||||||
|
NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE
|
||||||
|
data
|
||||||
|
ALTER COLUMN
|
||||||
|
owner_profile_id
|
||||||
|
SET
|
||||||
|
NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE
|
||||||
|
document_versions
|
||||||
|
ALTER COLUMN
|
||||||
|
owner_profile_id
|
||||||
|
SET
|
||||||
|
NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE
|
||||||
|
meeting_attendees
|
||||||
|
ALTER COLUMN
|
||||||
|
attendee_profile_id
|
||||||
|
SET
|
||||||
|
NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE
|
||||||
|
nonconformities
|
||||||
|
ALTER COLUMN
|
||||||
|
owner_profile_id
|
||||||
|
SET
|
||||||
|
NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE
|
||||||
|
obligations
|
||||||
|
ALTER COLUMN
|
||||||
|
owner_profile_id
|
||||||
|
SET
|
||||||
|
NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE
|
||||||
|
document_version_signatures
|
||||||
|
ALTER COLUMN
|
||||||
|
signed_by_profile_id
|
||||||
|
SET
|
||||||
|
NOT NULL;
|
||||||
|
|
||||||
|
ALTER TABLE
|
||||||
|
states_of_applicability
|
||||||
|
ALTER COLUMN
|
||||||
|
owner_profile_id
|
||||||
|
SET
|
||||||
|
NOT NULL;
|
||||||
|
|
||||||
|
-- 8. Expire any potential invitation that is now obsolete since we created memberships
|
||||||
|
ALTER TABLE
|
||||||
|
iam_invitations
|
||||||
|
ALTER COLUMN
|
||||||
|
email TYPE CITEXT [];
|
||||||
|
|
||||||
|
WITH people_identities AS (
|
||||||
|
SELECT
|
||||||
|
m.organization_id AS organization_id,
|
||||||
|
i.email_address AS email_address
|
||||||
|
FROM
|
||||||
|
iam_memberships m
|
||||||
|
JOIN identities i ON i.id = m.identity_id
|
||||||
|
JOIN peoples p ON p.primary_email_address = i.email_address
|
||||||
|
AND p.organization_id = m.organization_id
|
||||||
|
)
|
||||||
|
UPDATE
|
||||||
|
iam_invitations i
|
||||||
|
SET
|
||||||
|
expires_at = NOW()
|
||||||
|
FROM
|
||||||
|
people_identities pi
|
||||||
|
WHERE
|
||||||
|
pi.organization_id = i.organization_id
|
||||||
|
AND i.email = pi.email_address;
|
||||||
@@ -287,7 +287,7 @@ func (s *AccountService) AcceptInvitation(
|
|||||||
return fmt.Errorf("cannot update invitation: %w", err)
|
return fmt.Errorf("cannot update invitation: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Accept other pending invitations for email in organization
|
// Expire other pending invitations for email in organization
|
||||||
invitations := &coredata.Invitations{}
|
invitations := &coredata.Invitations{}
|
||||||
onlyPending := coredata.NewInvitationFilter([]coredata.InvitationStatus{coredata.InvitationStatusPending})
|
onlyPending := coredata.NewInvitationFilter([]coredata.InvitationStatus{coredata.InvitationStatusPending})
|
||||||
if err := invitations.ExpireByEmailAndOrganization(
|
if err := invitations.ExpireByEmailAndOrganization(
|
||||||
|
|||||||
@@ -1852,7 +1852,7 @@ func (r *mutationResolver) CreateTrustCenterAccess(ctx context.Context, input ty
|
|||||||
|
|
||||||
prb := r.ProboService(ctx, input.TrustCenterID.TenantID())
|
prb := r.ProboService(ctx, input.TrustCenterID.TenantID())
|
||||||
|
|
||||||
// TODO: should not create an access nor identity, but send an invitation
|
// TODO: should not create an access nor identity, but send a compliance page invitation
|
||||||
identity, err := r.iam.AuthService.LoadOrCreateIdentity(
|
identity, err := r.iam.AuthService.LoadOrCreateIdentity(
|
||||||
ctx,
|
ctx,
|
||||||
&iam.LoadOrCreateIdentityRequest{
|
&iam.LoadOrCreateIdentityRequest{
|
||||||
|
|||||||
Reference in New Issue
Block a user