Skip to content

Commit

Permalink
fix: Fix "Standardize phone number identifiers" migration [CHI-2673] (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
GPaoloni authored Apr 16, 2024
1 parent fed5d07 commit 1cd0399
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 15 deletions.
8 changes: 3 additions & 5 deletions hrm-domain/hrm-core/profile/profileService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,6 @@ export {
SearchParameters,
} from './profileDataAccess';

const sanitizeIdentifier = (i: string) => i.replace(' ', '');

export const getProfile =
(task?) =>
async (
Expand All @@ -69,7 +67,7 @@ export const createIdentifierAndProfile =
return txIfNotInOne(task, async t => {
try {
const newIdentifier = await profileDB.createIdentifier(t)(accountSid, {
identifier: sanitizeIdentifier(identifier.identifier),
identifier: identifier.identifier,
createdBy: user.workerSid,
});
const newProfile = await profileDB.createProfile(t)(accountSid, {
Expand Down Expand Up @@ -116,7 +114,7 @@ export const getOrCreateProfileWithIdentifier =

const profileResult = await profileDB.getIdentifierWithProfiles(task)({
accountSid,
identifier: sanitizeIdentifier(identifier.identifier),
identifier: identifier.identifier,
});

if (profileResult) {
Expand Down Expand Up @@ -185,7 +183,7 @@ export const getIdentifierByIdentifier = async (
): Promise<profileDB.IdentifierWithProfiles> =>
profileDB.getIdentifierWithProfiles()({
accountSid,
identifier: sanitizeIdentifier(identifier),
identifier: identifier,
});

export const listProfiles = profileDB.listProfiles;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,65 @@
module.exports = {
up: async queryInterface => {
await queryInterface.sequelize.query(`
DO $$
DECLARE idx public."Identifiers";
BEGIN
-- For each identifier in Identifier with spaces
FOR idx IN (SELECT * FROM "Identifiers" WHERE "identifier" LIKE '% %') LOOP
-- Remove any blank spaces that the identifiers might have
UPDATE "Identifiers" SET "identifier" = replace(idx."identifier", ' ', '') WHERE id = idx.id;
END LOOP;
END$$
-- Fix the contacts for the conflicting records
UPDATE "Contacts" SET "profileId" = sanitized."targetProfile", "identifierId" = sanitized."targetId"
FROM (
--- All identifiers with conflicts, plus the "target id" which is the minimal id that matches the sanitized identifier
SELECT "main"."id" AS "conflictId", "main"."accountSid", "grouped"."targetId", "p2i"."profileId" AS "targetProfile"
FROM "Identifiers" "main"
INNER JOIN (
SELECT "accountSid", replace("identifier", ' ', '') AS "sanitized", MIN("id") AS "targetId" FROM "Identifiers" GROUP BY "accountSid", replace("identifier", ' ', '') HAVING COUNT(*) > 1
) "grouped" ON replace("main"."identifier", ' ', '')="grouped"."sanitized" AND "main"."accountSid"="grouped"."accountSid"
INNER JOIN "ProfilesToIdentifiers" "p2i" ON "p2i"."identifierId" = "grouped"."targetId"
ORDER BY replace("identifier", ' ', '')
) AS sanitized WHERE "identifierId" = sanitized."conflictId" AND "identifierId" != sanitized."targetId"
`);
console.log('Sequence "Profiles_id_seq" created');
console.log('Contacts fixed');

await queryInterface.sequelize.query(`
DELETE FROM "Profiles" WHERE "id" IN (
SELECT "p2i"."profileId" AS "conflictProfileId"
FROM (
--- All identifiers with conflicts, plus the "target id" which is the minimal id that matches the sanitized identifier
SELECT "main"."id" AS "conflictId", "main"."accountSid", "grouped"."targetId", "p2i"."profileId" AS "targetProfile"
FROM "Identifiers" "main"
INNER JOIN (
SELECT "accountSid", replace("identifier", ' ', '') AS "sanitized", MIN("id") AS "targetId" FROM "Identifiers" GROUP BY "accountSid", replace("identifier", ' ', '') HAVING COUNT(*) > 1
) "grouped" ON replace("main"."identifier", ' ', '')="grouped"."sanitized" AND "main"."accountSid"="grouped"."accountSid"
INNER JOIN "ProfilesToIdentifiers" "p2i" ON "p2i"."identifierId" = "grouped"."targetId"
ORDER BY replace("identifier", ' ', '')
) AS "sanitized"
INNER JOIN "ProfilesToIdentifiers" "p2i" ON "p2i"."identifierId" = "sanitized"."conflictId" AND "p2i"."identifierId" != "sanitized"."targetId"
)
`);
console.log('Conflicting profiles deleted');

await queryInterface.sequelize.query(`
DELETE FROM "Identifiers" WHERE "id" IN (
SELECT "idx"."id" AS "conflictIdentifierId"
FROM (
--- All identifiers with conflicts, plus the "target id" which is the minimal id that matches the sanitized identifier
SELECT "main"."id" AS "conflictId", "grouped"."targetId"
FROM "Identifiers" "main"
INNER JOIN (
SELECT "accountSid", replace("identifier", ' ', '') AS "sanitized", MIN("id") AS "targetId" FROM "Identifiers" GROUP BY "accountSid", replace("identifier", ' ', '') HAVING COUNT(*) > 1
) "grouped" ON replace("main"."identifier", ' ', '')="grouped"."sanitized" AND "main"."accountSid"="grouped"."accountSid"
ORDER BY replace("identifier", ' ', '')
) AS "sanitized"
INNER JOIN "Identifiers" "idx" ON "idx"."id" = "sanitized"."conflictId" AND "idx"."id" != "sanitized"."targetId"
)
`);
console.log('Conflicting identifiers deleted');

await queryInterface.sequelize.query(`
UPDATE "Identifiers" "idx" SET "identifier" = replace("idx"."identifier", ' ', '')
FROM (
SELECT DISTINCT identifiers.* FROM "Identifiers" identifiers
JOIN "Contacts" contacts ON identifiers.id = contacts."identifierId"
WHERE identifiers.identifier LIKE '% %' AND contacts."channel" IN ('voice', 'whatsapp', 'sms', 'modica')
) AS "whitespaced" WHERE "idx"."id" = "whitespaced"."id"
`);
console.log('Whitespaced identifiers sanitized');
},

down: async () => {},
Expand Down

0 comments on commit 1cd0399

Please sign in to comment.