itpdp/api/src/party-data.ts
2026-04-29 22:36:48 +02:00

112 lines
2.3 KiB
TypeScript

import { eq } from "drizzle-orm";
import { db } from "./db";
import { party, partyMember } from "./db/schema";
import type { PartySnapshot } from "./party-types";
type DbClient = typeof db;
type DbTransaction = Parameters<typeof db.transaction>[0] extends (
tx: infer T,
) => Promise<unknown>
? T
: never;
export type DbLike = DbClient | DbTransaction;
export async function getPartyForUser(userId: string) {
const memberships = await db.query.partyMember.findMany({
where: {
userId,
},
with: {
party: true,
},
limit: 1,
});
return memberships[0]?.party ?? null;
}
export async function getMemberRecord(dbClient: DbLike, userId: string) {
return (
(await dbClient.query.partyMember.findFirst({
where: {
userId,
},
orderBy: {
joinedAt: "desc",
},
})) ?? null
);
}
export async function getPartyStatus(
partyId: string,
): Promise<PartySnapshot | null> {
const partyRecord = await db.query.party.findFirst({
where: {
id: partyId,
},
});
if (!partyRecord) return null;
const members = await db.query.partyMember.findMany({
where: {
partyId,
},
with: {
user: true,
},
orderBy: {
joinedAt: "asc",
},
});
return {
party: partyRecord,
members,
};
}
export async function cleanupPartyIfEmpty(dbClient: DbLike, partyId: string) {
const members = await dbClient.query.partyMember.findMany({
where: {
partyId,
},
limit: 1,
});
if (members.length > 0) return;
await dbClient.delete(party).where(eq(party.id, partyId));
}
export async function leaveParty(dbClient: DbLike, userId: string) {
const member = await getMemberRecord(dbClient, userId);
if (!member) return null;
await dbClient.delete(partyMember).where(eq(partyMember.id, member.id));
const nextHost = await dbClient.query.partyMember.findFirst({
where: {
partyId: member.partyId,
},
orderBy: {
joinedAt: "asc",
},
});
let newHostId: string | null = null;
if (nextHost) {
const currentParty = await dbClient.query.party.findFirst({
where: {
id: member.partyId,
},
});
if (currentParty?.hostId === userId) {
await dbClient
.update(party)
.set({
hostId: nextHost.userId,
lastUpdated: new Date(),
})
.where(eq(party.id, member.partyId));
newHostId = nextHost.userId;
}
}
await cleanupPartyIfEmpty(dbClient, member.partyId);
return {
partyId: member.partyId,
newHostId,
};
}