diff --git a/CHANGELOG.fr.md b/CHANGELOG.fr.md index 7415247..d59f703 100644 --- a/CHANGELOG.fr.md +++ b/CHANGELOG.fr.md @@ -3,6 +3,7 @@ ## [Non publié] ### Ajouté +- **Bilan — éditeur de snapshot (type simple)** (route `/balance/snapshot`) : deuxième tranche de la feature *Bilan*. La nouvelle page permet de créer ou modifier un snapshot daté de votre patrimoine : choisissez une date (par défaut aujourd'hui), saisissez la valeur de chaque compte actif groupé par catégorie, puis enregistrez. Le mode est piloté par le paramètre `?date=` de l'URL — si un snapshot existe déjà à cette date, la page bascule automatiquement en mode édition (la contrainte UNIQUE sur `balance_snapshots.snapshot_date` garantit un snapshot par jour). La date d'un snapshot existant est immuable : pour la changer, supprimez puis recréez. Un bouton *Pré-remplir depuis le précédent* copie les valeurs du snapshot antérieur le plus récent (comptes simples uniquement — les comptes cotés seront pris en charge quand l'éditeur coté arrivera). Un bouton *Supprimer* affiche une modal de double confirmation qui exige de retaper la date du snapshot avant d'activer l'action destructive. Seules les valeurs de type simple sont acceptées à ce stade (`quantity` et `unit_price` sont laissés `NULL`) ; l'éditeur coté (quantité × prix unitaire + récupération de prix) arrivera dans une prochaine version. Nouveau hook `useSnapshotEditor` (`useReducer` couvrant tout le cycle de vie) et deux nouveaux composants `SnapshotEditor` + `SnapshotLineRow`. i18n FR/EN sous `balance.snapshot.*` (#146) - **Bilan — fondations du schéma et page Comptes** (route `/balance/accounts`) : première tranche de la nouvelle feature *Bilan*. La migration SQL v9 introduit 5 tables (`balance_categories`, `balance_accounts`, `balance_snapshots`, `balance_snapshot_lines`, `balance_account_transfers`) avec 7 index et seede 7 catégories standard — Encaisse, CELI, REER, Fonds commun, Autre (type simple) + Action et Cryptomonnaie (type coté). La colonne `currency` est verrouillée à `CAD` via une contrainte CHECK au MVP — le support multi-devises arrivera plus tard. La nouvelle page expose deux onglets : *Comptes* (CRUD complet sur les comptes de l'utilisateur, archivage soft plutôt que suppression dure pour préserver les snapshots historiques) et *Catégories* (renommer une catégorie, créer des catégories de type simple, supprimer celles créées par l'utilisateur — les catégories standard sont protégées). Couverture i18n FR/EN complète sous `balance.*`. Snapshots, transferts, rendements et price-fetching premium arriveront dans les prochaines issues ; pour l'instant la route est accessible directement par URL (pas encore d'entrée sidebar) (#138) ### Corrigé diff --git a/CHANGELOG.md b/CHANGELOG.md index 66f4e04..0274106 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## [Unreleased] ### Added +- **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 underlying `balance_snapshots.snapshot_date` UNIQUE 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 (`quantity` and `unit_price` are kept `NULL`); the priced editor (quantity × unit price + price fetch) ships in a later release. New `useSnapshotEditor` hook (scoped `useReducer` covering the full lifecycle) and two new components `SnapshotEditor` + `SnapshotLineRow`. FR/EN i18n under `balance.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). The `currency` column is hardcoded to `CAD` via 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 under `balance.*`. 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) ### Fixed diff --git a/src/i18n/locales/en.json b/src/i18n/locales/en.json index 7a1f03a..2f52ba9 100644 --- a/src/i18n/locales/en.json +++ b/src/i18n/locales/en.json @@ -981,7 +981,8 @@ "darkMode": "Dark mode", "lightMode": "Light mode", "close": "Close", - "underConstruction": "Under construction" + "underConstruction": "Under construction", + "back": "Back" }, "license": { "title": "License", @@ -1535,6 +1536,36 @@ "stock": "Stock", "crypto": "Crypto" }, + "snapshot": { + "page": { + "newTitle": "New snapshot", + "editTitle": "Edit snapshot", + "dateLabel": "Snapshot date", + "dateImmutable": "An existing snapshot date cannot be changed. To change the date, delete this snapshot and create a new one.", + "total": "Entered total", + "noAccounts": "You need to create at least one balance account first.", + "goToAccounts": "Go to accounts", + "prefill": "Prefill from previous", + "prefillTooltip": "Copy values from the snapshot dated {{date}}", + "prefillNoPrevious": "No earlier snapshot available.", + "save": "Save", + "create": "Create snapshot", + "delete": "Delete this snapshot" + }, + "editor": { + "empty": "No active accounts. Create an account before entering a snapshot." + }, + "line": { + "valuePlaceholder": "0.00", + "valueLabel": "Value for {{account}}" + }, + "delete": { + "title": "Delete this snapshot?", + "body": "This permanently deletes the snapshot dated {{date}} and all its lines. To confirm, retype the date below.", + "confirmLabel": "Retype the date {{date}} to confirm", + "confirm": "Delete permanently" + } + }, "errors": { "currency_unsupported": "Only CAD is supported at the MVP.", "category_seed_protected": "Standard categories cannot be deleted.", @@ -1542,7 +1573,12 @@ "category_not_found": "Category not found.", "account_not_found": "Account not found.", "name_required": "Name is required.", - "kind_invalid": "Invalid category kind." + "kind_invalid": "Invalid category kind.", + "snapshot_date_required": "A date in YYYY-MM-DD format is required.", + "snapshot_date_taken": "A snapshot already exists at that date — edit it instead of creating a new one.", + "snapshot_not_found": "Snapshot not found.", + "snapshot_value_invalid": "An entered value is not a valid number.", + "snapshot_priced_unsupported": "Priced accounts (stocks/crypto) will be supported in a future release." } } } diff --git a/src/i18n/locales/fr.json b/src/i18n/locales/fr.json index d5b5f8a..2a777ff 100644 --- a/src/i18n/locales/fr.json +++ b/src/i18n/locales/fr.json @@ -981,7 +981,8 @@ "darkMode": "Mode sombre", "lightMode": "Mode clair", "close": "Fermer", - "underConstruction": "En construction" + "underConstruction": "En construction", + "back": "Retour" }, "license": { "title": "Licence", @@ -1535,6 +1536,36 @@ "stock": "Action", "crypto": "Cryptomonnaie" }, + "snapshot": { + "page": { + "newTitle": "Nouveau snapshot", + "editTitle": "Modifier le snapshot", + "dateLabel": "Date du snapshot", + "dateImmutable": "La date d'un snapshot existant ne peut pas être modifiée. Pour changer la date, supprimez ce snapshot et créez-en un nouveau.", + "total": "Total saisi", + "noAccounts": "Vous devez d'abord créer au moins un compte de bilan.", + "goToAccounts": "Aller aux comptes", + "prefill": "Pré-remplir depuis le précédent", + "prefillTooltip": "Copier les valeurs du snapshot du {{date}}", + "prefillNoPrevious": "Aucun snapshot antérieur disponible.", + "save": "Enregistrer", + "create": "Créer le snapshot", + "delete": "Supprimer ce snapshot" + }, + "editor": { + "empty": "Aucun compte actif. Créez un compte avant de saisir un snapshot." + }, + "line": { + "valuePlaceholder": "0,00", + "valueLabel": "Valeur pour {{account}}" + }, + "delete": { + "title": "Supprimer ce snapshot ?", + "body": "Cette action supprime définitivement le snapshot du {{date}} et toutes ses lignes. Pour confirmer, retapez la date ci-dessous.", + "confirmLabel": "Retapez la date {{date}} pour confirmer", + "confirm": "Supprimer définitivement" + } + }, "errors": { "currency_unsupported": "Seul le CAD est supporté au MVP.", "category_seed_protected": "Les catégories standard ne peuvent pas être supprimées.", @@ -1542,7 +1573,12 @@ "category_not_found": "Catégorie introuvable.", "account_not_found": "Compte introuvable.", "name_required": "Le nom est obligatoire.", - "kind_invalid": "Type de catégorie invalide." + "kind_invalid": "Type de catégorie invalide.", + "snapshot_date_required": "Une date au format AAAA-MM-JJ est obligatoire.", + "snapshot_date_taken": "Un snapshot existe déjà à cette date — modifiez-le au lieu d'en créer un nouveau.", + "snapshot_not_found": "Snapshot introuvable.", + "snapshot_value_invalid": "Une valeur saisie n'est pas un nombre valide.", + "snapshot_priced_unsupported": "Les comptes cotés (actions/crypto) seront supportés dans une prochaine version." } } }