From 83417aba1686436726fde93095bce51ee1a4de99 Mon Sep 17 00:00:00 2001 From: Hammad Jutt Date: Sun, 17 Jan 2021 22:23:56 -0700 Subject: [PATCH] Add step to remove duplicate players in migrateSourceCredAccounts handler (#280) Some accounts in SourceCred get merged after they had already been added in the database (e.g. merging a discord and discourse identity) which causes conflicts in the database when we try to set an ETH address for the new merged account that conflicts with the old unmerged account. --- .../migrateSourceCredAccounts/handler.ts | 34 +++++++++++++++++-- .../backend/src/handlers/graphql/mutations.ts | 13 ++++++- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/packages/backend/src/handlers/actions/migrateSourceCredAccounts/handler.ts b/packages/backend/src/handlers/actions/migrateSourceCredAccounts/handler.ts index dc403aaa..22cd186c 100644 --- a/packages/backend/src/handlers/actions/migrateSourceCredAccounts/handler.ts +++ b/packages/backend/src/handlers/actions/migrateSourceCredAccounts/handler.ts @@ -28,6 +28,26 @@ const VALID_ACCOUNT_TYPES: Array = [ AccountType_Enum.Twitter, ]; +const parseMergedIdentityId = (alias: SCAlias) => { + try { + const addressParts = api.core.graph.NodeAddress.toParts(alias.address); + + if ( + addressParts[1].toUpperCase() === 'CORE' && + addressParts[2].toUpperCase() === 'IDENTITY' + ) { + return addressParts[addressParts.length - 1]; + } + return null; + } catch (e) { + console.log('Unable to parse merged identity: ', { + error: e.message, + alias, + }); + return null; + } +}; + const parseAlias = (alias: SCAlias) => { try { const addressParts = api.core.graph.NodeAddress.toParts(alias.address); @@ -86,6 +106,10 @@ export const migrateSourceCredAccounts = async ( }) .filter(isNotNullOrUndefined); + const mergedIdentityIds = a.account.identity.aliases + .map((alias) => parseMergedIdentityId(alias)) + .filter(isNotNullOrUndefined); + const discordId = linkedAccounts.find(({ type }) => type === 'DISCORD') ?.identifier; @@ -98,6 +122,7 @@ export const migrateSourceCredAccounts = async ( totalXp: a.totalCred, rank: RANKS[Math.floor(index / NUM_PLAYERS_PER_RANK)], discordId, + mergedIdentityIds, Accounts: { data: linkedAccounts, on_conflict: accountOnConflict, @@ -117,6 +142,11 @@ export const migrateSourceCredAccounts = async ( totalXp: player.totalXp, discordId: player.discordId || '', }; + if (player.mergedIdentityIds.length) { + await client.DeleteDuplicatePlayers({ + scIds: player.mergedIdentityIds, + }); + } try { const updateResult = await client.UpdatePlayer(vars); @@ -158,12 +188,12 @@ export const migrateSourceCredAccounts = async ( ); const usersToInsert: Player_Insert_Input[] = result .filter(isNotNullOrUndefined) - .map(player => ({ + .map((player) => ({ username: player.username, ethereum_address: player.ethereum_address, sc_identity_id: player.scIdentityId, rank: player.rank, - total_xp: player.totalXp + total_xp: player.totalXp, })); const resultInsert = await client.UpsertPlayer({ diff --git a/packages/backend/src/handlers/graphql/mutations.ts b/packages/backend/src/handlers/graphql/mutations.ts index 0630026b..37ff72bb 100644 --- a/packages/backend/src/handlers/graphql/mutations.ts +++ b/packages/backend/src/handlers/graphql/mutations.ts @@ -39,6 +39,18 @@ export const UpsertPlayer = gql` } } `; +export const DeleteDuplicatePlayers = gql` + mutation DeleteDuplicatePlayers($scIds: [String!] = "") { + delete_player_account( + where: { Player: { sc_identity_id: { _in: $scIds } } } + ) { + affected_rows + } + delete_player(where: { sc_identity_id: { _in: $scIds } }) { + affected_rows + } + } +`; export const UpdatePlayer = gql` mutation UpdatePlayer( @@ -71,7 +83,6 @@ export const UpdatePlayer = gql` _set: { ethereum_address: $ethAddress sc_identity_id: $identityId - username: $username rank: $rank total_xp: $totalXp }