diff --git a/HISTORY.md b/HISTORY.md index e4cc1fa..16c1293 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,19 @@ # 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 ### 🚀 Features diff --git a/client/index.css b/client/index.css index 0de3e56..4d9e121 100644 --- a/client/index.css +++ b/client/index.css @@ -62,7 +62,7 @@ --sidebar-accent-foreground: 0.20 0.008 250; --sidebar-border: 0.88 0.008 250; --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-mono: "Roboto Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace; --radius: 1rem; @@ -160,7 +160,7 @@ } .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-feature-settings: "tnum" 1, "lnum" 1; -webkit-font-smoothing: auto; diff --git a/db/database.js b/db/database.js index 064f5a0..b466e26 100644 --- a/db/database.js +++ b/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'], ]; +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) { database.exec(` CREATE TABLE IF NOT EXISTS advisory_non_bill_filters ( @@ -2264,6 +2409,14 @@ function runMigrations() { run: function() { runAdvisoryFiltersMigration(db); } + }, + { + version: 'v0.69', + description: 'subscription_catalog v2: 90 new services + category fixes', + dependsOn: ['v0.68'], + run: function() { + runSubscriptionCatalogV2Migration(db); + } } ]; diff --git a/package.json b/package.json index 88cd204..d51678a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "bill-tracker", - "version": "0.33.8.0", + "version": "0.33.8.1", "description": "Monthly bill tracking system", "main": "server.js", "scripts": {