deckhearth/pages/api/cron/sync-catalog.js
Randall Stillwell ec9bb2b93e feat(catalog): unified multi-game bulk sync + schema map update
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>
2026-06-14 08:22:19 -05:00

41 lines
1.3 KiB
JavaScript

import { runUnifiedCatalogSync } from '../../../lib/card-import/sync-catalog.js';
function authorizeCron(req) {
const secret = process.env.CRON_SECRET;
if (!secret) {
if (process.env.NODE_ENV === 'production' || process.env.VERCEL_ENV === 'production') {
return { ok: false, status: 503, error: 'CRON_SECRET is not configured' };
}
console.warn('[GET /api/cron/sync-catalog] CRON_SECRET unset — allowing in dev');
return { ok: true };
}
const authHeader = req.headers.authorization || '';
const token = authHeader.startsWith('Bearer ') ? authHeader.slice('Bearer '.length) : '';
if (!token || token !== secret) {
return { ok: false, status: 401, error: 'Unauthorized' };
}
return { ok: true };
}
export default async function handler(req, res) {
if (req.method !== 'GET') {
return res.status(405).json({ error: 'Method not allowed' });
}
const auth = authorizeCron(req);
if (!auth.ok) {
return res.status(auth.status).json({ error: auth.error });
}
try {
const summary = await runUnifiedCatalogSync();
return res.status(200).json({ success: true, ...summary });
} catch (error) {
console.error('[GET /api/cron/sync-catalog]', error);
return res.status(500).json({ error: 'Catalog sync failed', details: error.message });
}
}