Ship Pokemon and Lorcana bulk import libs/scripts, unified weekly cron sync across MTG/Pokemon/Lorcana with per-game error isolation and catalog_sync_log telemetry. Admin UI adds Unified/Incremental/Bulk MTG modes. - Rename reconcile migrations to 1781442330* timestamps so they apply after bulk-data migrations without node-pg-migrate ordering conflicts - Add Lorcana set-code normalization + orphan cleanup migrations - Drop stricter user_cards_user_card_unique (keep 3-column foil unique) - Update docs/SCHEMA_MAP.md for tags, card_tags, catalog_sync_log, bulk columns Co-authored-by: Cursor <cursoragent@cursor.com>
49 lines
1.8 KiB
JavaScript
49 lines
1.8 KiB
JavaScript
/**
|
|
* Remove legacy Lorcana catalog rows that predate bulk import normalization.
|
|
* Remaps collection_cards to canonical TFC printings where possible.
|
|
*/
|
|
export const shorthands = undefined;
|
|
|
|
export const up = (pgm) => {
|
|
// Remap collection_cards from orphan Elsa/Mickey rows to canonical TFC printings.
|
|
pgm.sql(`
|
|
UPDATE collection_cards cc
|
|
SET card_id = canonical.id
|
|
FROM cards orphan
|
|
JOIN cards canonical ON canonical.game = 'Lorcana'
|
|
AND canonical.name = orphan.name
|
|
AND canonical.set_code = orphan.set_code
|
|
AND canonical.scryfall_id ~ '^[A-Za-z]{2,4}-[0-9]{3}$'
|
|
WHERE cc.card_id = orphan.id
|
|
AND orphan.game = 'Lorcana'
|
|
AND (orphan.scryfall_id IS NULL OR orphan.scryfall_id !~ '^[A-Za-z]{2,4}-[0-9]{3}$')
|
|
AND NOT EXISTS (
|
|
SELECT 1 FROM collection_cards existing
|
|
WHERE existing.collection_id = cc.collection_id
|
|
AND existing.card_id = canonical.id
|
|
);
|
|
`);
|
|
|
|
// Drop collection refs that would duplicate after remap.
|
|
pgm.sql(`
|
|
DELETE FROM collection_cards cc
|
|
USING cards orphan
|
|
WHERE cc.card_id = orphan.id
|
|
AND orphan.game = 'Lorcana'
|
|
AND (orphan.scryfall_id IS NULL OR orphan.scryfall_id !~ '^[A-Za-z]{2,4}-[0-9]{3}$');
|
|
`);
|
|
|
|
// Delete unreferenced legacy rows (variant collector numbers, null external ids).
|
|
pgm.sql(`
|
|
DELETE FROM cards c
|
|
WHERE c.game = 'Lorcana'
|
|
AND (c.scryfall_id IS NULL OR c.scryfall_id !~ '^[A-Za-z]{2,4}-[0-9]{3}$')
|
|
AND NOT EXISTS (SELECT 1 FROM user_cards uc WHERE uc.card_id = c.id)
|
|
AND NOT EXISTS (SELECT 1 FROM deck_cards dc WHERE dc.card_id = c.id)
|
|
AND NOT EXISTS (SELECT 1 FROM collection_cards cc WHERE cc.card_id = c.id);
|
|
`);
|
|
};
|
|
|
|
export const down = () => {
|
|
throw new Error('Irreversible data cleanup');
|
|
};
|