Turn the detailed-account snapshot variant into the real per-title entry
surface (building on the minimal sub-rows from #213):
- New SecurityPicker (src/components/balance/SecurityPicker.tsx): an
autocomplete combobox over the existing balance_securities catalogue
(loaded via listSecurities()) with inline creation. Accepts any
normalized symbol (UPPER/TRIM) with NO live ticker validation — the
price fetch is best-effort and separate. On pick/create it emits a
SecurityPick {symbol, asset_type, name, isNew}; a stock/crypto toggle
lets the user set the asset class when creating a new symbol (default
'stock'). Built on the CategoryCombobox UI idiom (ARIA listbox,
keyboard nav, click-outside). Pure helpers filterSecurities /
decideCreateOption are exported and unit-tested (no jsdom harness).
- SnapshotLineRow detailed sub-rows: labeled columns
[title (SecurityPicker), quantity, price (+ existing PriceFetchControl),
value (qty x price, read-only), book_cost, live unrealized gain].
Account value = displayed SUM of positions. Simple accounts unchanged.
- useSnapshotEditor: new SET_HOLDING_SECURITY action + setHoldingSecurity
callback (atomically sets symbol + asset_type + name and drops the
stale fetched-price attribution since the symbol changed). The
securities catalogue is loaded in loadForDate and exposed as
state.securities, so it refreshes after a save that creates a security.
- i18n: extended balance.snapshot.detailed.* (col.*, picker.*, book cost,
unrealized gain) in FR + EN — no hardcoded UI text.
- CHANGELOG (EN + FR) under [Unreleased]: first user-visible surface of
the per-title detail chain (#210-#213 were schema/service/reducer).
Build (tsc + vite) green; npm test green (613 tests, +10 SecurityPicker).
Generated autonomously by /autopilot run of 2026-06-06
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>