mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-08-20 10:04:57 -05:00
Handle new account having a team in account merge Closes #2308
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import type { Transaction } from "kysely";
|
||||
import { db, sql } from "~/db/sql";
|
||||
import type { Tables } from "~/db/tables";
|
||||
import type { DB, Tables } from "~/db/tables";
|
||||
import { dateToDatabaseTimestamp } from "~/utils/dates";
|
||||
import invariant from "~/utils/invariant";
|
||||
import { syncXPBadges } from "../badges/queries/syncXPBadges.server";
|
||||
@@ -33,8 +34,21 @@ export const cleanUp = () => {
|
||||
cleanUpStm.run();
|
||||
};
|
||||
|
||||
/**
|
||||
* Migrates user-related data. Takes data from the "old user" and remaps it to the Discord ID of the "new user". Used when user switches their Discord accounts.
|
||||
*
|
||||
* @param args - An object containing:
|
||||
* - `newUserId`: The ID of the user whose data will be migrated and then deleted.
|
||||
* - `oldUserId`: The ID of the user who will receive the migrated data.
|
||||
* @returns A promise that resolves to `null` if the migration succeeds, or an error message if validation fails.
|
||||
*/
|
||||
export function migrate(args: { newUserId: number; oldUserId: number }) {
|
||||
return db.transaction().execute(async (trx) => {
|
||||
const error = await validateMigration(trx, args);
|
||||
if (error) {
|
||||
return error;
|
||||
}
|
||||
|
||||
// delete some limited data from the target user
|
||||
// idea is to make the migration a bit more smooth
|
||||
// since it won't fail if some small thing has been added
|
||||
@@ -53,6 +67,24 @@ export function migrate(args: { newUserId: number; oldUserId: number }) {
|
||||
.where("userId", "=", args.newUserId)
|
||||
.set({ userId: args.oldUserId })
|
||||
.execute();
|
||||
await trx
|
||||
.updateTable("UnvalidatedUserSubmittedImage")
|
||||
.where("submitterUserId", "=", args.newUserId)
|
||||
.set({ submitterUserId: args.oldUserId })
|
||||
.execute();
|
||||
|
||||
// delete past team membership data (not user visible)
|
||||
await trx
|
||||
.deleteFrom("AllTeamMember")
|
||||
.where("userId", "=", args.newUserId)
|
||||
.where("leftAt", "is not", null)
|
||||
.execute();
|
||||
// existing team membership will stay
|
||||
await trx
|
||||
.updateTable("AllTeamMember")
|
||||
.where("userId", "=", args.newUserId)
|
||||
.set({ userId: args.oldUserId })
|
||||
.execute();
|
||||
|
||||
const deletedUser = await trx
|
||||
.deleteFrom("User")
|
||||
@@ -65,9 +97,34 @@ export function migrate(args: { newUserId: number; oldUserId: number }) {
|
||||
.set({ discordId: deletedUser.discordId })
|
||||
.where("User.id", "=", args.oldUserId)
|
||||
.execute();
|
||||
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
async function validateMigration(
|
||||
trx: Transaction<DB>,
|
||||
args: { newUserId: number; oldUserId: number },
|
||||
) {
|
||||
const oldUserCurrentTeam = await trx
|
||||
.selectFrom("TeamMember")
|
||||
.select(["teamId"])
|
||||
.where("userId", "=", args.oldUserId)
|
||||
.executeTakeFirst();
|
||||
|
||||
const newUserCurrentTeam = await trx
|
||||
.selectFrom("TeamMember")
|
||||
.select(["teamId"])
|
||||
.where("userId", "=", args.newUserId)
|
||||
.executeTakeFirst();
|
||||
|
||||
if (oldUserCurrentTeam && newUserCurrentTeam) {
|
||||
return "both old and new user are in teams";
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function replacePlusTiers(
|
||||
plusTiers: Array<{ userId: number; plusTier: number }>,
|
||||
) {
|
||||
|
||||
Reference in New Issue
Block a user