#!/usr/bin/env node /** * One-shot migration for the taxonomy change (Oct 2026): * * - Top-level groups introduced: Apps / Games / FinTech. * - Sub-category slugs renamed: * wallets → fintech * utilities → productivity * - New sub-category under Apps: browsers (for Theseus, Ariadne's Thread, * Ariadne Navigator) * - Removed listing slug: ariadne-android (mislabel of ariadne-navigator) * - Renamed listing slug: ariadne-resolver-win → ariadne-thread-win * (to match the product's actual name, * Ariadne's Thread) * * This script deletes every row that was inserted by `seed.mjs` (identified by * signature='SM_OPERATOR_SEED'), so a subsequent `seed.mjs` run inserts the * fresh set with the new slugs + categories. Publisher-POSTed listings are * NOT touched — a listing with a real BIP-137 signature stays put, and the * admin can rewrite its category by withdrawing + republishing if needed. * * Run with: * node scripts/migrate-taxonomy.mjs * or inside the VPS container: * docker exec prometheus-prometheus-1 node scripts/migrate-taxonomy.mjs * * Idempotent — a second run finds no SM_OPERATOR_SEED rows and does nothing. */ import { db } from '../service/db.js'; const stmt = db.prepare(` DELETE FROM listings WHERE signature = 'SM_OPERATOR_SEED' RETURNING id, category `); const removed = stmt.all(); if (removed.length === 0) { console.log('[migrate] no operator-seeded rows found — nothing to remove.'); } else { console.log(`[migrate] removed ${removed.length} operator-seeded rows:`); for (const r of removed) console.log(` - ${r.id} (category=${r.category})`); console.log('[migrate] now run `node scripts/seed.mjs` to insert the fresh set.'); }