diff --git a/backend/src/db/migrations/20251018061215_sub-org.ts b/backend/src/db/migrations/20251018061215_sub-org.ts index 3254a4aca..089aeef90 100644 --- a/backend/src/db/migrations/20251018061215_sub-org.ts +++ b/backend/src/db/migrations/20251018061215_sub-org.ts @@ -1,9 +1,8 @@ import { Knex } from "knex"; import { dropConstraintIfExists } from "@app/db/migrations/utils/dropConstraintIfExists"; -import { chunkArray } from "@app/lib/fn"; -import { AccessScope, TableName } from "../schemas"; +import { TableName } from "../schemas"; export async function up(knex: Knex): Promise { const hasParentOrgId = await knex.schema.hasColumn(TableName.Organization, "parentOrgId"); @@ -19,8 +18,6 @@ export async function up(knex: Knex): Promise { await dropConstraintIfExists(TableName.Organization, "organizations_slug_unique", knex); t.unique(["rootOrgId", "parentOrgId", "slug"]); }); - - // had to switch to raw for null not distinct } const hasIdentityOrgCol = await knex.schema.hasColumn(TableName.Identity, "orgId"); @@ -29,43 +26,6 @@ export async function up(knex: Knex): Promise { t.uuid("orgId"); t.foreign("orgId").references("id").inTable(TableName.Organization).onDelete("CASCADE"); }); - - const identityMemberships = await knex(TableName.Membership) - .where({ - scope: AccessScope.Organization - }) - .whereNotNull("actorIdentityId") - .select("actorIdentityId", "scopeOrgId"); - - const identityToOrgMapping: Record = {}; - identityMemberships.forEach((el) => { - if (el.actorIdentityId) { - identityToOrgMapping[el.actorIdentityId] = el.scopeOrgId; - } - }); - - const batchMemberships = chunkArray(identityMemberships, 500); - for await (const membership of batchMemberships) { - const identityIds = membership.map((el) => el.actorIdentityId).filter(Boolean) as string[]; - if (identityIds.length) { - const identities = await knex(TableName.Identity).whereIn("id", identityIds).select("*"); - await knex(TableName.Identity) - .insert( - identities.map((el) => ({ - ...el, - orgId: identityToOrgMapping[el.id] - })) - ) - .onConflict("id") - .merge(); - } - } - - await knex(TableName.Identity).whereNull("orgId").delete(); - - await knex.schema.alterTable(TableName.Identity, (t) => { - t.uuid("orgId").notNullable().alter(); - }); } } diff --git a/backend/src/db/migrations/20251024150349_sub-org-identity-backfill.ts b/backend/src/db/migrations/20251024150349_sub-org-identity-backfill.ts new file mode 100644 index 000000000..12aa38edc --- /dev/null +++ b/backend/src/db/migrations/20251024150349_sub-org-identity-backfill.ts @@ -0,0 +1,51 @@ +import { Knex } from "knex"; + +import { chunkArray } from "@app/lib/fn"; + +import { AccessScope, TableName } from "../schemas"; + +export async function up(knex: Knex): Promise { + const hasIdentityOrgCol = await knex.schema.hasColumn(TableName.Identity, "orgId"); + if (hasIdentityOrgCol) { + const identityMemberships = await knex(TableName.Membership) + .where({ + scope: AccessScope.Organization + }) + .whereNotNull("actorIdentityId") + .select("actorIdentityId", "scopeOrgId"); + + const identityToOrgMapping: Record = {}; + identityMemberships.forEach((el) => { + if (el.actorIdentityId) { + identityToOrgMapping[el.actorIdentityId] = el.scopeOrgId; + } + }); + + const batchMemberships = chunkArray(identityMemberships, 500); + for await (const membership of batchMemberships) { + const identityIds = membership.map((el) => el.actorIdentityId).filter(Boolean) as string[]; + if (identityIds.length) { + const identities = await knex(TableName.Identity).whereIn("id", identityIds).select("*"); + await knex(TableName.Identity) + .insert( + identities.map((el) => ({ + ...el, + orgId: identityToOrgMapping[el.id] + })) + ) + .onConflict("id") + .merge(); + } + } + + await knex(TableName.Identity).whereNull("orgId").delete(); + await knex.schema.alterTable(TableName.Identity, (t) => { + t.uuid("orgId").notNullable().alter(); + }); + } +} + +export async function down(): Promise {} + +const config = { transaction: false }; +export { config };