diff --git a/components/card-detail/CardDetailPurchaseTab.js b/components/card-detail/CardDetailPurchaseTab.js
index 7009c82..056a972 100644
--- a/components/card-detail/CardDetailPurchaseTab.js
+++ b/components/card-detail/CardDetailPurchaseTab.js
@@ -119,12 +119,14 @@ export default function CardDetailPurchaseTab({
)}
-
+
+
+
);
}
diff --git a/package.json b/package.json
index 60792b8..6ac1707 100644
--- a/package.json
+++ b/package.json
@@ -19,6 +19,7 @@
"backfill-embeddings": "node --env-file=.env.local scripts/backfill-card-embeddings.js",
"migrate-neon-to-homelab": "node --env-file=.env.local scripts/migrate-neon-to-homelab.js",
"fix-pricing-pgmigration-order": "node --env-file=.env.local scripts/fix-pricing-pgmigration-order.js",
+ "sync-catalog-unified": "node --env-file=.env.local scripts/run-unified-catalog-sync.js",
"import-tags": "node --env-file=.env.local scripts/import-scryfall-tags.js",
"test": "vitest",
"test:run": "vitest run",
diff --git a/scripts/run-unified-catalog-sync.js b/scripts/run-unified-catalog-sync.js
new file mode 100644
index 0000000..f729410
--- /dev/null
+++ b/scripts/run-unified-catalog-sync.js
@@ -0,0 +1,32 @@
+#!/usr/bin/env node
+/**
+ * Run MTG + Pokémon + Lorcana bulk syncs (with pricing ingest) against POSTGRES_URL.
+ *
+ * Usage:
+ * node --env-file=.env.local scripts/run-unified-catalog-sync.js
+ */
+
+import { runUnifiedCatalogSync } from '../lib/card-import/sync-catalog.js';
+import { closeSqlPool } from '../lib/sql.js';
+
+async function main() {
+ const summary = await runUnifiedCatalogSync();
+ console.log(JSON.stringify(summary, null, 2));
+
+ if (summary.errors?.length) {
+ process.exitCode = 1;
+ }
+}
+
+main()
+ .catch((err) => {
+ console.error(err);
+ process.exitCode = 1;
+ })
+ .finally(async () => {
+ try {
+ await closeSqlPool();
+ } catch {
+ // ignore
+ }
+ });
diff --git a/test/lib/card-import/lorcana-bulk.test.js b/test/lib/card-import/lorcana-bulk.test.js
index cfab24f..0a90e22 100644
--- a/test/lib/card-import/lorcana-bulk.test.js
+++ b/test/lib/card-import/lorcana-bulk.test.js
@@ -66,7 +66,7 @@ describe('enrichLorcanaRowWithFolio', () => {
stats
);
- expect(enriched.currentPrice).toBeNull();
+ expect(enriched.currentPrice ?? null).toBeNull();
expect(stats.unmatchedCount).toBe(1);
});
});
diff --git a/test/lib/pricing/foolio-client.test.js b/test/lib/pricing/foolio-client.test.js
index 0e5c812..4dbcefc 100644
--- a/test/lib/pricing/foolio-client.test.js
+++ b/test/lib/pricing/foolio-client.test.js
@@ -14,7 +14,7 @@ describe('foolio-client', () => {
});
it('uses default Foilio feed URL', () => {
- expect(getFolioFeedUrl()).toBe('https://foolio.net/api/prices/feed?game=lorcana');
+ expect(getFolioFeedUrl()).toBe('https://foilio.net/api/prices/feed?game=lorcana');
});
it('prefers USD fields when parsing feed rows', () => {