feat: subscription catalog v2 + GeorgiaDigits font-face (batch 0.33.8.1)
- Migration v0.69: 90 new services across 16 categories - Fixed Discord Nitro, Twitch Turbo, X Premium categories - GeorgiaDigits @font-face with unicode-range for digit/currency codepoints only, applied via --font-sans and .tracker-number - Bump v0.33.8.0 -> v0.33.8.1
This commit is contained in:
parent
b34e21d1ba
commit
c37716f685
14
HISTORY.md
14
HISTORY.md
|
|
@ -1,5 +1,19 @@
|
||||||
# Bill Tracker — Changelog
|
# Bill Tracker — Changelog
|
||||||
|
|
||||||
|
## v0.33.8.1
|
||||||
|
|
||||||
|
### 🚀 Features
|
||||||
|
|
||||||
|
- **Subscription catalog v2** — 90 new services across 16 new categories: AI (Suno, Midjourney, Grok, ElevenLabs, Character.ai, Runway, Windsurf, Leonardo.ai), home security (Ring, Nest, SimpliSafe, ADT, Arlo, Wyze, Abode), financial data (SimpleFIN Bridge, Tiller, Monarch, Empower), cloud backup (Backblaze, Carbonite, iDrive), email (Proton Mail, Fastmail, Superhuman, Hey), security/privacy (Bitwarden, Keeper, LastPass, Proton VPN, Mullvad, PIA, Proton Pass, SimpleLogin), identity protection, comics, genealogy, telehealth, website builders, learning platforms, project management, email marketing, cloud compute, media server, homelab/network, and productivity tools.
|
||||||
|
- **Category corrections** — Discord Nitro (`news` → `software`), Twitch Turbo (`news` → `streaming`), X Premium (`news` → `software`).
|
||||||
|
- **GeorgiaDigits font-face** — Browser loads Georgia only for digit/currency codepoints via `unicode-range`. Letters continue with Inter/Roboto. Applied globally via `--font-sans` and `.tracker-number`.
|
||||||
|
|
||||||
|
### 🛠 Internal
|
||||||
|
|
||||||
|
- Migration `v0.69` — seeds `SUBSCRIPTION_CATALOG_V2_ROWS`, fixes 3 existing category bugs, skips duplicates.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## v0.33.8.0
|
## v0.33.8.0
|
||||||
|
|
||||||
### 🚀 Features
|
### 🚀 Features
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@
|
||||||
--sidebar-accent-foreground: 0.20 0.008 250;
|
--sidebar-accent-foreground: 0.20 0.008 250;
|
||||||
--sidebar-border: 0.88 0.008 250;
|
--sidebar-border: 0.88 0.008 250;
|
||||||
--sidebar-ring: 0.55 0.20 276;
|
--sidebar-ring: 0.55 0.20 276;
|
||||||
--font-sans: Inter, Roboto, ui-sans-serif, system-ui, sans-serif;
|
--font-sans: 'GeorgiaDigits', Inter, Roboto, ui-sans-serif, system-ui, sans-serif;
|
||||||
--font-serif: Merriweather, Georgia, serif;
|
--font-serif: Merriweather, Georgia, serif;
|
||||||
--font-mono: "Roboto Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
--font-mono: "Roboto Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
|
||||||
--radius: 1rem;
|
--radius: 1rem;
|
||||||
|
|
@ -160,7 +160,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.tracker-number {
|
.tracker-number {
|
||||||
font-family: Inter, Roboto, ui-sans-serif, system-ui, sans-serif;
|
font-family: 'GeorgiaDigits', Inter, Roboto, ui-sans-serif, system-ui, sans-serif;
|
||||||
font-variant-numeric: tabular-nums lining-nums;
|
font-variant-numeric: tabular-nums lining-nums;
|
||||||
font-feature-settings: "tnum" 1, "lnum" 1;
|
font-feature-settings: "tnum" 1, "lnum" 1;
|
||||||
-webkit-font-smoothing: auto;
|
-webkit-font-smoothing: auto;
|
||||||
|
|
|
||||||
153
db/database.js
153
db/database.js
|
|
@ -276,6 +276,151 @@ const SUBSCRIPTION_CATALOG_ROWS = [
|
||||||
[200,'Book of the Month','Books & Subscription Boxes','education','https://www.bookofthemonth.com/','bookofthemonth.com'],
|
[200,'Book of the Month','Books & Subscription Boxes','education','https://www.bookofthemonth.com/','bookofthemonth.com'],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const SUBSCRIPTION_CATALOG_V2_ROWS = [
|
||||||
|
// ── AI ──────────────────────────────────────────────────────────────────────
|
||||||
|
[201,'Suno','AI Music','music','https://suno.com/','suno.com'],
|
||||||
|
[202,'Midjourney','AI Image Generation','software','https://midjourney.com/','midjourney.com'],
|
||||||
|
[203,'Grok','AI','software','https://grok.com/','grok.com'],
|
||||||
|
[204,'ElevenLabs','AI Voice','software','https://elevenlabs.io/','elevenlabs.io'],
|
||||||
|
[205,'Character.ai Plus','AI','software','https://character.ai/','character.ai'],
|
||||||
|
[206,'Runway','AI Video','software','https://runwayml.com/','runwayml.com'],
|
||||||
|
[207,'Windsurf','Developer Tools','software','https://windsurf.com/','windsurf.com'],
|
||||||
|
[208,'Leonardo.ai','AI Image Generation','software','https://leonardo.ai/','leonardo.ai'],
|
||||||
|
// ── Home Security / Smart Home ───────────────────────────────────────────────
|
||||||
|
[209,'Ring Protect','Home Security','other','https://ring.com/protect-plans','ring.com'],
|
||||||
|
[210,'Nest Aware','Home Security','other','https://store.google.com/us/category/connected_home','nest.com'],
|
||||||
|
[211,'SimpliSafe','Home Security','other','https://simplisafe.com/','simplisafe.com'],
|
||||||
|
[212,'ADT','Home Security','other','https://www.adt.com/','adt.com'],
|
||||||
|
[213,'Arlo Secure','Home Security','other','https://www.arlo.com/','arlo.com'],
|
||||||
|
[214,'Wyze Cam Plus','Home Security','other','https://www.wyze.com/','wyze.com'],
|
||||||
|
[215,'Abode','Home Security','other','https://goabode.com/','goabode.com'],
|
||||||
|
// ── Financial Data & Aggregation ────────────────────────────────────────────
|
||||||
|
[216,'SimpleFIN Bridge','Financial Data','software','https://simplefin.org/','simplefin.org'],
|
||||||
|
[217,'Tiller Money','Financial Data','software','https://www.tillerhq.com/','tillerhq.com'],
|
||||||
|
[218,'Monarch Money','Finance Software','software','https://www.monarchmoney.com/','monarchmoney.com'],
|
||||||
|
[219,'Empower','Finance Software','software','https://www.empower.com/','empower.com'],
|
||||||
|
// ── Cloud Backup ─────────────────────────────────────────────────────────────
|
||||||
|
[220,'Backblaze','Cloud Backup','cloud','https://www.backblaze.com/','backblaze.com'],
|
||||||
|
[221,'Carbonite','Cloud Backup','cloud','https://www.carbonite.com/','carbonite.com'],
|
||||||
|
[222,'iDrive','Cloud Backup','cloud','https://www.idrive.com/','idrive.com'],
|
||||||
|
// ── Email ────────────────────────────────────────────────────────────────────
|
||||||
|
[223,'Proton Mail','Email & Privacy','software','https://proton.me/mail','proton.me'],
|
||||||
|
[224,'Fastmail','Email','software','https://www.fastmail.com/','fastmail.com'],
|
||||||
|
[225,'Superhuman','Email','software','https://superhuman.com/','superhuman.com'],
|
||||||
|
[226,'Hey','Email','software','https://www.hey.com/','hey.com'],
|
||||||
|
// ── Security / Privacy ───────────────────────────────────────────────────────
|
||||||
|
[227,'Bitwarden','Security','security','https://bitwarden.com/','bitwarden.com'],
|
||||||
|
[228,'Keeper','Security','security','https://www.keepersecurity.com/','keepersecurity.com'],
|
||||||
|
[229,'LastPass','Security','security','https://www.lastpass.com/','lastpass.com'],
|
||||||
|
[230,'Proton VPN','Security','security','https://protonvpn.com/','protonvpn.com'],
|
||||||
|
[231,'Mullvad VPN','Security','security','https://mullvad.net/','mullvad.net'],
|
||||||
|
[232,'Private Internet Access','Security','security','https://www.privateinternetaccess.com/','privateinternetaccess.com'],
|
||||||
|
[233,'Proton Pass','Security','security','https://proton.me/pass','proton.me'],
|
||||||
|
[234,'SimpleLogin','Email Privacy','software','https://simplelogin.io/','simplelogin.io'],
|
||||||
|
// ── Identity Protection ──────────────────────────────────────────────────────
|
||||||
|
[235,'LifeLock','Identity Protection','security','https://www.lifelock.com/','lifelock.com'],
|
||||||
|
[236,'Aura','Identity Protection','security','https://www.aura.com/','aura.com'],
|
||||||
|
[237,'IdentityForce','Identity Protection','security','https://www.identityforce.com/','identityforce.com'],
|
||||||
|
// ── Comics ───────────────────────────────────────────────────────────────────
|
||||||
|
[238,'Marvel Unlimited','Comics','streaming','https://www.marvel.com/unlimited','marvel.com'],
|
||||||
|
[239,'DC Universe Infinite','Comics','streaming','https://www.dcuniverseinfinite.com/','dcuniverseinfinite.com'],
|
||||||
|
// ── Genealogy ────────────────────────────────────────────────────────────────
|
||||||
|
[240,'Ancestry','Genealogy','other','https://www.ancestry.com/','ancestry.com'],
|
||||||
|
[241,'MyHeritage','Genealogy','other','https://www.myheritage.com/','myheritage.com'],
|
||||||
|
[242,'Findmypast','Genealogy','other','https://www.findmypast.com/','findmypast.com'],
|
||||||
|
// ── Telehealth ───────────────────────────────────────────────────────────────
|
||||||
|
[243,'BetterHelp','Telehealth','other','https://www.betterhelp.com/','betterhelp.com'],
|
||||||
|
[244,'Talkspace','Telehealth','other','https://www.talkspace.com/','talkspace.com'],
|
||||||
|
[245,'Teladoc','Telehealth','other','https://www.teladoc.com/','teladoc.com'],
|
||||||
|
[246,'Hims & Hers','Telehealth','other','https://www.forhims.com/','forhims.com'],
|
||||||
|
[247,'Cerebral','Telehealth','other','https://cerebral.com/','cerebral.com'],
|
||||||
|
// ── Website Builder / Hosting / Domains ─────────────────────────────────────
|
||||||
|
[248,'Squarespace','Website Builder','software','https://www.squarespace.com/','squarespace.com'],
|
||||||
|
[249,'Wix','Website Builder','software','https://www.wix.com/','wix.com'],
|
||||||
|
[250,'Webflow','Website Builder','software','https://webflow.com/','webflow.com'],
|
||||||
|
[251,'GoDaddy','Domain & Hosting','software','https://www.godaddy.com/','godaddy.com'],
|
||||||
|
[252,'Namecheap','Domain & Hosting','software','https://www.namecheap.com/','namecheap.com'],
|
||||||
|
[253,'Netlify','Developer Tools','software','https://www.netlify.com/','netlify.com'],
|
||||||
|
[254,'Vercel','Developer Tools','software','https://vercel.com/','vercel.com'],
|
||||||
|
// ── Learning ─────────────────────────────────────────────────────────────────
|
||||||
|
[255,'LinkedIn Learning','Education','education','https://www.linkedin.com/learning/','linkedin.com'],
|
||||||
|
[256,'Pluralsight','Education','education','https://www.pluralsight.com/','pluralsight.com'],
|
||||||
|
[257,"O'Reilly",'Education','education','https://www.oreilly.com/','oreilly.com'],
|
||||||
|
[258,'CBT Nuggets','Education','education','https://www.cbtnuggets.com/','cbtnuggets.com'],
|
||||||
|
[259,'Udacity','Education','education','https://www.udacity.com/','udacity.com'],
|
||||||
|
[260,'Frontend Masters','Education','education','https://frontendmasters.com/','frontendmasters.com'],
|
||||||
|
// ── Project Management ───────────────────────────────────────────────────────
|
||||||
|
[261,'Monday.com','Software & Productivity','software','https://monday.com/','monday.com'],
|
||||||
|
[262,'Asana','Software & Productivity','software','https://asana.com/','asana.com'],
|
||||||
|
[263,'ClickUp','Software & Productivity','software','https://clickup.com/','clickup.com'],
|
||||||
|
[264,'Linear','Developer Tools','software','https://linear.app/','linear.app'],
|
||||||
|
[265,'Basecamp','Software & Productivity','software','https://basecamp.com/','basecamp.com'],
|
||||||
|
[266,'Jira','Developer Tools','software','https://www.atlassian.com/software/jira','atlassian.com'],
|
||||||
|
[267,'Miro','Software & Productivity','software','https://miro.com/','miro.com'],
|
||||||
|
[268,'Airtable','Software & Productivity','software','https://airtable.com/','airtable.com'],
|
||||||
|
// ── Email Marketing ──────────────────────────────────────────────────────────
|
||||||
|
[269,'Mailchimp','Email Marketing','software','https://mailchimp.com/','mailchimp.com'],
|
||||||
|
[270,'ConvertKit','Email Marketing','software','https://convertkit.com/','convertkit.com'],
|
||||||
|
[271,'Beehiiv','Newsletter Platform','software','https://www.beehiiv.com/','beehiiv.com'],
|
||||||
|
[272,'Constant Contact','Email Marketing','software','https://www.constantcontact.com/','constantcontact.com'],
|
||||||
|
[273,'ActiveCampaign','Email Marketing','software','https://www.activecampaign.com/','activecampaign.com'],
|
||||||
|
// ── Cloud Computing ──────────────────────────────────────────────────────────
|
||||||
|
[274,'DigitalOcean','Cloud Computing','cloud','https://www.digitalocean.com/','digitalocean.com'],
|
||||||
|
[275,'Linode','Cloud Computing','cloud','https://www.linode.com/','linode.com'],
|
||||||
|
[276,'Render','Cloud Computing','cloud','https://render.com/','render.com'],
|
||||||
|
[277,'Vultr','Cloud Computing','cloud','https://www.vultr.com/','vultr.com'],
|
||||||
|
[278,'Hetzner','Cloud Computing','cloud','https://www.hetzner.com/','hetzner.com'],
|
||||||
|
[279,'Cloudflare','Network & Security','cloud','https://www.cloudflare.com/','cloudflare.com'],
|
||||||
|
// ── Media Server ─────────────────────────────────────────────────────────────
|
||||||
|
[280,'Plex Pass','Media Server','streaming','https://www.plex.tv/plex-pass/','plex.tv'],
|
||||||
|
[281,'Emby Premiere','Media Server','streaming','https://emby.media/premiere/','emby.media'],
|
||||||
|
// ── Network / Homelab ────────────────────────────────────────────────────────
|
||||||
|
[282,'NextDNS','Network & Security','software','https://nextdns.io/','nextdns.io'],
|
||||||
|
[283,'Tailscale','Network & Security','software','https://tailscale.com/','tailscale.com'],
|
||||||
|
// ── Productivity ─────────────────────────────────────────────────────────────
|
||||||
|
[284,'Obsidian Sync','Software & Productivity','software','https://obsidian.md/','obsidian.md'],
|
||||||
|
[285,'Readwise','Software & Productivity','software','https://readwise.io/','readwise.io'],
|
||||||
|
[286,'Loom','Software & Productivity','software','https://www.loom.com/','loom.com'],
|
||||||
|
[287,'Raycast Pro','Software & Productivity','software','https://www.raycast.com/','raycast.com'],
|
||||||
|
// ── Developer Tools ──────────────────────────────────────────────────────────
|
||||||
|
[288,'JetBrains','Developer Tools','software','https://www.jetbrains.com/','jetbrains.com'],
|
||||||
|
[289,'Tabnine','Developer Tools','software','https://www.tabnine.com/','tabnine.com'],
|
||||||
|
// ── Communication ────────────────────────────────────────────────────────────
|
||||||
|
[290,'Telegram Premium','Messaging','software','https://telegram.org/','telegram.org'],
|
||||||
|
];
|
||||||
|
|
||||||
|
function runSubscriptionCatalogV2Migration(database) {
|
||||||
|
// Category fixes for existing rows
|
||||||
|
database.prepare(`
|
||||||
|
UPDATE subscription_catalog SET subscription_type = 'software'
|
||||||
|
WHERE name = 'Discord Nitro' AND subscription_type = 'news'
|
||||||
|
`).run();
|
||||||
|
database.prepare(`
|
||||||
|
UPDATE subscription_catalog SET subscription_type = 'streaming'
|
||||||
|
WHERE name = 'Twitch Turbo' AND subscription_type = 'news'
|
||||||
|
`).run();
|
||||||
|
database.prepare(`
|
||||||
|
UPDATE subscription_catalog SET subscription_type = 'software'
|
||||||
|
WHERE name = 'X Premium' AND subscription_type = 'news'
|
||||||
|
`).run();
|
||||||
|
|
||||||
|
// New entries — skip any name already in the catalog
|
||||||
|
const existing = new Set(
|
||||||
|
database.prepare('SELECT name FROM subscription_catalog').all().map(r => r.name)
|
||||||
|
);
|
||||||
|
const toInsert = SUBSCRIPTION_CATALOG_V2_ROWS.filter(r => !existing.has(r[1]));
|
||||||
|
if (toInsert.length > 0) {
|
||||||
|
const insert = database.prepare(
|
||||||
|
'INSERT INTO subscription_catalog (rank, name, category, subscription_type, website, domain) VALUES (?,?,?,?,?,?)'
|
||||||
|
);
|
||||||
|
const insertMany = database.transaction((rows) => {
|
||||||
|
for (const row of rows) insert.run(...row);
|
||||||
|
});
|
||||||
|
insertMany(toInsert);
|
||||||
|
console.log(`[migration] subscription_catalog v2: added ${toInsert.length} new entries`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function runAdvisoryFiltersMigration(database) {
|
function runAdvisoryFiltersMigration(database) {
|
||||||
database.exec(`
|
database.exec(`
|
||||||
CREATE TABLE IF NOT EXISTS advisory_non_bill_filters (
|
CREATE TABLE IF NOT EXISTS advisory_non_bill_filters (
|
||||||
|
|
@ -2264,6 +2409,14 @@ function runMigrations() {
|
||||||
run: function() {
|
run: function() {
|
||||||
runAdvisoryFiltersMigration(db);
|
runAdvisoryFiltersMigration(db);
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
version: 'v0.69',
|
||||||
|
description: 'subscription_catalog v2: 90 new services + category fixes',
|
||||||
|
dependsOn: ['v0.68'],
|
||||||
|
run: function() {
|
||||||
|
runSubscriptionCatalogV2Migration(db);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "bill-tracker",
|
"name": "bill-tracker",
|
||||||
"version": "0.33.8.0",
|
"version": "0.33.8.1",
|
||||||
"description": "Monthly bill tracking system",
|
"description": "Monthly bill tracking system",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue