the build
LiveSubscription Manager
A tracker for the slow drip of recurring charges — Netflix, iCloud, broadband — that answers what you're spending this month, what's about to hit, and where the money actually goes.
- My role
- Solo — product, client, server, schema
- Timeline
- 2024 — ongoing
- Core stack
- React 19 · Vite · Tailwind v4

what's in it
Features
- Every amount stored twice
- A subscription keeps
originalAmount/originalCurrencyexactly as entered andcostInDollarnormalised at entry time, so a later rate move can never rewrite your history — and a ৳2,200 broadband bill stays addable to a $15.49 Netflix one. - Nothing re-converts on the way to the screen
- Totals, charts, forecasts and the AI prompt all read the normalised column. Live rates are fetched server-side, cached 12h with a static fallback, and touched exactly once — at write time.
- A forecast that walks the schedule
- Six months of projected spend built by stepping each subscription's real billing cycle forward, so an annual renewal shows up as the spike it is instead of being smeared into a monthly average.
- Price-change detection
- Reads the transaction history and surfaces which services quietly went up, by how much and when — YouTube Premium $12 → $14, Adobe $55 → $60.
- Gating that actually gates
- The 10-subscription free cap and every premium feature are enforced in the resolvers through
requireFeatureandassertWithinSubscriptionLimit, reading the sameconfig/plans.jstable the client reads. A disabled button is not the security model. - AI insights that regenerate themselves
- A plain-language read on your spending, specific about your services and written in your own currency. Cached, and regenerated only when the underlying data changes — no 'generate' button to babysit.
- Renewals everywhere you look
- A nightly cron rolls billing cycles forward and fires reminders — email plus in-app — at as many lead times as you pick. Google Calendar events add, update and remove themselves as you edit; there's a private
.icsfeed for Apple and Outlook. - History you can correct by hand
- Month-by-month transactions with per-provider and per-category breakdowns, editable in place, because a billing record that can't be fixed stops being trusted.
- One layout, phone to desktop
- The stat grid folds to a single column rather than shrinking, and dark mode is a token swap on the same markup — no second stylesheet to keep in sync.
a look around
What it looks like in use
The overview answers three questions in one screen: what this month costs, what's charged next, and how that compares to last month. Upcoming payments are ordered by how soon they land, not alphabetically.
three questions, one screen
Every figure here reads the normalised USD column, so mixed-currency subscriptions add up without the chart layer touching an exchange rate.
The September spike is an annual renewal, not noise — the forecast walks each billing schedule forward rather than averaging.
The model gets normalised amounts and real service names, so the advice names your services and your numbers.
One table, filterable by category and cycle. Alerts toggle per row; renewal date is the sort everyone actually wants.
Same data, one column — the stat grid folds rather than shrinking to unreadable.
built thumb-first
History keeps its per-row edit and delete on a phone; correcting a bill is exactly where you are when you notice it's wrong.
what it's made of
The stack
- Client
- React 19
- Vite
- Tailwind v4
- Apollo Client
- Chart.js
- Framer Motion
- Server
- Node
- Express 5
- Apollo Server 5
- GraphQL
- Passport (sessions)
- Helmet
- Data
- MongoDB
- Mongoose
- Services
- Nodemailer
- Google Calendar
- OpenAI-compatible API
- Stripe (seam)
- node-cron