112 lines
2.3 KiB
TypeScript
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,
|
|
};
|
|
}
|