Only destroy team sandboxes and homes for spaces the deleting user owns with no remaining members or bots. Guard home removal under dataDir/homes. Add unit and postgres journey coverage. Co-authored-by: cynarAI <cynarAI@users.noreply.github.com>
33 lines
1.1 KiB
TypeScript
33 lines
1.1 KiB
TypeScript
import type { PrismaClient } from "./client.js";
|
|
|
|
type AccountDeleteDb = Pick<PrismaClient, "spaceMember" | "bot">;
|
|
|
|
/** Spaces whose team sandboxes and homes may be torn down when this user deletes their account. */
|
|
export async function spaceIdsForSandboxTeardownAfterAccountDelete(
|
|
prisma: AccountDeleteDb,
|
|
input: { userId: string; spaceIds: Iterable<string> },
|
|
): Promise<string[]> {
|
|
const uniqueSpaceIds = [...new Set(input.spaceIds)];
|
|
if (!uniqueSpaceIds.length) return [];
|
|
|
|
const eligible: string[] = [];
|
|
for (const spaceId of uniqueSpaceIds) {
|
|
const membership = await prisma.spaceMember.findUnique({
|
|
where: { spaceId_userId: { spaceId, userId: input.userId } },
|
|
select: { role: true },
|
|
});
|
|
if (membership?.role !== "owner") continue;
|
|
|
|
const [otherMembers, otherBots] = await Promise.all([
|
|
prisma.spaceMember.count({
|
|
where: { spaceId, userId: { not: input.userId } },
|
|
}),
|
|
prisma.bot.count({
|
|
where: { spaceId, userId: { not: input.userId } },
|
|
}),
|
|
]);
|
|
if (otherMembers === 0 && otherBots === 0) eligible.push(spaceId);
|
|
}
|
|
return eligible;
|
|
}
|