54 lines
1.7 KiB
TypeScript
54 lines
1.7 KiB
TypeScript
import { eq, inArray } from 'drizzle-orm'
|
|
import { useDb } from '../database/client'
|
|
import { expenseParticipants, expenses, participants, pots } from '../database/schema'
|
|
|
|
export interface ExpenseWithDetails {
|
|
id: number
|
|
type: string
|
|
description: string
|
|
amountCents: number
|
|
payerId: number
|
|
participantIds: number[]
|
|
createdAt: number
|
|
}
|
|
|
|
export async function getPotOrThrow(slug: string) {
|
|
const db = useDb()
|
|
const [pot] = await db.select().from(pots).where(eq(pots.slug, slug))
|
|
if (!pot) {
|
|
throw createError({ statusCode: 404, statusMessage: 'Pot not found' })
|
|
}
|
|
return pot
|
|
}
|
|
|
|
export async function getParticipants(slug: string) {
|
|
const db = useDb()
|
|
return db.select().from(participants).where(eq(participants.potSlug, slug))
|
|
}
|
|
|
|
export async function getExpensesWithParticipants(slug: string): Promise<ExpenseWithDetails[]> {
|
|
const db = useDb()
|
|
const expenseRows = await db.select().from(expenses).where(eq(expenses.potSlug, slug)).orderBy(expenses.createdAt)
|
|
if (expenseRows.length === 0) return []
|
|
|
|
const expenseIds = expenseRows.map(row => row.id)
|
|
const links = await db.select().from(expenseParticipants).where(inArray(expenseParticipants.expenseId, expenseIds))
|
|
|
|
const participantIdsByExpense = new Map<number, number[]>()
|
|
for (const link of links) {
|
|
const list = participantIdsByExpense.get(link.expenseId) ?? []
|
|
list.push(link.participantId)
|
|
participantIdsByExpense.set(link.expenseId, list)
|
|
}
|
|
|
|
return expenseRows.map(row => ({
|
|
id: row.id,
|
|
type: row.type,
|
|
description: row.description,
|
|
amountCents: row.amountCents,
|
|
payerId: row.payerId,
|
|
participantIds: participantIdsByExpense.get(row.id) ?? [],
|
|
createdAt: row.createdAt,
|
|
}))
|
|
}
|