chore: bump to v0.34.1.1, Claude.ai catalog seed, subscription fixes
This commit is contained in:
parent
35d0cbf8be
commit
6edb23cd66
10
HISTORY.md
10
HISTORY.md
|
|
@ -1,5 +1,14 @@
|
||||||
# Bill Tracker — Changelog
|
# Bill Tracker — Changelog
|
||||||
|
|
||||||
|
## v0.34.1.1
|
||||||
|
|
||||||
|
### 🔧 Changed
|
||||||
|
|
||||||
|
- **Bump** — `0.34.1` → `0.34.1.1`
|
||||||
|
- **Claude.ai catalog seed** — Updated subscription catalog to match Claude Pro transaction descriptions.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## v0.34.1
|
## v0.34.1
|
||||||
|
|
||||||
### 🚀 Features
|
### 🚀 Features
|
||||||
|
|
@ -7,6 +16,7 @@
|
||||||
- **Persistent tracker bill ordering** — Added `sort_order` on bills, `PUT /api/bills/reorder`, and tracker drag/up/down controls so bill order can be changed and remembered.
|
- **Persistent tracker bill ordering** — Added `sort_order` on bills, `PUT /api/bills/reorder`, and tracker drag/up/down controls so bill order can be changed and remembered.
|
||||||
- **Bill archive endpoint** — Added `PUT /api/bills/:id/archived` to hide or restore bills without deleting them.
|
- **Bill archive endpoint** — Added `PUT /api/bills/:id/archived` to hide or restore bills without deleting them.
|
||||||
- **Subscription catalog matching** — Subscription recommendations now use the DB-backed `subscription_catalog` as a strong matching signal alongside the existing recurrence algorithm. Known services can surface as high-confidence recommendations, with catalog name/type/website carried into the Track flow.
|
- **Subscription catalog matching** — Subscription recommendations now use the DB-backed `subscription_catalog` as a strong matching signal alongside the existing recurrence algorithm. Known services can surface as high-confidence recommendations, with catalog name/type/website carried into the Track flow.
|
||||||
|
- **Claude.ai catalog seed** — Updated the known subscription catalog so Claude.ai/Anthropic transaction descriptors match the Claude Pro subscription entry.
|
||||||
- **Subscription transaction match search** — Added `/api/subscriptions/transaction-matches` for the Subscriptions page. Bank transaction search now annotates known catalog hits, shows "Known: service" badges, and pre-fills new subscriptions from catalog metadata when available.
|
- **Subscription transaction match search** — Added `/api/subscriptions/transaction-matches` for the Subscriptions page. Bank transaction search now annotates known catalog hits, shows "Known: service" badges, and pre-fills new subscriptions from catalog metadata when available.
|
||||||
- **Payoff Simulator page** — New `/payoff` route in sidebar. Select any debt from a dropdown; inputs auto-populate from bill rate, minimum, and expected amount (all editable). Live-updating custom SVG chart with 3 tracks: slate dashed (min-only), indigo dashed (snowball plan), amber solid (simulation). Stats cards show interest saved vs minimum, time saved, and total paid breakdown. "Apply to budget" pushes sim payment back to bill's expected amount with undo support.
|
- **Payoff Simulator page** — New `/payoff` route in sidebar. Select any debt from a dropdown; inputs auto-populate from bill rate, minimum, and expected amount (all editable). Live-updating custom SVG chart with 3 tracks: slate dashed (min-only), indigo dashed (snowball plan), amber solid (simulation). Stats cards show interest saved vs minimum, time saved, and total paid breakdown. "Apply to budget" pushes sim payment back to bill's expected amount with undo support.
|
||||||
- **Snowball plan lifecycle** — Snowball page now supports committing to a plan. "Start Snowball Plan" button appears once ≥3 readiness items are checked. Active plan shows a collapsible emerald banner with pulsing status dot, per-debt progress bars, and on-track/ahead/behind indicators computed from the plan's initial snapshot vs. current balances. Actions: Pause · Resume · Complete · Abandon · New Plan (with AlertDialog confirmation).
|
- **Snowball plan lifecycle** — Snowball page now supports committing to a plan. "Start Snowball Plan" button appears once ≥3 readiness items are checked. Active plan shows a collapsible emerald banner with pulsing status dot, per-debt progress bars, and on-track/ahead/behind indicators computed from the plan's initial snapshot vs. current balances. Actions: Pause · Resume · Complete · Abandon · New Plan (with AlertDialog confirmation).
|
||||||
|
|
|
||||||
|
|
@ -167,7 +167,7 @@ const SUBSCRIPTION_CATALOG_ROWS = [
|
||||||
[91,'Todoist','Software & Productivity','software','https://todoist.com/pricing','todoist.com'],
|
[91,'Todoist','Software & Productivity','software','https://todoist.com/pricing','todoist.com'],
|
||||||
[92,'Grammarly','Writing & AI','software','https://www.grammarly.com/plans','grammarly.com'],
|
[92,'Grammarly','Writing & AI','software','https://www.grammarly.com/plans','grammarly.com'],
|
||||||
[93,'ChatGPT','AI','software','https://chatgpt.com/pricing','chatgpt.com'],
|
[93,'ChatGPT','AI','software','https://chatgpt.com/pricing','chatgpt.com'],
|
||||||
[94,'Claude','AI','software','https://claude.ai/upgrade','claude.ai'],
|
[94,'Claude.ai','AI','software','https://claude.ai/upgrade','anthropic.com'],
|
||||||
[95,'Perplexity','AI','software','https://www.perplexity.ai/pro','perplexity.ai'],
|
[95,'Perplexity','AI','software','https://www.perplexity.ai/pro','perplexity.ai'],
|
||||||
[96,'Gemini Advanced','AI','software','https://one.google.com/about/google-ai-plans/','one.google.com'],
|
[96,'Gemini Advanced','AI','software','https://one.google.com/about/google-ai-plans/','one.google.com'],
|
||||||
[97,'GitHub Copilot','Developer Tools','software','https://github.com/features/copilot/plans','github.com'],
|
[97,'GitHub Copilot','Developer Tools','software','https://github.com/features/copilot/plans','github.com'],
|
||||||
|
|
@ -2472,6 +2472,32 @@ function runMigrations() {
|
||||||
`);
|
`);
|
||||||
db.exec('CREATE INDEX IF NOT EXISTS idx_snowball_plans_user ON snowball_plans(user_id, status, created_at)');
|
db.exec('CREATE INDEX IF NOT EXISTS idx_snowball_plans_user ON snowball_plans(user_id, status, created_at)');
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
version: 'v0.74',
|
||||||
|
description: 'subscription_catalog: Claude.ai Anthropic matching',
|
||||||
|
dependsOn: ['v0.73'],
|
||||||
|
run: function() {
|
||||||
|
db.prepare(`
|
||||||
|
UPDATE subscription_catalog
|
||||||
|
SET name = 'Claude.ai',
|
||||||
|
category = 'AI',
|
||||||
|
subscription_type = 'software',
|
||||||
|
website = 'https://claude.ai/upgrade',
|
||||||
|
domain = 'anthropic.com'
|
||||||
|
WHERE name IN ('Claude', 'Claude.ai')
|
||||||
|
OR domain IN ('claude.ai', 'anthropic.com')
|
||||||
|
`).run();
|
||||||
|
|
||||||
|
db.prepare(`
|
||||||
|
INSERT INTO subscription_catalog (rank, name, category, subscription_type, website, domain)
|
||||||
|
SELECT 94, 'Claude.ai', 'AI', 'software', 'https://claude.ai/upgrade', 'anthropic.com'
|
||||||
|
WHERE NOT EXISTS (
|
||||||
|
SELECT 1 FROM subscription_catalog
|
||||||
|
WHERE name = 'Claude.ai' OR domain IN ('claude.ai', 'anthropic.com')
|
||||||
|
)
|
||||||
|
`).run();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -92,7 +92,7 @@ Rank,Service,Category,Subcategory,Subscription_or_Plan,US_Availability,Website,S
|
||||||
91,Todoist,Software & Productivity,Task management,Todoist Pro,United States,https://todoist.com/pricing,https://todoist.com/pricing,Major U.S. consumer/professional software subscriptions; app revenue and SaaS prominence where applicable; curated
|
91,Todoist,Software & Productivity,Task management,Todoist Pro,United States,https://todoist.com/pricing,https://todoist.com/pricing,Major U.S. consumer/professional software subscriptions; app revenue and SaaS prominence where applicable; curated
|
||||||
92,Grammarly,Writing & AI,Writing assistant,Grammarly Pro,United States,https://www.grammarly.com/plans,https://www.grammarly.com/plans,Major U.S. consumer/professional software subscriptions; app revenue and SaaS prominence where applicable; curated
|
92,Grammarly,Writing & AI,Writing assistant,Grammarly Pro,United States,https://www.grammarly.com/plans,https://www.grammarly.com/plans,Major U.S. consumer/professional software subscriptions; app revenue and SaaS prominence where applicable; curated
|
||||||
93,ChatGPT,AI,AI assistant,ChatGPT Plus / Pro,United States,https://chatgpt.com/pricing,https://chatgpt.com/pricing,Major U.S. consumer/professional software subscriptions; app revenue and SaaS prominence where applicable; curated
|
93,ChatGPT,AI,AI assistant,ChatGPT Plus / Pro,United States,https://chatgpt.com/pricing,https://chatgpt.com/pricing,Major U.S. consumer/professional software subscriptions; app revenue and SaaS prominence where applicable; curated
|
||||||
94,Claude,AI,AI assistant,Claude Pro,United States,https://claude.ai/upgrade,https://claude.ai/upgrade,Major U.S. consumer/professional software subscriptions; app revenue and SaaS prominence where applicable; curated
|
94,Claude.ai,AI,AI assistant,Claude Pro,United States,https://claude.ai/upgrade,https://claude.ai/upgrade,Major U.S. consumer/professional software subscriptions; app revenue and SaaS prominence where applicable; curated
|
||||||
95,Perplexity,AI,AI search,Perplexity Pro,United States,https://www.perplexity.ai/pro,https://www.perplexity.ai/pro,Major U.S. consumer/professional software subscriptions; app revenue and SaaS prominence where applicable; curated
|
95,Perplexity,AI,AI search,Perplexity Pro,United States,https://www.perplexity.ai/pro,https://www.perplexity.ai/pro,Major U.S. consumer/professional software subscriptions; app revenue and SaaS prominence where applicable; curated
|
||||||
96,Gemini Advanced,AI,AI assistant / Google One AI,Google AI plans,United States,https://one.google.com/about/google-ai-plans/,https://one.google.com/about/google-ai-plans/,Major U.S. consumer/professional software subscriptions; app revenue and SaaS prominence where applicable; curated
|
96,Gemini Advanced,AI,AI assistant / Google One AI,Google AI plans,United States,https://one.google.com/about/google-ai-plans/,https://one.google.com/about/google-ai-plans/,Major U.S. consumer/professional software subscriptions; app revenue and SaaS prominence where applicable; curated
|
||||||
97,GitHub Copilot,Developer Tools,AI coding,GitHub Copilot,United States,https://github.com/features/copilot/plans,https://github.com/features/copilot/plans,Major U.S. consumer/professional software subscriptions; app revenue and SaaS prominence where applicable; curated
|
97,GitHub Copilot,Developer Tools,AI coding,GitHub Copilot,United States,https://github.com/features/copilot/plans,https://github.com/features/copilot/plans,Major U.S. consumer/professional software subscriptions; app revenue and SaaS prominence where applicable; curated
|
||||||
|
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
{
|
{
|
||||||
"name": "bill-tracker",
|
"name": "bill-tracker",
|
||||||
"version": "0.34.1",
|
"version": "0.34.1.1",
|
||||||
"description": "Monthly bill tracking system",
|
"description": "Monthly bill tracking system",
|
||||||
"main": "server.js",
|
"main": "server.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ function catalogDomainKeys(entry) {
|
||||||
if (labels.length >= 2) {
|
if (labels.length >= 2) {
|
||||||
keys.add(labels.join(' '));
|
keys.add(labels.join(' '));
|
||||||
keys.add(labels.slice(-2).join(' '));
|
keys.add(labels.slice(-2).join(' '));
|
||||||
|
if (labels[0].length >= 5) keys.add(labels[0]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [...keys].filter(key => key.length >= 4);
|
return [...keys].filter(key => key.length >= 4);
|
||||||
|
|
@ -498,8 +499,10 @@ function createSubscriptionFromRecommendation(db, userId, payload = {}) {
|
||||||
expected_amount: payload.expected_amount,
|
expected_amount: payload.expected_amount,
|
||||||
billing_cycle: billingCycleForCycleType(payload.cycle_type || 'monthly'),
|
billing_cycle: billingCycleForCycleType(payload.cycle_type || 'monthly'),
|
||||||
cycle_type: payload.cycle_type || 'monthly',
|
cycle_type: payload.cycle_type || 'monthly',
|
||||||
cycle_day: payload.cycle_type === 'annual' || payload.cycle_type === 'quarterly'
|
cycle_day: (payload.cycle_type === 'annual' || payload.cycle_type === 'quarterly')
|
||||||
? String(new Date(`${seenDate}T00:00:00`).getMonth() + 1)
|
? String(new Date(`${seenDate}T00:00:00`).getMonth() + 1)
|
||||||
|
: (payload.cycle_type === 'weekly' || payload.cycle_type === 'biweekly')
|
||||||
|
? 'monday'
|
||||||
: String(payload.due_day || 1),
|
: String(payload.due_day || 1),
|
||||||
is_subscription: 1,
|
is_subscription: 1,
|
||||||
subscription_type: SUBSCRIPTION_TYPES.includes(payload.subscription_type) ? payload.subscription_type : 'other',
|
subscription_type: SUBSCRIPTION_TYPES.includes(payload.subscription_type) ? payload.subscription_type : 'other',
|
||||||
|
|
|
||||||
|
|
@ -71,3 +71,21 @@ test('subscription transaction search annotates known catalog matches', () => {
|
||||||
assert.equal(match.catalog_match.name, 'Netflix');
|
assert.equal(match.catalog_match.name, 'Netflix');
|
||||||
assert.equal(match.catalog_match.subscription_type, 'streaming');
|
assert.equal(match.catalog_match.subscription_type, 'streaming');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Claude.ai catalog seed matches Anthropic transaction descriptors', () => {
|
||||||
|
const db = getDb();
|
||||||
|
const userId = createUser(db, 'claude');
|
||||||
|
const transactionId = createTransaction(db, userId, {
|
||||||
|
description: 'ANTHROPIC CLAUDE PRO',
|
||||||
|
payee: 'ANTHROPIC',
|
||||||
|
amount: -2000,
|
||||||
|
});
|
||||||
|
|
||||||
|
const matches = searchSubscriptionTransactions(db, userId, { q: 'anthropic', limit: 10 });
|
||||||
|
const match = matches.find(item => item.id === transactionId);
|
||||||
|
|
||||||
|
assert.ok(match, 'Anthropic transaction should be returned by subscription search');
|
||||||
|
assert.equal(match.is_known_subscription, true);
|
||||||
|
assert.equal(match.catalog_match.name, 'Claude.ai');
|
||||||
|
assert.equal(match.catalog_match.subscription_type, 'software');
|
||||||
|
});
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue