From cb829e1922907aa49fe3f74eb0cedf09b1117941 Mon Sep 17 00:00:00 2001 From: Thad Miller Date: Tue, 7 Apr 2026 09:52:17 -0400 Subject: [PATCH] [chore] move inventory relationship to sku --- scripts/pokemon-helper.ts | 10 ++++++---- src/db/relations.ts | 11 +++-------- src/db/schema.ts | 5 ++--- src/pages/api/inventory.ts | 39 ++++++++++++++++++++++---------------- 4 files changed, 34 insertions(+), 31 deletions(-) diff --git a/scripts/pokemon-helper.ts b/scripts/pokemon-helper.ts index 9a9a9c9..1ba7db0 100644 --- a/scripts/pokemon-helper.ts +++ b/scripts/pokemon-helper.ts @@ -62,7 +62,7 @@ export const createCardCollection = async () => { { name: 'releaseDate', type: 'int32' }, { name: 'marketPrice', type: 'int32', optional: true, sort: true }, { name: 'content', type: 'string', token_separators: ['/'] }, - { name: 'sku_id', type: 'string[]', optional: true, reference: 'skus.id', async_reference: true } + // { name: 'sku_id', type: 'string[]', optional: true, reference: 'skus.id', async_reference: true } ], }); console.log(chalk.green('Collection "cards" created successfully.')); @@ -83,6 +83,7 @@ export const createSkuCollection = async () => { { name: 'highestPrice', type: 'int32', optional: true }, { name: 'lowestPrice', type: 'int32', optional: true }, { name: 'marketPrice', type: 'int32', optional: true }, + { name: 'card_id', type: 'string', reference: 'cards.id' }, ] }); console.log(chalk.green('Collection "skus" created successfully.')); @@ -101,7 +102,7 @@ export const createInventoryCollection = async () => { { name: 'id', type: 'string' }, { name: 'userId', type: 'string' }, { name: 'catalogName', type: 'string' }, - { name: 'card_id', type: 'string', reference: 'cards.id' }, + { name: 'sku_id', type: 'string', reference: 'skus.id' }, ] }); console.log(chalk.green('Collection "inventories" created successfully.')); @@ -132,7 +133,7 @@ export const upsertCardCollection = async (db:DBInstance) => { content: [card.productName, card.productLineName, card.set?.setName || "", card.number, card.rarityName, card.artist || ""].join(' '), releaseDate: card.tcgdata?.releaseDate ? Math.floor(new Date(card.tcgdata.releaseDate).getTime() / 1000) : 0, ...(marketPrice !== null && { marketPrice }), - sku_id: card.prices.map(price => price.skuId.toString()) + // sku_id: card.prices.map(price => price.skuId.toString()) }; }), { action: 'upsert' }); console.log(chalk.green('Collection "cards" indexed successfully.')); @@ -146,6 +147,7 @@ export const upsertSkuCollection = async (db:DBInstance) => { highestPrice: DollarToInt(sku.highestPrice), lowestPrice: DollarToInt(sku.lowestPrice), marketPrice: DollarToInt(sku.marketPrice), + card_id: sku.cardId.toString(), })), { action: 'upsert' }); console.log(chalk.green('Collection "skus" indexed successfully.')); } @@ -156,7 +158,7 @@ export const upsertInventoryCollection = async (db:DBInstance) => { id: i.inventoryId, userId: i.userId, catalogName: i.catalogName, - card_id: i.cardId.toString(), + sku_id: i.skuId.toString(), })), { action: 'upsert' }); console.log(chalk.green('Collection "inventories" indexed successfully.')); } diff --git a/src/db/relations.ts b/src/db/relations.ts index 0ecc14d..73157bd 100644 --- a/src/db/relations.ts +++ b/src/db/relations.ts @@ -24,18 +24,13 @@ export const relations = defineRelations(schema, (r) => ({ inventories: r.many.inventory(), }, inventory: { - card: r.one.cards({ - from: r.inventory.cardId, - to: r.cards.cardId, - }), - sku: r.one.skus({ - from: [r.inventory.cardId, r.inventory.condition], - to: [r.skus.cardId, r.skus.condition], + card: r.one.skus({ + from: r.inventory.skuId, + to: r.skus.skuId, }), }, cards: { prices: r.many.skus(), - inventories: r.many.inventory(), set: r.one.sets({ from: r.cards.setId, to: r.sets.setId, diff --git a/src/db/schema.ts b/src/db/schema.ts index c19a5fd..c634396 100644 --- a/src/db/schema.ts +++ b/src/db/schema.ts @@ -129,15 +129,14 @@ export const inventory = pokeSchema.table('inventory',{ inventoryId: uuid().primaryKey().notNull().defaultRandom(), userId: varchar({ length: 100 }).notNull(), catalogName: varchar({ length: 100 }), - cardId: integer().notNull(), - condition: varchar({ length: 255 }).notNull(), + skuId: integer().notNull(), quantity: integer(), purchasePrice: decimal({ precision: 10, scale: 2 }), note: varchar({ length:255 }), createdAt: timestamp().notNull().defaultNow(), }, (table) => [ - index('idx_userid_cardid').on(table.userId, table.cardId) + index('idx_userid_skuId').on(table.userId, table.skuId) ]); export const processingSkus = pokeSchema.table('processing_skus', { diff --git a/src/pages/api/inventory.ts b/src/pages/api/inventory.ts index 3ccd6cc..bc313be 100644 --- a/src/pages/api/inventory.ts +++ b/src/pages/api/inventory.ts @@ -1,6 +1,6 @@ import type { APIRoute } from 'astro'; import { db } from '../../db/index'; -import { inventory } from '../../db/schema'; +import { inventory, priceHistory } from '../../db/schema'; import { client } from '../../db/typesense'; import { eq } from 'drizzle-orm'; @@ -15,27 +15,29 @@ const GainLoss = (purchasePrice: any, marketPrice: any) => { const getInventory = async (userId: string, cardId: number) => { - const inventories = await db.query.inventory.findMany({ - where: { userId:userId, cardId:cardId, }, - with: { card: true, sku: true, } + const card = await db.query.cards.findFirst({ + where: { cardId: cardId, }, + with : { prices: { + with: { inventories: { where: { userId: userId } }, } + }, }, }); - const invHtml = inventories.map(inv => { - const marketPrice = inv.sku?.marketPrice; + const invHtml = card?.prices?.flatMap(price => price.inventories.map(inv => { + const marketPrice = price.marketPrice; const marketPriceDisplay = marketPrice ? `$${marketPrice}` : '—'; const purchasePriceDisplay = inv.purchasePrice ? `$${Number(inv.purchasePrice).toFixed(2)}` : '—'; return `
-
${inv.condition}
+
${price.condition}
Added: ${inv.createdAt ? new Date(inv.createdAt).toLocaleDateString() : '—'}
@@ -71,7 +73,7 @@ const getInventory = async (userId: string, cardId: number) => {
`; - }); + })) || []; return new Response( invHtml.join(''), @@ -83,13 +85,12 @@ const getInventory = async (userId: string, cardId: number) => { } -const addToInventory = async (userId: string, cardId: number, condition: string, variant: string, purchasePrice: number, quantity: number, note: string, catalogName: string) => { +const addToInventory = async (userId: string, skuId: number, purchasePrice: number, quantity: number, note: string, catalogName: string) => { // First add to database const inv = await db.insert(inventory).values({ userId: userId, - cardId: cardId, + skuId: skuId, catalogName: catalogName, - condition: condition, purchasePrice: purchasePrice.toFixed(2), quantity: quantity, note: note, @@ -99,7 +100,7 @@ const addToInventory = async (userId: string, cardId: number, condition: string, id: i.inventoryId, userId: i.userId, catalogName: i.catalogName, - card_id: i.cardId.toString(), + sku_id: i.skuId.toString(), }))); } @@ -128,13 +129,19 @@ export const POST: APIRoute = async ({ request, locals }) => { switch (action) { case 'add': - const condition = formData.get('condition')?.toString() || 'Unknown'; - const variant = formData.get('variant')?.toString() || 'Normal'; const purchasePrice = Number(formData.get('purchasePrice')) || 0; const quantity = Number(formData.get('quantity')) || 1; const note = formData.get('note')?.toString() || ''; const catalogName = formData.get('catalogName')?.toString() || 'Default'; - await addToInventory(userId!, cardId, condition, variant, purchasePrice, quantity, note, catalogName); + const condition = formData.get('condition')?.toString() || 'Near Mint'; + const skuId = await db.query.skus.findFirst({ + where: { cardId: cardId, condition: condition }, + columns: { skuId: true }, + }).then(sku => sku?.skuId); + if (!skuId) { + return new Response('SKU not found for card', { status: 404 }); + } + await addToInventory(userId!, skuId, purchasePrice, quantity, note, catalogName); break; case 'remove':