github securo-finance/securo v0.16.0

4 hours ago
reconciliation-queue

In this release we added payment matching: money that lands in an account binds itself to the invoice it settles, what it cannot decide alone goes to a queue, and the rules behind it are a list you can read, reorder and rewrite. Indian workspaces get an April to March financial year, seven currencies joined the list, and rules gained a full editor when adding a transaction to one and a way to be managed through MCP. On the fixes side, editing a recurring schedule moves its next occurrence, synced card installments inherit the category you gave the first one, a credit card bill no longer shrinks when a charge is tagged as a transfer, and the payees list holds up at the size a bank sync makes it.

reconciliation-rules

Features

  • Payments match the invoices they settle. Every transaction that comes in, whether synced, imported or typed by hand, is checked against open invoices and linked when the evidence is clear: same client, exact amount, inside the date window. One payment can settle several invoices and an invoice can be paid in parts. What is plausible but not certain waits under Rules with the evidence attached, to link or decline in one click, from the queue, the invoice or the transaction row. A history says what happened and whether you or the rules did it, and open invoices now count in the cash forecast (#817)
  • Matching rules are yours. Each threshold is a row under Rules: how close the amount must be, how wide the date window is, whether the payer must be known, whether a match links or asks. Reorder them, edit them, write your own, delete the shipped ones and bring them back, or export the set to a file and import it elsewhere (#817)
  • Indian financial year. A workspace with tax_jurisdiction = IN reports on an April to March year, with INR grouping and day-first dates. By @SaikumarMadel (#841) πŸŽ‰
  • Adding a transaction to a rule opens the full editor, pre-filled with the rule's conditions and actions, instead of a bare description field. Closes #905, by @vhsantos26 (#906) πŸŽ‰
  • Rules through MCP. An agent can list rules, preview what one would do, and propose a create, update or delete that you confirm in the existing proposal UI. Closes #908, by @DanielSuhett (#910) πŸŽ‰
  • Seven new currencies. Chinese yuan, closes #832, and Malaysian ringgit, closes #921, by @shaynhornik (#940, #939) πŸŽ‰ Β· Egyptian pound, closes #922, by @archibullo (#923) πŸŽ‰ Β· Thai baht, closes #865, by @deeepanshu (#903) πŸŽ‰ Β· UAE dirham, by @asankahh (#945) πŸŽ‰ Β· Moldovan leu, closes #878, by @maxpricop (#885) πŸŽ‰ Β· Pakistani rupee, closes #866, by @7487 (#867) πŸŽ‰

Fixes

  • Editing a recurring schedule left its next occurrence where it was. Changing the start date, day of month or frequency now moves the pointer to the first date of the new schedule, so projections follow the edit. Closes #942, by @rhuanbarreto (#943) πŸŽ‰
  • Synced card installments inherit their category. Once you categorise one installment of a purchase, the next ones arrive with the same category instead of blank, with your rules still taking precedence. By @panga (#894) πŸŽ‰
  • A credit card bill shrank when a charge was tagged as a transfer. The bill total reused the reporting filter, so a charge under a transfer or ignored category dropped out of what you owe the bank. Closes #647, by @vhsantos26 (#649) πŸŽ‰
  • Widening a card's date range could hide billed charges. A hand-picked window that matched no bill asked the backend for unbilled rows only, so the list and its total got smaller as the range got bigger (#874)
  • The payees list holds up at the size a sync creates. Long names truncate instead of widening the table, the list is paginated, and the detail card no longer displaces it. Closes #709, by @jrvidotti (#710) πŸŽ‰
  • Payees with a legacy type made the list fail. Rows imported long ago as transfer, employer or merchant are read as untyped instead of returning a 500. Closes #830, by @wolfgang-aura (#875) πŸŽ‰
  • A sync failed on a counterparty with a non-ASCII capital in its name. The payee lookup compared a database lowercase with a Python one, which disagree on a C-locale Postgres, so the second transaction naming "MÜLLER GmbH" tripped the unique constraint and took the whole sync down. Closes #678 (#683)
  • CSV import preselects the categories it already recognises, so a column that matches an existing category by name shows up chosen in the preview. By @joaolucenalima (#812) πŸŽ‰
  • Gemini through an OpenAI-compatible connection rejected tool results. Thought signatures on tool calls are kept through streaming, persistence and replay, and the /v1beta/openai path no longer gets an extra /v1. Closes #884, by @11VitorAlves11 (#889) πŸŽ‰
  • OIDC-only deployments could not remove an old 2FA or passkey. The dialogs are reachable in a remove-only mode for users who enrolled before the switch. By @ADolkun (#898) πŸŽ‰
  • Disabling 2FA blamed the code for every failure, including a wrong password. The real reason is shown, and the fields carry the right autocomplete hints. By @ADolkun (#891) πŸŽ‰
  • Leaving the login page mid-passkey prompt still spent the challenge. The ceremony is dropped when the page is gone, and the passkey button no longer flashes in on first paint. By @ADolkun (#892) πŸŽ‰
  • Helm: 502 from nginx on Kubernetes. The frontend resolves the backend by its fully qualified service name, frontend.backendUrl overrides it, and /api is routed straight to the backend in both the Ingress and the HTTPRoute. By @jorishaenseler15 (#868) πŸŽ‰

Under the hood

Migrations 086 to 089 run automatically on upgrade and add the matching rules, suggestions and history tables; nothing existing is rewritten Β· CI now fails on any pytest or ESLint warning, with the previous forty cleared, by @ADolkun (#873) πŸŽ‰ Β· the JWT expiry test uses a fake clock instead of sleeping, by @ADolkun (#893) πŸŽ‰ Β· one CI run in ten was failing on a random test because SQLite turned all-digit UUIDs into floats (#948) Β· uv moved to 0.12.15 (#858, #928), Helm to 4.3.0 (#929) and the backend dependencies were refreshed (#859, #931)

Thanks @SaikumarMadel, @vhsantos26, @DanielSuhett, @shaynhornik, @archibullo, @deeepanshu, @asankahh, @maxpricop, @7487, @rhuanbarreto, @panga, @jrvidotti, @wolfgang-aura, @joaolucenalima, @11VitorAlves11, @ADolkun and @jorishaenseler15 for the code and the reviews, and @e3mydu1f, @yikeat, @doubleOZ, @aiexpert-Azan, @kodazavr and @adheizal for the reports πŸ’œ

Full Changelog: v0.15.1...v0.16.0

Don't miss a new securo release

NewReleases is sending notifications on new releases.