Repository navigation
Release v0.3.0 - #144
Merged
Merged
Release v0.3.0#144
Conversation
…match pg_cron - markRefunds (Deno post-sync and Node classify-flow) pairs only rows whose flow_source is 'default', guarded on it too: a flow you, a rule or a past choice decided is never moved to refunded. - Node sync stores own_counterparty like the Deno sync (same IBAN compare, left out when your accounts can't be read). - Installer: Gemini privacy note says what goes to Google (names, descriptions, amounts, imported PDFs) and the free-tier terms. - README: sync runs in Supabase (pg_cron + Edge Functions), not on your computer. - package.json: name alopex, real description, version 0.1.0. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Legacy flows (set before flow_source existed) are what refund pairing always read, so a refund of a charge from before the upgrade still pairs. Only flows you or a rule decided stay untouched. Comments no longer claim the dashboard can mark refunds by hand. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
A "not a transfer" flow rule sets flow_source='rule' but keeps the direction, so the default/legacy-only filter stopped pairing refunds for those merchants (counted as spend and income). Refunds now skip only flows set by hand. The update guards flow_type too (new optional alsoIn in applyGroupedUpdates), so a row a rule turned into a transfer after the read is left alone. Tests now run against an in-memory table and check which rows pair, not the query shape. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
entry_reference is not unique across accounts, so pages could overlap or skip rows and miss a pair. The Deno side already does this. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
A pair whose second write failed, or whose other side you moved to Transfer or deleted, stayed 'refunded' on one side for good, putting spend and income off by the amount. Each run now repairs these first: it finishes a pair whose charge is still plain spend, counts a lone credit as income again (keeping refund_of, so it can only re-pair with that same charge, never last month's identical one), and counts a charge with no live refunded credit as spend again so it pairs anew. Rows you set by hand are never touched. A credit looks its charge up by key with no date limit, so pairs at the window edge stay intact. Also: candidates are read in primary-key order and deduped by key (a concurrent write could shift a row into two pages), and a failed refund write now marks the post-sync run as failed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
While the Node scheduler still runs, it could pair a credit the Edge repair reset to income with an older identical charge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
restrict_transaction_updates now guards refund_of too. Only the refund pairing (service role, trigger skipped) writes it; a signed-in user setting it could break the pairing query for every user or pair a credit with any charge (P2-3). Test: lock-refund-of-migration.test.js "a signed-in user cannot change refund_of" (also checked on PGlite: user update rejected, service role and category/flow updates still allowed, rollback reopens it). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
A charge lookup that errors now skips that account's repair for the run (counted as failed, logged by code only) instead of throwing out of markRefunds, which skipped refunds for every user (also P2-2). Test: flow.test.ts "a failed charge lookup on one account is counted, the others still repair and pair". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
`node --test installer/` also ran installer/index.js on Node 22 (real install + Supabase call). Test: "the installer test command runs only the test files". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Subscription/One-time runs right after categories, not last. Test: "the README lists the post-sync steps in the order they run". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…ions post-sync also sends Splitwise expense descriptions to Gemini (categorizeSplitwise). Test: "both Gemini privacy notes mention Splitwise". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Up/down/up in one rolled-back transaction: a signed-in user can't change or clear refund_of, still edits category/flow, can't touch other users' rows; the service role still writes it. Fails against the migration without the lock line (checked on local Postgres 16). Test: "a rehearsal runs the lock as a signed-in user and as the service role". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
npx create-alopex downloads tag v<installer version>; it was still v0.1.0, so new installs missed 13 migrations. UPGRADING.md gets a v0.2.0 section (installer and manual upgrade order) and the refund_of note now says post-sync must be redeployed too. Test: "UPGRADING.md has a section for the installer version". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…changelog FAQ (and its JSON-LD) said Gemini sees transaction descriptions; it also gets names, amounts, Splitwise descriptions and imported PDFs, and the free tier may train on them. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Before, any first argument was the install folder, so --help installed into ./--help. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
… (polish-1 B1) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…arting with - (polish-1 B2/B3) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
On Windows cmd expands %VAR% even inside quotes, so tar -C would unpack elsewhere. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
… in lib (polish-3 F9, F11) main() now only applies lib.startup(argv), so help/refuse/install is covered without spawning the installer (a spawn test would start a real install if it broke). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…alopex/alopex (polish-5 I1) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…ide the install; mark Codespaces-only steps (polish-5 I1, I2, I5) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…ish-5 I1) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
… it too (polish-5 I1 re-audit) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…ding (polish-5 I5 re-audit) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
…r, after asking (polish-5 I1 re-audit 2) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
… (polish-5 I1 re-audit nit) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015ob4vvxZYctk2yjxFjnvCL
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Release PR for v0.3.0. It changes no code: only the version, the upgrade notes and the changelog.
installer/package.json: version 0.2.0 → 0.3.0. The installer downloads tagv0.3.0of both repos.UPGRADING.md: the "Unreleased" section becomes v0.3.0 (14 Nov 2026). It adds:npx create-alopex@0.3.0)--helpand updating from inside the install (Installer: --help is taken as the folder name #132), and the dashboard fixessite/changelog.html: a new "14 Nov v0.3.0" entry above v0.2.0.--helpand updating, old long rules can be edited again.npx create-alopex@latest.What's in v0.3.0:
After merge (Marco):
v0.3.0on both repos, at main.cd installer && npm publish. Runnpm loginfirst if npm answers 404.npm test: 368 pass, 0 fail.Generated by Claude Code