github securo-finance/securo v0.13.12

5 hours ago

This release gives the cash-flow calendar a second question to answer. It already showed what your balance will be; it now also shows how much actually came in and went out each day, with forecasts kept visually separate from settled money. Alongside that, a rule saved with a blank condition value no longer quietly matches every transaction you own, OFX 2.x statements with accented characters import instead of crashing, and CSV imports survive the ragged files real banks export while finally letting you map payee, transaction ID and notes columns. The Helm chart is now built, validated and published on every release.

Features

  • Activity mode for the cash-flow calendar. The calendar gains a Balance | Activity toggle, independent from Compact | Detailed, with Balance unchanged as the default. Balance answers "what will I have?"; Activity answers "how much moved?", which previously meant opening each day and adding rows up by hand, easy to miscount because projections sit in the same list as settled transactions. In Activity mode the trend strip becomes daily bars with income above the axis and expenses below, day cells report the real amounts that moved, and the day panel leads with the actual net. Projections are never mixed into those figures: they get their own violet line, their own dashed bars, and their own block in the panel. Transfers keep their marker and their rows but never count as income or expense. The preference persists, and switching modes never moves the selected day or your filters. Closes #484 reported by and contributed by @DannyFeliz (#485) ๐ŸŽ‰
  • Map payee, transaction ID and notes columns when importing a CSV. Bank exports carry more than a date, description and amount, but there was no way to bring the rest across. Payee and notes are auto-detected from the usual headers in English and Portuguese, and can be mapped explicitly like every other column. Transaction ID is deliberately explicit-only, never guessed, because it drives duplicate detection and a wrong guess would silently drop rows. The same import also stopped being fragile: a row with fewer columns than the header, a row with more, or an unquoted comma inside an amount each used to abort the entire import with an AttributeError, and 15.01.2026 style dates are now understood. Contributed by @jorishaenseler15 (#474) ๐ŸŽ‰
  • The transfer dialog shows which transaction is on the other side. The banner said a transaction was a transfer but never which one it was linked to, so an automatic link could not be checked without going and finding the counterpart yourself. One line now sits under the message: Linked to: Revolut ยท 26/07/2026 ยท +โ‚ฌ 300,00. Both legs share a transfer_pair_id, but TransactionRead only ever exposed the bare UUID, so a transfer-pair endpoint was added next to the existing transfer-candidates one, fetched lazily and only when the transaction is actually a transfer. Closes #453 reported by @ingridmachado (#487) ๐Ÿ™
  • Ukrainian Hryvnia. UAH is now a supported currency, with the โ‚ด symbol and uk-UA formatting, matching the interface language that already shipped. Closes #457 reported by @fx-a (#486) ๐Ÿ™

Fixes

  • A rule with a blank condition value no longer matches everything. A blank value is a tautology: "" is a substring of every string, every string starts and ends with it, an empty regex always matches, and a blank numeric value fell back to Decimal("0"), so amount greater than matched every transaction. Nothing validated it on any path, because RuleCondition.value is typed Any. An active rule saved this way recategorised the entire ledger the next time rules were applied, which is exactly what was reported. Blank and whitespace-only values are now rejected on create and update, the evaluator treats one as a non-match rather than a match if it somehow reaches it, and existing rules in this state can no longer do damage. Closes #438 reported by @mjneto (#488) ๐Ÿ™
  • OFX 2.x statements with accented characters import. ofxparse only looks for an encoding hint in the bytes before a file's first <. OFX 2.x is plain XML and has no legacy SGML header block there, so the library silently assumed ASCII and aborted the whole import with UnicodeDecodeError on the first non-ASCII byte, an upstream bug open since 2017. Any statement containing an umlaut or an accent failed, which for European exports is most of them. A synthetic header now routes those files through the decode path that works, declaring whichever encoding the content actually decoded as rather than trusting what the file claims. Files that omit the optional XML declaration entirely are covered too. Closes #479 reported by and contributed by @Jyasapara (#480) ๐ŸŽ‰
  • Asset transaction dates can be edited. PATCH /api/assets/transactions/{tx_id} rejected any request containing a date with a 422, so a transaction's date could never be corrected once entered. The schema field shadowed itself: Python binds the default before evaluating the annotation, so date: Optional[date] = None resolved to NoneType and Pydantic required the field to always be null. The service layer had always handled date changes correctly, including revalidating the position and recomputing the average price in the new order; only the schema was blocking. Closes #481 reported by and contributed by @Jyasapara (#482) ๐ŸŽ‰

Under the hood

  • The Helm chart is now built, validated and published automatically. Every pull request that touches the chart runs helm lint, helm template and kubeconform, so a chart with broken syntax or invalid Kubernetes objects cannot be merged. Every release packages it and pushes it to GHCR as an OCI artifact with the release version injected into both the image tags and the chart metadata, so the published chart deploys the images from that same release rather than latest. Installing no longer requires cloning the repository: helm install securo oci://ghcr.io/securo-finance/charts/securo --version <VERSION>. The chart is also registered on Artifact Hub. Contributed by @jorishaenseler15 (#458) ๐ŸŽ‰

Big thanks to @DannyFeliz, @Jyasapara and @jorishaenseler15 for the code, and to @mjneto, @ingridmachado and @fx-a for the reports that shaped this release ๐Ÿ’œ

Full Changelog: v0.13.11...v0.13.12

Don't miss a new securo release

NewReleases is sending notifications on new releases.