[chore] refactor common functions into helper script

This commit is contained in:
2026-03-19 22:18:06 -04:00
parent 023cd87319
commit 171ce294f4
6 changed files with 160 additions and 94 deletions

View File

@@ -3,15 +3,11 @@ import 'dotenv/config';
import chalk from 'chalk';
import { db, ClosePool } from '../src/db/index.ts';
import { sql, inArray, eq } from 'drizzle-orm';
import { skus, processingSkus, priceHistory } from '../src/db/schema.ts';
import { skus, processingSkus, priceHistory, salesHistory } from '../src/db/schema.ts';
import { toSnakeCase } from 'drizzle-orm/casing';
import * as Indexing from './indexing.ts';
import * as helper from './pokemon-helper.ts';
function sleep(ms: number) {
return new Promise(resolve => setTimeout(resolve, ms));
}
async function resetProcessingTable() {
// Use sql.raw to execute the TRUNCATE TABLE statement
await db.execute(sql.raw('TRUNCATE TABLE pokemon.processing_skus;'));
@@ -21,6 +17,7 @@ async function resetProcessingTable() {
async function syncPrices() {
const batchSize = 1000;
// const skuIndex = client.collections('skus');
const updatedCards = new Set<number>();
await resetProcessingTable();
console.log(chalk.green('Processing table reset and populated with current SKUs.'));
@@ -60,7 +57,7 @@ async function syncPrices() {
// remove skus from the 'working' processingSkus table
await db.delete(processingSkus).where(inArray(processingSkus.skuId, skuIds));
// be nice to the API and not send too many requests in a short time
await sleep(200);
await helper.Sleep(200);
continue;
}
@@ -103,21 +100,63 @@ async function syncPrices() {
});
console.log(chalk.cyan(`${skuRows.length} history rows added.`));
}
for (const productId of skuRows.filter(row => row.calculatedAt != null).map(row => row.productId)) {
updatedCards.add(productId);
}
}
// remove skus from the 'working' processingSkus table
await db.delete(processingSkus).where(inArray(processingSkus.skuId, skuIds));
// be nice to the API and not send too many requests in a short time
await sleep(200);
await helper.Sleep(200);
}
return updatedCards;
}
const updateLatestSales = async (updatedCards: Set<number>) => {
for (const productId of updatedCards.values()) {
console.log(`Getting sale history for ${productId}`)
const salesResponse = await fetch(`https://mpapi.tcgplayer.com/v2/product/${productId}/latestsales`,{
method: 'POST',
headers: {
'Content-Type': 'application/json',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36'
},
body: JSON.stringify({ conditions:[], languages:[1], limit:25, listType:"All", variants:[] }),
});
if (!salesResponse.ok) {
console.error('Error fetching sale history:', salesResponse.statusText);
process.exit(1);
}
const salesData = await salesResponse.json();
for (const sale of salesData.data) {
const skuData = await db.query.skus.findFirst({ where: { productId: productId, variant: sale.variant, condition: sale.condition } });
if (skuData) {
await db.insert(salesHistory).values({
skuId: skuData.skuId,
orderDate: new Date(sale.orderDate),
title: sale.title,
customListingId: sale.customListingId,
language: sale.language,
listingType: sale.listingType,
purchasePrice: sale.purchasePrice,
quantity: sale.quantity,
shippingPrice: sale.shippingPrice
}).onConflictDoNothing();
}
}
await helper.Sleep(500);
}
}
const start = Date.now();
await syncPrices();
await Indexing.upsertSkuCollection(db);
const updatedCards = await syncPrices();
await helper.upsertSkuCollection(db);
//console.log(updatedCards);
//console.log(updatedCards.size);
//await updateLatestSales(updatedCards);
await ClosePool();
const end = Date.now();
const duration = (end - start) / 1000;