[feat] script to updating pricing

This commit is contained in:
2026-02-15 15:25:08 -05:00
parent a774360065
commit 32df33f29e
7 changed files with 94 additions and 14 deletions

3
.gitignore vendored
View File

@@ -25,3 +25,6 @@ pnpm-debug.log*
# imges from tcgplayer # imges from tcgplayer
public/cards/* public/cards/*
# anything test
test.*

View File

@@ -6,8 +6,7 @@
"dev": "astro dev", "dev": "astro dev",
"build": "astro build", "build": "astro build",
"preview": "astro preview", "preview": "astro preview",
"astro": "astro", "astro": "astro"
"add-user": "ts-node scripts/add-user.ts"
}, },
"dependencies": { "dependencies": {
"astro": "^5.17.1", "astro": "^5.17.1",

View File

@@ -11,13 +11,9 @@ import chalk from 'chalk';
async function syncTcgplayer() { async function syncTcgplayer() {
// const productLines = [
// { name: "pokemon", energyType: ["Water", "Fire", "Grass", "Lightning", "Psychic", "Fighting", "Darkness", "Metal", "Fairy", "Dragon", "Colorless", "Energy"] },
// { name: "pokemon-japan", cardType: ["Water", "Fire", "Grass", "Lightning", "Psychic", "Fighting", "Darkness", "Metal", "Fairy", "Dragon", "Colorless", "Energy"] }
// ];
const productLines = [ const productLines = [
{ name: "pokemon-japan", cardType: ["Dragon", "Colorless", "Energy"] } { name: "pokemon", energyType: ["Water", "Fire", "Grass", "Lightning", "Psychic", "Fighting", "Darkness", "Metal", "Fairy", "Dragon", "Colorless", "Energy"] },
{ name: "pokemon-japan", cardType: ["Water", "Fire", "Grass", "Lightning", "Psychic", "Fighting", "Darkness", "Metal", "Fairy", "Dragon", "Colorless", "Energy"] }
]; ];
for (const productLine of productLines) { for (const productLine of productLines) {

79
scripts/sync-prices.ts Normal file
View File

@@ -0,0 +1,79 @@
import 'dotenv/config';
import chalk from 'chalk';
import { db, poolConnection } from '../src/db/index.ts';
import { sql, inArray, eq } from 'drizzle-orm';
import { skus, processingSkus } from '../src/db/schema.ts';
async function resetProcessingTable() {
// Use sql.raw to execute the TRUNCATE TABLE statement
await db.execute(sql.raw('TRUNCATE TABLE processingSkus;'));
await db.insert(processingSkus).select(db.select({skuId: skus.skuId}).from(skus));
}
async function syncPrices() {
const batchSize = 1000;
await resetProcessingTable();
console.log(chalk.green('Processing table reset and populated with current SKUs.'));
while (true) {
const batch = await db.select().from(processingSkus).limit(batchSize);
if (batch.length === 0) {
console.log('All SKUs processed.');
break;
}
const skuIds = batch.map(item => item.skuId);
console.log(`${chalk.blue('Processing SKUs:')} ${chalk.gray(skuIds.join(', '))}`);
const skuResponse = await fetch('https://mpgateway.tcgplayer.com/v1/pricepoints/marketprice/skus/search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ skuIds: skuIds }),
});
if (!skuResponse.ok) {
console.error('Error fetching SKU pricing:', skuResponse.statusText);
process.exit(1);
}
const skuData = await skuResponse.json();
if (skuData.length !== batchSize) {
console.error(chalk.yellow(`Expected ${batchSize} SKUs, got ${skuData.length}`));
//process.exit(1);
}
for (const sku of skuData) {
await db.update(skus)
.set({
marketPrice: sku.marketPrice,
lowestPrice: sku.lowPrice,
highestPrice: sku.highPrice,
priceCount: sku.priceCount,
calculatedAt: sku.calculatedAt ? new Date(sku.calculatedAt) : null,
})
.where(eq(skus.skuId, sku.skuId));
}
await db.delete(processingSkus).where(inArray(processingSkus.skuId, skuIds));
}
// No need to call db.end(); Drizzle ORM manages connections.
}
const start = Date.now();
await syncPrices();
await poolConnection.end();
const end = Date.now();
const duration = (end - start) / 1000;
console.log(chalk.green(`Price sync completed in ${duration.toFixed(2)} seconds.`));
export {};

View File

@@ -1,11 +1,10 @@
// src/db/index.ts // src/db/index.ts
import 'dotenv/config'; import 'dotenv/config';
import { relations } from './relations'; import { relations } from './relations.ts';
import { drizzle } from 'drizzle-orm/mysql2'; import { drizzle } from 'drizzle-orm/mysql2';
//import mysql from 'mysql2/promise'; import mysql from 'mysql2/promise';
//import * as schema from './schema';
//const poolConnection = mysql.createPool(process.env.DATABASE_URL!); export const poolConnection = mysql.createPool(process.env.DATABASE_URL!);
export const db = drizzle(process.env.DATABASE_URL!, { relations }); export const db = drizzle({ client: poolConnection, relations: relations});

View File

@@ -1,5 +1,5 @@
import { defineRelations } from "drizzle-orm"; import { defineRelations } from "drizzle-orm";
import * as schema from "./schema"; import * as schema from "./schema.ts";
export const relations = defineRelations(schema, (r) => ({ export const relations = defineRelations(schema, (r) => ({
skus: { skus: {

View File

@@ -61,3 +61,7 @@ export const skus = mysqlTable("skus", {
(table) => [ (table) => [
index("productIdIdx").on(table.productId), index("productIdIdx").on(table.productId),
]); ]);
export const processingSkus = mysqlTable("processingSkus", {
skuId: int().primaryKey(),
});