-
Simpl'Résultat v0.9.0
StableAll checks were successfulRelease / build-and-release (push) Successful in 25m25sreleased this
2026-04-29 23:20:03 +00:00 | 35 commits to main since this releaseAdded
-
Balance sheet —
asset_typecolumn on priced categories (route/balance/accounts): priced balance categories now carry an explicitasset_type(stockorcrypto) that drives PriceFetchControl provider routing without relying on symbol heuristics (e.g. ETH = Ethan Allen NYSE and Ethereum crypto are no longer ambiguous). Migration v10 adds a nullable column and backfills the two seeded priced categories (stock,crypto) with their matching values; legacy custom priced rows stay NULL until a future edit-category UI lets the user fill them in. The category creation form (Categories tab) now shows an asset-type selector whenkind = pricedand rejects submission until a value is picked. The snapshot editor hides the price-fetch button on priced rows whoseasset_typeis still NULL — manual entry remains the only path on those legacy rows. (#169) -
Balance sheet — documentation and ADRs (
docs/): closes the Bilan milestone with the documentation pass.docs/architecture.mdnow lists the 5 new tables (balance_categories,balance_accounts,balance_snapshots,balance_snapshot_lines,balance_account_transfers), the 7 new indexes, the SQL CHECK and FK invariants (CAD-only, kind invariants,RESTRICTontransaction_idfor Modified Dietz reproducibility), thebalance.service.ts4-section layout (CRUD / snapshots+lines / returns+transfers / prices), the 3 page-scoped hooks (useBalanceAccounts,useSnapshotEditor,useBalanceOverview), thecompute_account_returnTauri command (with thefetch_pricefuture-Phase-5 mention), and the 3 new/balance*routes. Three new ADRs land alongside: 0008 — Modified Dietz (justifies the choice vs. ROI / TWR / IRR with reference toreturn_calculator.rs); 0009 — Proxy price-fetching via maximus-api (architecture documented now, implementation stays BLOCKED by maximus-api Phase 2 — covers privacy considerations like header stripping, no(symbol, license)log correlation and the fixedsimpl-resultatUA, the Yahoo + CoinGecko provider abstraction, the Bearer auth strategy, the client + server rate limiting and the dual-side premium gating); 0010 — FK RESTRICT onbalance_account_transfers.transaction_id(justifies the integrity over friction trade-off for Modified Dietz reproducibility). The user guide gains a new Balance sheet section walking through snapshot entry (simple + priced), transfer linking, multi-horizon return reading (3M / 1Y / since inception with the side-by-side unadjusted column), with the price-fetching premium flagged "coming in Phase 5".docs.balance.*i18n keys (FR + EN) ship so the in-app guide reflects the new section (#145) -
Balance sheet — cross-cutting integration test suite (test infrastructure): closes out the Bilan feature with a layer of integration tests that exercise the whole TypeScript surface in a single happy-path flow (account → priced category → priced snapshot → linked transfer → return) plus dedicated assertions for currency lock (CAD-only at the MVP, rejected at both the service layer and SQL CHECK), priced-kind tolerance safety (a bad save must NOT clear pre-existing lines),
computeAccountReturnwiring (active-profile resolution, ISO date forwarding, partial-period payload pass-through). Three new Rust integration tests apply migration v9 on top of a seeded v1 schema with pre-existing transactions to verify (1) no row loss / data mutation, (2) link / unlink transfer round-trip on real transaction ids, (3) the FK RESTRICT chain (linked transaction deletion blocked, unblocked after unlink), (4) the v1categories.idand v9balance_categories.idnamespaces coexist independently. A non-regression source-level test onTransactionTable.tsxlocks down the inlined transfer icon contract: optional prop, optional-chaining short-circuit, i18n keys, aria-label, shared description-cell layout — so the page renders identically when no transfers are linked. (#144) -
Balance sheet — Modified Dietz returns and transfer linking (route
/balance): per-account performance now ships. New Rust modulecommands/return_calculator.rsimplements the Modified Dietz formulaR = (V_end − V_start − ΣCF_i) / (V_start + ΣW_i × CF_i)with day-precision contribution weightsW_i = (T − t_i) / T, plus(1 + R)^(365/T) − 1annualization. Edge cases — missing endpoint snapshot, no flows tagged in the period, account created mid-period, depleted-then-refilled, zero-length period — are surfaced with explicitis_partial/has_no_transfers_warningflags so the UI shows a clean dash + tooltip instead of a confusing number. The new Tauri commandcompute_account_return(account_id, period_start, period_end)runs three short SQL reads against the active profile DB (latest snapshot ≤ period start, latest snapshot ≤ period end, transfers JOINed with transactions filtered to the period) and feeds the calculator. Seven co-located TDD tests cover every case before the implementation. The accounts table on/balancenow shows four extra columns side-by-side: 3M / 1Y / Since-inception (Modified Dietz) plus an Unadjusted column showing the simple(V_end − V_start) / V_startso the user can see at a glance how much of the return came from contribution timing. Each row's actions menu gains a Link transfers item that opens a multi-select modal with date range / category / free-text filters; the modal auto-proposes the direction (infor negative bank amounts,outfor positive) and the user can flip it per row before submitting. Transactions linked to one or more balance accounts now show a smallLink2icon next to the description in the Transactions page, with a tooltip listing the account name(s) and direction(s). Bulk transaction-deletion paths (per-imported-file and clear-all) now pre-check for any link inbalance_account_transfersand surface a typedTransactionLinkedToBalanceError("This transaction is linked to balance account X — unlink it before deleting") instead of leaking the raw SQLite FK error. The evolution chart on/balancenow overlays vertical reference lines at every linked-transfer date (green forin, red forout). New i18n keys underbalance.returns.*,balance.accountsTable.*,balance.transfers.*,balance.evolution.*,transactions.transferIcon.*(FR + EN) (#142) -
Balance sheet —
/balanceoverview page, evolution chart and sidebar entry (route/balance): fourth slice of the Bilan feature finally surfaces it in the navigation. The new page composes (1) an overview card with the latest aggregate net worth, the Δ% versus the previous chronological snapshot (rendered as "—" when only one snapshot exists), a 60-day staleness warning when the latest snapshot is older than that threshold, and a New snapshot CTA pointing at/balance/snapshot; (2) a period selector (3 months / 6 months / 1 year / 3 years / All) that re-fetches every series in parallel; (3) an evolution chart with two modes — Line (single series ofSUM(value) GROUP BY snapshot_date) and Stacked by category (one Recharts<Area stackId>perbalance_categories.key); (4) an accounts table listing every active account with its latest snapshot value, the per-account Δ% over the active period (latest value vs the value at the earliest snapshot inside the window — null when no anchor exists, rendered as "—"), and an actions menu (Details placeholder, Archive). Return-metric columns (3M / 1Y / since-creation / unadjusted) are reserved for a later release with aTODOmarker. The sidebar now exposes the Balance sheet entry (Walleticon) between Reports and Settings. The service grows three time-series helpers:getSnapshotTotalsByDate(range?),getSnapshotTotalsByCategoryAndDate(range?),getAccountsLatestSnapshot()and a per-account anchor querygetAccountsPeriodAnchor(range)— all guarded by unit tests. NewuseBalanceOverviewhook (scopeduseReducer) drives the page state. New i18n keys underbalance.overview.*,balance.period.*,balance.chart.*plusnav.balance(FR + EN) (#141) -
Balance sheet — priced kind (quantity × unit price) (routes
/balance/accountsand/balance/snapshot): third slice of the Bilan feature. Categories now expose a kind selector at creation:simple(direct value entry) orpriced(quantity × unit_price). Accounts linked to a priced category require a symbol. The snapshot editor dispatches on the account's category kind: simple accounts keep their single value field, priced accounts get three inputs —quantity,unit_price(both required) and a read-onlyvaluefield computed live fromquantity × unit_price(rounded to 2 decimals). A[Manual]/[Manuel]attribution tag is shown on each priced row; the future[via Maximus on YYYY-MM-DD]tag will land with automatic price-fetching. The Prefill from previous button now copies quantities for priced accounts but leaves unit prices blank (a fresh price must be entered each time). The service validates priced lines ahead of the SQL CHECK: kind invariants (priced lines must carry both quantity and unit_price; simple lines must carry neither) and a value-match invariant|value − quantity × unit_price| ≤ 0.01(one cent tolerance to absorb floating-point drift). Category deletion now blocks earlier and surfaces a richer error: a category linked to one or more accounts shows a dismissable banner listing the count and up to three account names so the user knows exactly which accounts to archive first; seeded categories remain protected at the service layer with their button disabled in the UI. New i18n keysbalance.category.kind.*,balance.category.form.kindLabel/kindHint*,balance.category.error.has_accounts,balance.snapshot.priced.*(FR + EN) (#140) -
Balance sheet — snapshot editor (simple kind) (route
/balance/snapshot): second slice of the Bilan feature. The new page lets you create or edit a dated snapshot of your balance: pick a date (defaulting to today), enter the value of each active account grouped by category, and save. The mode is driven by the?date=query parameter — when a snapshot already exists at that date the page automatically flips into edit mode (the underlyingbalance_snapshots.snapshot_dateUNIQUE constraint guarantees one snapshot per day). The date of an existing snapshot is immutable: to change it, delete the snapshot and create a new one. A Prefill from previous snapshot button copies values from the most recent earlier snapshot (simple-kind accounts only — priced accounts will be handled when the priced editor lands in a later release). A Delete button surfaces a double-confirmation modal that requires retyping the snapshot date before the destructive action is enabled. Only simple-kind values are accepted at this stage (quantityandunit_priceare keptNULL); the priced editor (quantity × unit price + price fetch) ships in a later release. NewuseSnapshotEditorhook (scopeduseReducercovering the full lifecycle) and two new componentsSnapshotEditor+SnapshotLineRow. FR/EN i18n underbalance.snapshot.*(#146) -
Balance sheet — schema foundation and accounts page (route
/balance/accounts): first slice of the upcoming Bilan feature. New SQL migration v9 introduces 5 tables (balance_categories,balance_accounts,balance_snapshots,balance_snapshot_lines,balance_account_transfers) with 7 indexes and seeds 7 standard categories — Cash, TFSA, RRSP, Mutual Fund, Other (simple kind) plus Stock and Crypto (priced kind). Thecurrencycolumn is hardcoded toCADvia a CHECK constraint at the MVP ��� multi-currency support will come in a later release. The new accounts page exposes two tabs: Accounts (full CRUD over the user's holdings, soft-archive instead of hard delete to preserve historic snapshots) and Categories (rename any category, create simple-kind ones, delete user-created ones — seeded categories are protected). The full FR/EN i18n coverage uses keys underbalance.*. Snapshots, transfers, returns and the price-fetching premium remain to ship in upcoming issues; for now the route is reachable directly via URL (no sidebar entry yet) (#138) -
Price-fetching premium for stocks (best-effort) and crypto (direct exchanges) — privacy preserved via maximus-api proxy. Privacy toggle in Settings to revoke consent. (#160)
Changed
- License Ed25519 public key rotated to match the freshly deployed
maximus-apilicense server (now live athttps://api.lacompagniemaximus.com). No production licenses had been issued against the previous key, so this change is invisible to existing users — but/licenses/activatenow answers, so machine activation (Issue #53) is unblocked once this release ships. The matching private key lives only on the server (#49)
Fixed
- Category zoom report (
/reports/category): the category combobox dropdown now renders the full list in proper hierarchical DFS order — each root is emitted before its descendants, with siblings sorted bysort_orderthen display name. Previously the list was ordered bysort_orderglobally (from a SQLORDER BY sort_order, name), which interleaved parents and children from different sub-trees that shared the samesort_order, producing scrambled indentation and a mis-leading tree. Filtering (accent-insensitive search) still behaves identically (#126)
Installation
Windows : Téléchargez le fichier
.execi-dessous.
Linux : Téléchargez le fichier.debou.AppImageci-dessous.Downloads
-
Source code (ZIP)
2 downloads
-
Source code (TAR.GZ)
2 downloads
-
Simpl Resultat-0.9.0-1.x86_64.rpm
4 downloads · 9.5 MiB
-
Simpl Resultat-0.9.0-1.x86_64.rpm.sig
5 downloads · 424 B
-
Simpl Resultat_0.9.0_amd64.deb
6 downloads · 9.5 MiB
-
Simpl Resultat_0.9.0_amd64.deb.sig
5 downloads · 420 B
-
Simpl Resultat_0.9.0_x64-setup.exe
1 download · 5.2 MiB
-
Simpl Resultat_0.9.0_x64-setup.exe.sig
4 downloads · 428 B
-
latest.json
1 download · 14 KiB
-