feat(api): tokens on all routes; items expose claims/claimedQuantity/remainingQuantity
This commit is contained in:
55
lib/items-with-claims.ts
Normal file
55
lib/items-with-claims.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import { eq, inArray } from 'drizzle-orm';
|
||||
import { db, wishlistItems, itemClaims, guests } from '@/lib/db';
|
||||
|
||||
type RawItem = typeof wishlistItems.$inferSelect;
|
||||
|
||||
export async function attachClaimsToItems(items: RawItem[]) {
|
||||
if (items.length === 0) return [];
|
||||
const itemIds = items.map((i) => i.id);
|
||||
const rows = await db
|
||||
.select({
|
||||
id: itemClaims.id,
|
||||
itemId: itemClaims.itemId,
|
||||
quantity: itemClaims.quantity,
|
||||
note: itemClaims.note,
|
||||
isPurchased: itemClaims.isPurchased,
|
||||
claimedAt: itemClaims.claimedAt,
|
||||
guestId: guests.id,
|
||||
guestName: guests.name,
|
||||
})
|
||||
.from(itemClaims)
|
||||
.innerJoin(guests, eq(itemClaims.guestId, guests.id))
|
||||
.where(inArray(itemClaims.itemId, itemIds));
|
||||
|
||||
const byItem = new Map<string, ReturnType<typeof shapeClaim>[]>();
|
||||
for (const r of rows) {
|
||||
const arr = byItem.get(r.itemId) ?? [];
|
||||
arr.push(shapeClaim(r));
|
||||
byItem.set(r.itemId, arr);
|
||||
}
|
||||
|
||||
return items.map((it) => {
|
||||
const claims = byItem.get(it.id) ?? [];
|
||||
const claimedQuantity = claims.reduce((s, c) => s + c.quantity, 0);
|
||||
return {
|
||||
...it,
|
||||
claims,
|
||||
claimedQuantity,
|
||||
remainingQuantity: Math.max(0, it.quantity - claimedQuantity),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function shapeClaim(r: {
|
||||
id: string; quantity: number; note: string | null; isPurchased: boolean;
|
||||
claimedAt: Date; guestId: string; guestName: string;
|
||||
}) {
|
||||
return {
|
||||
id: r.id,
|
||||
quantity: r.quantity,
|
||||
note: r.note,
|
||||
isPurchased: r.isPurchased,
|
||||
claimedAt: r.claimedAt,
|
||||
guest: { id: r.guestId, name: r.guestName },
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user