Three top-level groups replace the flat eight categories on the home
page and /browse:
Apps 7 sub-categories inside: browsers / communication /
privacy / devtools / media / productivity / other
Games single bucket for now; sub-chips later when there's volume
FinTech single bucket for now (BCH wallets, bridges, POS, DeFi)
Routes:
/t/<slug> top-level page. For Apps shows the 7 sub-chips + an
aggregated listings view across them. For Games and
FinTech shows the listings directly (no sub-chips).
/c/<slug> sub-category page under Apps (browsers, communication, …).
The sole-sub categories /c/games and /c/fintech 301 to
/t/games and /t/fintech respectively, so each view has
exactly one canonical URL.
Slug renames + removals in the CATEGORIES allow-list on listings.js:
utilities → productivity (the display label was already pointing at
that in people's heads — "productivity"
fits storage + sync + file tools better)
wallets → fintech (broader scope: bridges + POS + DeFi,
not just wallets)
games stays as a top-level sole-bucket
browsers NEW sub-category under Apps for BCNR
resolvers, mobile browsers, extensions
Seed listings re-categorised + two slug fixes:
theseus.x/theseus-navigator-win category: other → browsers
ariadne.x/ariadne-resolver-win → RENAMED to ariadne-thread-win,
name "Ariadne's Thread
(Windows resolver)" shortened
to just "Ariadne's Thread";
category: privacy → browsers
ariadne.x/ariadne-android → RENAMED to ariadne-navigator,
name "Ariadne's Thread
(Android)" → "Ariadne
Navigator" (it is a
different program, not a
platform build of Thread);
category: privacy → browsers
pithos.x/pithos-desktop category: utilities → productivity
scripts/migrate-taxonomy.mjs is a one-shot that deletes every row with
signature='SM_OPERATOR_SEED'; a subsequent `seed.mjs` run then inserts
the fresh set with the new slugs. Publisher-POSTed listings (none in
production today) are left alone. Idempotent — a second run finds
nothing to remove.
New icons:
top-apps.svg 2×2 rounded tile grid (OS launcher metaphor)
cat-browsers.svg browser window + 3 chrome dots + content block
Three icons reused: cat-games.svg doubles as the Games top icon,
cat-wallets.svg as the FinTech top icon (same visual, different label);
cat-utilities.svg stays as the Productivity sub icon.
45 lines
1.8 KiB
JavaScript
45 lines
1.8 KiB
JavaScript
#!/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.');
|
|
}
|