deckhearth/lib/card-import/sync-catalog.js
Randall Stillwell adfaa4e5db Prioritize newest missing sets in catalog sync queue.
The cron was importing oldest MTG sets first and never reaching recent Pokémon releases like Perfect Order; merge MTG and Pokémon by release date descending instead.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-05-27 21:48:22 -05:00

97 lines
2.7 KiB
JavaScript

import { discoverMissingMtgSets, discoverMissingPokemonSets } from './discover.js';
import { importMtgSet } from './mtg.js';
import { importPokemonSet } from './pokemon.js';
const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const DEFAULT_MAX_SETS_PER_RUN = 3;
const DEFAULT_DELAY_MS = 1500;
/**
* Merge missing MTG + Pokémon sets and pick the newest releases first.
*/
export function buildCatalogSyncQueue(missingMtg, missingPokemon, maxSetsPerRun = DEFAULT_MAX_SETS_PER_RUN) {
const queue = [
...missingMtg.map((set) => ({
game: 'mtg',
setCode: set.code,
name: set.name,
releasedAt: set.releasedAt,
})),
...missingPokemon.map((set) => ({
game: 'pokemon',
setCode: set.id,
name: set.name,
releasedAt: set.releasedAt,
})),
];
queue.sort((a, b) => {
const dateA = a.releasedAt || '';
const dateB = b.releasedAt || '';
if (!dateA && !dateB) return 0;
if (!dateA) return 1;
if (!dateB) return -1;
return dateB.localeCompare(dateA);
});
return queue.slice(0, maxSetsPerRun);
}
/**
* Discover missing MTG + Pokémon sets and import up to maxSetsPerRun, paced for upstream APIs.
*/
export async function runCatalogSync(options = {}) {
const maxSetsPerRun = options.maxSetsPerRun ?? DEFAULT_MAX_SETS_PER_RUN;
const delayBetweenSetsMs = options.delayBetweenSetsMs ?? DEFAULT_DELAY_MS;
const [missingMtg, missingPokemon] = await Promise.all([
discoverMissingMtgSets(),
discoverMissingPokemonSets(),
]);
const queue = buildCatalogSyncQueue(missingMtg, missingPokemon, maxSetsPerRun);
const summary = {
imported: 0,
skipped: 0,
errors: [],
setsProcessed: [],
pendingMtgSets: missingMtg.length,
pendingPokemonSets: missingPokemon.length,
lorcana: 'skipped — manual Lorcana set map update required',
};
for (let index = 0; index < queue.length; index += 1) {
const item = queue[index];
try {
const result =
item.game === 'mtg'
? await importMtgSet(item.setCode)
: await importPokemonSet(item.setCode);
summary.setsProcessed.push({
game: item.game,
setCode: item.setCode,
name: item.name,
...result,
});
summary.imported += result.imported;
summary.skipped += result.skipped;
} catch (error) {
console.error(`[runCatalogSync] Failed ${item.game}/${item.setCode}:`, error);
summary.errors.push({
game: item.game,
setCode: item.setCode,
message: error.message,
});
}
if (index < queue.length - 1) {
await delay(delayBetweenSetsMs);
}
}
console.log('[runCatalogSync]', JSON.stringify(summary));
return summary;
}