[chore] move inventory relationship to sku
This commit is contained in:
@@ -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.'));
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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', {
|
||||
|
||||
@@ -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 `
|
||||
<article class="border rounded-4 p-2 inventory-entry-card"
|
||||
data-inventory-id="${inv.inventoryId}"
|
||||
data-card-id="${inv.cardId}"
|
||||
data-card-id="${price.cardId}"
|
||||
data-purchase-price="${inv.purchasePrice}"
|
||||
data-note="${(inv.note || '').replace(/"/g, '"')}">
|
||||
<div class="d-flex flex-column">
|
||||
<!-- Top row -->
|
||||
<div class="d-flex justify-content-between gap-3">
|
||||
<div class="min-w-0 flex-grow-1">
|
||||
<div class="fw-semibold fs-6 text-body mb-1">${inv.condition}</div>
|
||||
<div class="fw-semibold fs-6 text-body mb-1">${price.condition}</div>
|
||||
</div>
|
||||
<div class="fs-7 text-secondary">Added: ${inv.createdAt ? new Date(inv.createdAt).toLocaleDateString() : '—'}</div>
|
||||
</div>
|
||||
@@ -71,7 +73,7 @@ const getInventory = async (userId: string, cardId: number) => {
|
||||
</div>
|
||||
</div>
|
||||
</article>`;
|
||||
});
|
||||
})) || [];
|
||||
|
||||
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':
|
||||
|
||||
Reference in New Issue
Block a user