ajout fonctions importer csv pour details en actions #245

Closed
opened 2026-07-04 20:06:07 +00:00 by maximus · 0 comments
Owner

Contexte

En snapshot d'un compte détaillé, on ajoute les titres un par un (SnapshotLineRow.tsx variante detailed + SecurityPicker). Feature : importer un CSV à la place.

Découverte clé : c'est PUREMENT FRONT. Le chemin de sauvegarde (balance.service.ts saveSnapshotAtomic -> findOrCreateSecurity + insert holdings, transactionnel, migration v14 existante) gère déjà tout. Un import = fichier -> HoldingDraft[] -> reducer -> save existant. AUCUNE migration SQL.

Décision (figée via /analyze 2026-07-04)

Détection FLEXIBLE du prix : détecter et proposer les colonnes ; si une colonne prix existe, la mapper ; sinon laisser unit_price vide et permettre le fetch ensuite (PriceFetchControl). Mapping cible : symbole -> security, quantité, prix -> unit_price (optionnel), coût -> book_cost (optionnel).

Travail à faire

  • Bouton « Importer CSV » par compte détaillé dans SnapshotLineRow.tsx (~155, à côté de « Ajouter un titre »).
  • Chaîne fichier : pick_import_file (filtre CSV) -> detect_encoding -> read_file_content -> preprocessQuotedCSV -> Papa.parse.
  • Écrire autoDetectHoldingColumns (le autoDetectConfig existant est couplé aux transactions) en réutilisant les helpers de csvAutoDetect.ts (detectDelimiter, detectHeader, detectNumericColumns) + parseFrenchAmount.
  • Mini-éditeur de mapping (symbole/quantité/prix/book_cost) inspiré de ColumnMappingEditor.tsx, avec détection flexible du prix.
  • Action reducer bulk IMPORT_HOLDINGS dans useSnapshotEditor.ts (à côté de ADD_HOLDING ~317).
  • Fusionner les symboles dupliqués à l'import (contrainte UNIQUE(snapshot_line_id, security_id)).

Fichiers concernés

  • src/components/balance/SnapshotLineRow.tsx — bouton + branchement.
  • src/hooks/useSnapshotEditor.ts — action IMPORT_HOLDINGS, mapping ligne CSV -> HoldingDraft.
  • src/utils/csvAutoDetect.ts — réutilisation helpers + nouveau autoDetectHoldingColumns.
  • src/utils/amountParser.ts (parseFrenchAmount) — réutilisé.
  • src/components/import/ColumnMappingEditor.tsx — idiome de mapping (référence).
  • src-tauri : fs_commands.rs (detect_encoding, read_file_content) + export_import_commands.rs (pick_import_file) — réutilisés tels quels.
  • src/i18n/locales/fr.json + en.json — clés balance.snapshot.detailed.importCsv.*.

Surface de test

  • balance.service.test.ts + useSnapshotEditor.test.ts couvrent le save/reducer existant.
  • csvAutoDetect n'est pas testé unitairement -> autoDetectHoldingColumns doit apporter ses tests (détection colonnes, prix présent/absent, fusion doublons, nombres FR).
  • Tester l'action IMPORT_HOLDINGS (drafts injectés -> buildDetailedLines).

Critères d'acceptation

  • Depuis un compte détaillé en snapshot, importer un CSV crée les holdings correspondants.
  • Les colonnes pertinentes sont détectées et proposées ; l'utilisateur peut ajuster le mapping.
  • Si le CSV contient un prix, il est repris ; sinon unit_price reste vide et le fetch reste possible.
  • Deux lignes CSV de même symbole sont fusionnées (pas de violation UNIQUE).
  • Clés i18n FR + EN. Entrée CHANGELOG Unreleased (Added).

Complexité : Medium

Notes autopilot

  • Indépendant côté logique ; touche fr.json/en.json (conflit i18n possible en parallèle).
  • Piège save : au pick d'un nouveau symbole, price_source/price_fetched_at sont effacés ; import sans prix -> validation snapshot_priced_unit_price_required au save sauf fetch ensuite (comportement voulu).
  • Aucune question ouverte.
## Contexte En snapshot d'un compte détaillé, on ajoute les titres un par un (`SnapshotLineRow.tsx` variante detailed + `SecurityPicker`). Feature : importer un CSV à la place. **Découverte clé : c'est PUREMENT FRONT.** Le chemin de sauvegarde (`balance.service.ts` `saveSnapshotAtomic` -> `findOrCreateSecurity` + insert holdings, transactionnel, migration v14 existante) gère déjà tout. Un import = fichier -> `HoldingDraft[]` -> reducer -> save existant. AUCUNE migration SQL. ## Décision (figée via /analyze 2026-07-04) Détection FLEXIBLE du prix : détecter et proposer les colonnes ; si une colonne prix existe, la mapper ; sinon laisser `unit_price` vide et permettre le fetch ensuite (`PriceFetchControl`). Mapping cible : symbole -> security, quantité, prix -> `unit_price` (optionnel), coût -> `book_cost` (optionnel). ## Travail à faire - [ ] Bouton « Importer CSV » par compte détaillé dans `SnapshotLineRow.tsx` (~155, à côté de « Ajouter un titre »). - [ ] Chaîne fichier : `pick_import_file` (filtre CSV) -> `detect_encoding` -> `read_file_content` -> `preprocessQuotedCSV` -> `Papa.parse`. - [ ] Écrire `autoDetectHoldingColumns` (le `autoDetectConfig` existant est couplé aux transactions) en réutilisant les helpers de `csvAutoDetect.ts` (`detectDelimiter`, `detectHeader`, `detectNumericColumns`) + `parseFrenchAmount`. - [ ] Mini-éditeur de mapping (symbole/quantité/prix/book_cost) inspiré de `ColumnMappingEditor.tsx`, avec détection flexible du prix. - [ ] Action reducer bulk `IMPORT_HOLDINGS` dans `useSnapshotEditor.ts` (à côté de `ADD_HOLDING` ~317). - [ ] Fusionner les symboles dupliqués à l'import (contrainte `UNIQUE(snapshot_line_id, security_id)`). ## Fichiers concernés - `src/components/balance/SnapshotLineRow.tsx` — bouton + branchement. - `src/hooks/useSnapshotEditor.ts` — action `IMPORT_HOLDINGS`, mapping ligne CSV -> `HoldingDraft`. - `src/utils/csvAutoDetect.ts` — réutilisation helpers + nouveau `autoDetectHoldingColumns`. - `src/utils/amountParser.ts` (`parseFrenchAmount`) — réutilisé. - `src/components/import/ColumnMappingEditor.tsx` — idiome de mapping (référence). - src-tauri : `fs_commands.rs` (`detect_encoding`, `read_file_content`) + `export_import_commands.rs` (`pick_import_file`) — réutilisés tels quels. - `src/i18n/locales/fr.json` + `en.json` — clés `balance.snapshot.detailed.importCsv.*`. ## Surface de test - `balance.service.test.ts` + `useSnapshotEditor.test.ts` couvrent le save/reducer existant. - `csvAutoDetect` n'est pas testé unitairement -> `autoDetectHoldingColumns` doit apporter ses tests (détection colonnes, prix présent/absent, fusion doublons, nombres FR). - Tester l'action `IMPORT_HOLDINGS` (drafts injectés -> `buildDetailedLines`). ## Critères d'acceptation - [ ] Depuis un compte détaillé en snapshot, importer un CSV crée les holdings correspondants. - [ ] Les colonnes pertinentes sont détectées et proposées ; l'utilisateur peut ajuster le mapping. - [ ] Si le CSV contient un prix, il est repris ; sinon `unit_price` reste vide et le fetch reste possible. - [ ] Deux lignes CSV de même symbole sont fusionnées (pas de violation UNIQUE). - [ ] Clés i18n FR + EN. Entrée CHANGELOG Unreleased (Added). ## Complexité : Medium ## Notes autopilot - Indépendant côté logique ; touche `fr.json`/`en.json` (conflit i18n possible en parallèle). - Piège save : au pick d'un nouveau symbole, `price_source`/`price_fetched_at` sont effacés ; import sans prix -> validation `snapshot_priced_unit_price_required` au save sauf fetch ensuite (comportement voulu). - Aucune question ouverte.
maximus added the
type:feature
source:human
labels 2026-07-04 20:06:07 +00:00
maximus added this to the overnight-2026-07-05-bilan-rapports-ux milestone 2026-07-04 20:45:13 +00:00
maximus added the
status:ready
label 2026-07-04 20:45:13 +00:00
maximus added
status:approved
and removed
status:ready
labels 2026-07-05 01:12:56 +00:00
Sign in to join this conversation.
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#245
No description provided.