feat(balance): SnapshotEditPage + simple-kind editor (#146) #148

Merged
maximus merged 3 commits from issue-146-bilan-1b into main 2026-04-26 13:25:16 +00:00
Owner

Closes #146

Stacked on top of #147 (Issue #138). Base branch: issue-138-bilan-1a. Once #147 is merged, this PR's base will be retargeted to main (or rebase needed).

Summary

  • Extends balance.service.ts with snapshots + lines CRUD (simple kind only — priced kind in #140)
  • New useSnapshotEditor hook (useReducer scoped) — single-snapshot lifecycle
  • New page /balance/snapshot with new/edit modes via ?date= query param
  • New components SnapshotEditor (groups by category) + SnapshotLineRow (simple variant)
  • "Prefill from previous snapshot" button — copies simple-kind values; priced-kind branch deferred to #140 (no-op + TODO comment)
  • Delete button with double-confirmation (re-type snapshot date)
  • i18n FR/EN under balance.snapshot.*
  • CHANGELOG entries (FR + EN) under [Unreleased]

Out of scope (per plan v2)

  • Priced-kind UI -> Issue #140
  • BalancePage + chart -> Issue #141
  • Sidebar entry -> Issue #141

Test plan

  • cargo check
  • npm run build
  • npm test
  • Manual verification — pending human

Generated autonomously by /autopilot run of 2026-04-25

Closes #146 > Stacked on top of #147 (Issue #138). Base branch: `issue-138-bilan-1a`. Once #147 is merged, this PR's base will be retargeted to `main` (or rebase needed). ## Summary - Extends `balance.service.ts` with snapshots + lines CRUD (simple kind only — priced kind in #140) - New `useSnapshotEditor` hook (useReducer scoped) — single-snapshot lifecycle - New page `/balance/snapshot` with new/edit modes via `?date=` query param - New components `SnapshotEditor` (groups by category) + `SnapshotLineRow` (simple variant) - "Prefill from previous snapshot" button — copies simple-kind values; priced-kind branch deferred to #140 (no-op + TODO comment) - Delete button with double-confirmation (re-type snapshot date) - i18n FR/EN under `balance.snapshot.*` - CHANGELOG entries (FR + EN) under [Unreleased] ## Out of scope (per plan v2) - Priced-kind UI -> Issue #140 - BalancePage + chart -> Issue #141 - Sidebar entry -> Issue #141 ## Test plan - [x] cargo check - [x] npm run build - [x] npm test - [ ] Manual verification — pending human Generated autonomously by /autopilot run of 2026-04-25
maximus added 3 commits 2026-04-25 18:50:25 +00:00
Adds the snapshots + lines section of the balance service for Issue #146
(Bilan #1b). Simple-kind only — quantity / unit_price are forced to NULL
both at the SQL CHECK level (already in v9) and at the service level
(`upsertSnapshotLines` validates ahead of time). Priced-kind upsert lands
in #140.

New service exports:
- listSnapshots / getSnapshotByDate / getSnapshotById / getPreviousSnapshot
- createSnapshot (throws snapshot_date_taken when UNIQUE per date violated
  so the UI can redirect to edit mode)
- updateSnapshot / deleteSnapshot (cascade lines via FK)
- listLinesBySnapshot / upsertSnapshotLines (rewrite-all strategy)

New BalanceErrorCode entries: snapshot_date_required, snapshot_date_taken,
snapshot_not_found, snapshot_value_invalid, snapshot_priced_unsupported.

New shared types: BalanceSnapshot, BalanceSnapshotLine.

22 new vitest cases cover: invalid-date guards, unique-per-date violation,
simple-kind null invariant on inserts, NaN/Infinity rejection,
clear+rewrite line semantics, getPreviousSnapshot strict-before ordering.

Refs #146

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New scoped useReducer hook covering the full single-snapshot lifecycle —
LOAD_FOR_DATE / SET_LINE_VALUE / SAVE / DELETE / PREFILL_FROM_PREVIOUS /
RESET — with the following semantics:
- 'new' mode (?date= absent or no snapshot at that date) creates the row
  at save time only, so abandoning the form does not leave an empty
  snapshot behind;
- 'edit' mode loads existing lines + prefills the values map;
- prefillFromPrevious copies simple-kind values from the most recent
  earlier snapshot (priced branch is a no-op + TODO Issue #140);
- save() flips 'new' -> 'edit' on success and updates the URL ?date=
  so refresh keeps the user in edit mode;
- snapshotDate is immutable in edit mode (UI guard, matches spec).

New SnapshotEditPage at /balance/snapshot:
- date picker (native input type=date — matches the AdjustmentForm /
  TransactionFilterBar / PeriodSelector pattern, no new dep)
- per-category groups of accounts with one value field each
- prefill button (disabled when no earlier snapshot exists, with
  tooltip explaining why)
- delete button with double-confirmation modal that requires retyping
  the snapshot date before the destructive action enables.

New SnapshotEditor (groups by category sort_order) and SnapshotLineRow
(simple variant — single value field per account) components.

Route /balance/snapshot wired in App.tsx.

Refs #146

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
feat(balance): add i18n keys + CHANGELOG entry for snapshot editor
All checks were successful
PR Check / rust (push) Successful in 21m48s
PR Check / frontend (push) Successful in 2m19s
8f5cc71707
i18n FR/EN under balance.snapshot.* — page (titles, date label and
immutability notice, total, prefill, save/create/delete buttons),
editor (empty state), line (placeholder + a11y label), delete
(double-confirm modal copy). Five new error codes added to
balance.errors.* (snapshot_date_required, snapshot_date_taken,
snapshot_not_found, snapshot_value_invalid, snapshot_priced_unsupported).

Adds common.back so the SnapshotEditPage back arrow has a localized title.

CHANGELOG entries for #146 under [Unreleased] in both EN and FR.

Refs #146

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
maximus added the
autopilot:pending-human
status:approved
labels 2026-04-25 18:50:30 +00:00
maximus changed target branch from issue-138-bilan-1a to main 2026-04-26 13:25:10 +00:00
maximus merged commit a344eab2bb into main 2026-04-26 13:25:16 +00:00
maximus deleted branch issue-146-bilan-1b 2026-04-26 13:25:16 +00:00
Sign in to join this conversation.
No reviewers
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: maximus/Simpl-Resultat#148
No description provided.