feat: Journal before the version history in Settings → System, history folded by version (#372) #470

Open
maximus wants to merge 3 commits from issue-372-systems-journal-first into issue-449-cargo-locked
Owner

Resolves #372
Generated autonomously by /autopilot run of 2026-10-18

Résumé

Maillon 3 sur 8 de la pile planned-2026-10-16-lot-v018, basé sur issue-449-cargo-locked (PR #469).

Paramètres → Système empilait Version, Mise à jour, Historique des versions (une cinquantaine de cartes dépliées), puis Journaux : pour lire le Journal, il fallait descendre sous toute la liste des versions. Désormais :

  • SystemsSettingsPage.tsx : ordre Version, Mise à jour, Journaux et commentaires, Historique des versions, mention de sécurité des données. ChangelogContent n'est monté qu'une fois getVersion() résolu. Un rejet, jusqu'ici non géré, laisse la version inconnue : l'historique s'ouvre alors sur la première version publiée, et une ligne logWarn le dit au Journal.
  • ChangelogContent.tsx : la version installée est dépliée, les autres sont repliées derrière leur titre (un bouton dans le h3, avec aria-expanded, un chevron, aria-controls vers un conteneur toujours présent et un title traduit « Afficher / Masquer les notes de cette version ») ; un bouton « Tout déplier / Tout replier » ; « Unreleased » / « Non publié » est masqué quand il n'a aucun élément, gardé (replié) quand il a du contenu (build de dev). L'état est un Set local, en mémoire, amorcé par la règle pure à chaque lecture du fichier, donc aussi au changement de langue ; une réponse tardive de l'ancienne langue est ignorée.
  • src/utils/changelog.ts (nouveau, pur) : parseChangelog déplacé sans changement, isPublishedVersion, visibleChangelogEntries, initiallyExpandedVersions (la version installée, sinon la première version publiée quand elle est inconnue ou absente du fichier), toggleVersion, allVersionsExpanded, toggleAllVersions. UpdateCard garde sa propre lecture (pas d'unification, décision de planification).
  • SettingsHomePage.tsx : la carte Système du hub des paramètres liste les sections de la page dans le nouvel ordre (Version, Mise à jour, Journaux et commentaires, Historique des versions) ; SECTIONS est exporté pour un test qui compare l'ordre des titres de la page à celui de la carte (constat de l'auto-revue, commit 5decb98).
  • i18n FR et EN : changelog.expandAll, changelog.collapseAll, changelog.showNotes, changelog.hideNotes ; docs.settings (une fonctionnalité, une étape).
  • Docs : guide §11 (ordre de la page, repli de l'historique), docs/architecture.md (ligne /settings/systems, pourquoi un Set local plutôt que useCollapsibleGroups, compte des utilitaires), CLAUDE.md (la ligne « Changelog bilingue » décrivait /changelog comme une page d'historique complet, alors qu'elle redirige vers Paramètres → Système depuis #190), une entrée Modifié / Changed dans les deux CHANGELOG.

Critères de l'issue : le Journal est atteignable sans faire défiler l'historique ; les notes de la version installée se lisent sans clic ; l'historique complet reste accessible (titre par titre ou « Tout déplier ») ; la page ne grandit plus d'une carte dépliée par release (une ligne repliée de plus).

Fichiers

Fichier Changement
src/pages/settings/SystemsSettingsPage.tsx ordre des sections, montage de l'historique après getVersion(), rejet géré et écrit au Journal
src/components/settings/ChangelogContent.tsx repli par version, bouton tout déplier/replier, prop installedVersion, annulation d'une réponse tardive
src/utils/changelog.ts nouveau module pur : analyse et règle de dépliage
src/utils/changelog.test.ts 22 tests (analyse, règle, bascules, canari sur les vrais CHANGELOG)
src/components/settings/ChangelogContent.test.tsx 16 tests (harnais hookHarness : chargement, dépliage, clics, accessibilité, langue)
src/pages/settings/SystemsSettingsPage.test.tsx 5 tests (ordre des sections par renderToStaticMarkup, même ordre que la carte Système du hub, montage après getVersion(), échec)
src/pages/settings/SettingsHomePage.tsx puces de la carte Système dans l'ordre de la page, SECTIONS exporté
src/i18n/locales/fr.json, en.json 4 clés changelog.*, un élément de docs.settings.features et de docs.settings.steps
docs/guide-utilisateur.md §11 : une fonctionnalité, une étape (étapes suivantes renumérotées)
docs/architecture.md route /settings/systems (ordre, montage, repli, carte du hub), note sous useCollapsibleGroups, utils/ (19)
CLAUDE.md ligne « Changelog bilingue »
CHANGELOG.md, CHANGELOG.fr.md Changed / Modifié

Décisions

Toutes consignées dans reports/run-2026-10-18-lot-v018/decisions-log.md : 4 HIGH, 9 MEDIUM, 0 LOW.

  • HIGH — « Plan d'exécution » appliqué contre le corps : pas de useCollapsibleGroups, Set local amorcé par la règle pure, montage après getVersion(), parseChangelog dans src/utils/changelog.ts, UpdateCard intact.

  • MEDIUM — L'en-tête non publié se reconnaît à sa forme, pas à son libellé : une version publiée correspond à /^\d+\.\d+/. Le fichier français dit [Non publié], l'anglais [Unreleased] ; une liste de libellés casserait en silence à un renommage.

  • MEDIUM — « Vide » = aucun élément sous aucune section (couvre « aucune section » de l'issue et un ### Added laissé sans élément). Une version publiée reste toujours affichée, même sans élément.

  • MEDIUM — Accessibilité : motif accordéon (h3 > button), nom accessible = le numéro visible (Label in Name), aria-expanded, chevron aria-hidden, aria-controls vers un conteneur toujours présent (motif d'OnboardingBanner, identifiants par index car un libellé peut contenir une espace), title traduit selon l'état comme description et infobulle. Écarté : un aria-label « Notes de version : X », qui remplace le texte visible et se lit mal sur « Non publié ».

  • MEDIUM — Un seul bouton bascule (motif de BudgetTable) : « Tout déplier » tant qu'une version est repliée, « Tout replier » quand toutes sont dépliées, à la main comprise ; clés propres sous changelog.* plutôt que reports.collapse.*.

  • MEDIUM — Changement de langue : rechargement du fichier et nouvel amorçage (la version installée est de nouveau dépliée) ; drapeau d'annulation pour qu'une réponse tardive de l'ancienne langue ne remplace pas la nouvelle.

  • MEDIUM — Rejet de getVersion() : catch ajouté, version null, ligne logWarn (texte fixe plus l'erreur IPC, aucun chemin) ; la ligne de version reste vide, comme avant.

  • MEDIUM — Canari sur les vrais fichiers : les deux CHANGELOG se lisent en un en-tête non publié puis des numéros seulement (avec et sans crochets), la même liste de versions publiées en FR et en EN, et la règle ouvre exactement la version de tauri.conf.json (celle que rend getVersion()). Tient parce que /release monte la version et ajoute les deux en-têtes dans le même commit.

  • MEDIUM — Docs : deux corrections d'exactitude hors de la liste de l'issue, sur la fonction touchée, la ligne « Changelog bilingue » de CLAUDE.md (prémisse fausse qui avait égaré le corps d'origine de l'issue) et le compte de utils/ dans docs/architecture.md (16 → 19 : startupConnection et rootFiles n'avaient pas été comptés, plus changelog) ; dans le guide et docs.settings, l'étape et la fonctionnalité sont insérées juste après celles des Journaux (étapes suivantes du guide renumérotées), à l'identique en FR et en EN.

  • MEDIUM — Constat de l'auto-revue, corrigé dans 5decb98 : la carte Système du hub des paramètres listait encore l'historique avant les journaux. Puces remises dans l'ordre de la page, et un test compare l'ordre des titres de la page à celui de la carte. Écarté : un rendu séparé de SettingsHomePage (il faudrait PageHelp et un routeur, sans lier les deux ordres).

Preuves

  • Sonde : src/zz_tmp_probe.test.ts avec un expect(1).toBe(2) → npx vitest run src/zz_tmp_probe.test.ts sonde rc=1, fichier supprimé.
  • npm run build vert (tsc + vite). npm test sur la tête 5decb98 : 141 fichiers / 2348 tests verts dans le worktree, soit 3 fichiers et 43 tests de plus que la base. Aucun fichier Rust touché.
  • Mutations : implémentation commitée avant la première (92b3e54, puis 5decb98 pour H1 et la reprise de P1) ; une à la fois, restauration par git checkout --, git status --short vide après chacune.
# Fichier Mutation Tests rouges rc
R1 src/utils/changelog.ts version installée ignorée (installed = undefined) 9 / 38 1
R2 src/utils/changelog.ts repli sur la première publiée retiré 5 / 38 1
R3 src/utils/changelog.ts repli sur la première entrée (non publiée comprise) 2 / 38 1
R4 src/utils/changelog.ts « Unreleased » vide gardé (filter(() => true)) 9 / 38 1
R5 src/utils/changelog.ts toute entrée non publiée masquée, même avec du contenu 2 / 38 1
R6 src/utils/changelog.ts « vide » = aucune section (sections sans élément gardées) 1 / 38 1
R7 src/utils/changelog.ts publiée = libellé différent de Unreleased (le français échappe) 12 / 38 1
R8 src/utils/changelog.ts crochets exigés dans l'en-tête de version 9 / 38 1
R9 src/utils/changelog.ts un titre ne replie jamais sa version 3 / 38 1
R10 src/utils/changelog.ts « tout déplié » dès qu'une version l'est (some) 4 / 38 1
R11 src/utils/changelog.ts « Tout replier » ne replie jamais 2 / 38 1
C1 ChangelogContent.tsx amorce vide (tout replié à l'ouverture) 11 / 16 1
C2 ChangelogContent.tsx aria-expanded inversé 9 / 16 1
C3 ChangelogContent.tsx test d'annulation retiré (réponse tardive appliquée) 1 / 16 1
C4 ChangelogContent.tsx dépendances de l'effet [] (pas de rechargement au changement de langue) 2 / 16 1
C5 ChangelogContent.tsx notes rendues même repliées 3 / 16 1
C6 ChangelogContent.tsx clic sur un titre sans effet 3 / 16 1
C7 ChangelogContent.tsx le bouton global ne fait que déplier 1 / 16 1
C8 ChangelogContent.tsx conteneur des notes sans id (aria-controls orphelin) 1 / 16 1
C9 ChangelogContent.tsx title Afficher / Masquer inversés 1 / 16 1
P1 SystemsSettingsPage.tsx Journaux remis sous l'historique 1 / 4 (2 / 5 sur 5decb98) 1
P2 SystemsSettingsPage.tsx historique monté avant la fin de getVersion() 2 / 4 1
P3 SystemsSettingsPage.tsx rejet sans setVersion(null) (historique jamais monté) 1 / 4 1
P4 SystemsSettingsPage.tsx rejet non écrit au Journal 1 / 4 1
H1 SettingsHomePage.tsx puces de la carte Système remises dans l'ancien ordre 1 / 5 1
I1 src/i18n/locales/en.json changelog.hideNotes retiré de l'anglais seulement 1 / 8 (garde de #453) 1

Les mutations R* ont tourné sur changelog.test.ts et ChangelogContent.test.tsx (38 tests), C* sur ChangelogContent.test.tsx, P* et H1 sur SystemsSettingsPage.test.tsx, I1 sur src/i18n/locales.keys.test.ts.

Vérifications manuelles dues (prochaine release)

  1. Paramètres → Système, dans l'app lancée : les sections se suivent Version, Mise à jour, Journaux et commentaires, Historique des versions, puis la mention de sécurité des données ; la carte Journaux est visible sans faire défiler l'historique. Sur le hub Paramètres, les puces de la carte Système suivent le même ordre.
  2. Historique d'un build de release : seule la version installée est dépliée, ses notes lisibles sans clic, toutes les autres sont repliées ; aucune carte « Non publié » / « Unreleased » ([Unreleased] est vidé au tag). Dans npm run tauri dev, avec du contenu sous [Unreleased], la carte « Non publié » apparaît en tête, repliée.
  3. Bouton « Tout déplier » : il déplie toutes les versions et devient « Tout replier », qui les replie toutes ; après avoir déplié une à une toutes les versions, il affiche « Tout replier ».
  4. Clavier : Tab jusqu'au titre d'une version, Entrée puis Espace la déplient puis la replient, le focus reste visible sur le titre ; au survol, l'infobulle dit « Afficher les notes de cette version » ou « Masquer les notes de cette version » (en anglais, « Show / Hide this version's notes »).
  5. Thèmes clair et sombre : titres, chevrons et bouton lisibles, survol visible.
  6. Changement de langue depuis la barre latérale, sur cette page : l'historique se recharge dans l'autre langue et rouvre la version installée.

À regarder

  • isPublishedVersion reconnaît une version à sa forme (/^\d+\.\d+/) : un en-tête qui ne commencerait pas par un chiffre serait traité comme non publié (masqué s'il est vide, jamais pris pour « la première version publiée »). Le canari sur les vrais fichiers le vérifie pour les 51 en-têtes de version actuels, avec et sans crochets.
  • La ligne logWarn d'un rejet de getVersion() est de niveau warn : elle peut partir avec une rétroaction si l'utilisateur coche « Inclure les derniers logs d'erreur » (getRecentErrorLogs prend warn et error). Elle ne contient qu'un texte fixe et l'erreur IPC, aucun chemin ni donnée de l'utilisateur.
  • Le canari de changelog.test.ts lie la suite à la règle de /release (version et en-têtes dans le même commit) : un tag dont l'en-tête manquerait dans un des fichiers ferait rougir npm test.
  • Niveau calculé : normal (aucune ligne Haut remplie : pas d'appel réseau ajouté ni modifié, le fetch local du CHANGELOG embarqué garde son URL ; CLAUDE.md et docs/architecture.md au moins normaux).

🤖 Generated with Claude Code

Resolves #372 Generated autonomously by /autopilot run of 2026-10-18 ## Résumé Maillon 3 sur 8 de la pile `planned-2026-10-16-lot-v018`, basé sur `issue-449-cargo-locked` (PR #469). Paramètres → Système empilait Version, Mise à jour, Historique des versions (une cinquantaine de cartes dépliées), puis Journaux : pour lire le Journal, il fallait descendre sous toute la liste des versions. Désormais : - `SystemsSettingsPage.tsx` : ordre Version, Mise à jour, Journaux et commentaires, Historique des versions, mention de sécurité des données. `ChangelogContent` n'est monté qu'une fois `getVersion()` résolu. Un rejet, jusqu'ici non géré, laisse la version inconnue : l'historique s'ouvre alors sur la première version publiée, et une ligne `logWarn` le dit au Journal. - `ChangelogContent.tsx` : la version installée est dépliée, les autres sont repliées derrière leur titre (un bouton dans le `h3`, avec `aria-expanded`, un chevron, `aria-controls` vers un conteneur toujours présent et un `title` traduit « Afficher / Masquer les notes de cette version ») ; un bouton « Tout déplier / Tout replier » ; « Unreleased » / « Non publié » est masqué quand il n'a aucun élément, gardé (replié) quand il a du contenu (build de dev). L'état est un `Set` local, en mémoire, amorcé par la règle pure à chaque lecture du fichier, donc aussi au changement de langue ; une réponse tardive de l'ancienne langue est ignorée. - `src/utils/changelog.ts` (nouveau, pur) : `parseChangelog` déplacé sans changement, `isPublishedVersion`, `visibleChangelogEntries`, `initiallyExpandedVersions` (la version installée, sinon la première version publiée quand elle est inconnue ou absente du fichier), `toggleVersion`, `allVersionsExpanded`, `toggleAllVersions`. `UpdateCard` garde sa propre lecture (pas d'unification, décision de planification). - `SettingsHomePage.tsx` : la carte Système du hub des paramètres liste les sections de la page dans le nouvel ordre (Version, Mise à jour, Journaux et commentaires, Historique des versions) ; `SECTIONS` est exporté pour un test qui compare l'ordre des titres de la page à celui de la carte (constat de l'auto-revue, commit `5decb98`). - i18n FR et EN : `changelog.expandAll`, `changelog.collapseAll`, `changelog.showNotes`, `changelog.hideNotes` ; `docs.settings` (une fonctionnalité, une étape). - Docs : guide §11 (ordre de la page, repli de l'historique), `docs/architecture.md` (ligne `/settings/systems`, pourquoi un `Set` local plutôt que `useCollapsibleGroups`, compte des utilitaires), `CLAUDE.md` (la ligne « Changelog bilingue » décrivait `/changelog` comme une page d'historique complet, alors qu'elle redirige vers Paramètres → Système depuis #190), une entrée Modifié / Changed dans les deux CHANGELOG. Critères de l'issue : le Journal est atteignable sans faire défiler l'historique ; les notes de la version installée se lisent sans clic ; l'historique complet reste accessible (titre par titre ou « Tout déplier ») ; la page ne grandit plus d'une carte dépliée par release (une ligne repliée de plus). ## Fichiers | Fichier | Changement | |---|---| | `src/pages/settings/SystemsSettingsPage.tsx` | ordre des sections, montage de l'historique après `getVersion()`, rejet géré et écrit au Journal | | `src/components/settings/ChangelogContent.tsx` | repli par version, bouton tout déplier/replier, prop `installedVersion`, annulation d'une réponse tardive | | `src/utils/changelog.ts` | nouveau module pur : analyse et règle de dépliage | | `src/utils/changelog.test.ts` | 22 tests (analyse, règle, bascules, canari sur les vrais CHANGELOG) | | `src/components/settings/ChangelogContent.test.tsx` | 16 tests (harnais `hookHarness` : chargement, dépliage, clics, accessibilité, langue) | | `src/pages/settings/SystemsSettingsPage.test.tsx` | 5 tests (ordre des sections par `renderToStaticMarkup`, même ordre que la carte Système du hub, montage après `getVersion()`, échec) | | `src/pages/settings/SettingsHomePage.tsx` | puces de la carte Système dans l'ordre de la page, `SECTIONS` exporté | | `src/i18n/locales/fr.json`, `en.json` | 4 clés `changelog.*`, un élément de `docs.settings.features` et de `docs.settings.steps` | | `docs/guide-utilisateur.md` | §11 : une fonctionnalité, une étape (étapes suivantes renumérotées) | | `docs/architecture.md` | route `/settings/systems` (ordre, montage, repli, carte du hub), note sous `useCollapsibleGroups`, `utils/` (19) | | `CLAUDE.md` | ligne « Changelog bilingue » | | `CHANGELOG.md`, `CHANGELOG.fr.md` | Changed / Modifié | ## Décisions Toutes consignées dans `reports/run-2026-10-18-lot-v018/decisions-log.md` : 4 HIGH, 9 MEDIUM, 0 LOW. - **HIGH** — « Plan d'exécution » appliqué contre le corps : pas de `useCollapsibleGroups`, `Set` local amorcé par la règle pure, montage après `getVersion()`, `parseChangelog` dans `src/utils/changelog.ts`, `UpdateCard` intact. - **MEDIUM** — L'en-tête non publié se reconnaît à sa forme, pas à son libellé : une version publiée correspond à `/^\d+\.\d+/`. Le fichier français dit `[Non publié]`, l'anglais `[Unreleased]` ; une liste de libellés casserait en silence à un renommage. - **MEDIUM** — « Vide » = aucun élément sous aucune section (couvre « aucune section » de l'issue et un `### Added` laissé sans élément). Une version publiée reste toujours affichée, même sans élément. - **MEDIUM** — Accessibilité : motif accordéon (`h3 > button`), nom accessible = le numéro visible (Label in Name), `aria-expanded`, chevron `aria-hidden`, `aria-controls` vers un conteneur toujours présent (motif d'`OnboardingBanner`, identifiants par index car un libellé peut contenir une espace), `title` traduit selon l'état comme description et infobulle. Écarté : un `aria-label` « Notes de version : X », qui remplace le texte visible et se lit mal sur « Non publié ». - **MEDIUM** — Un seul bouton bascule (motif de `BudgetTable`) : « Tout déplier » tant qu'une version est repliée, « Tout replier » quand toutes sont dépliées, à la main comprise ; clés propres sous `changelog.*` plutôt que `reports.collapse.*`. - **MEDIUM** — Changement de langue : rechargement du fichier et nouvel amorçage (la version installée est de nouveau dépliée) ; drapeau d'annulation pour qu'une réponse tardive de l'ancienne langue ne remplace pas la nouvelle. - **MEDIUM** — Rejet de `getVersion()` : `catch` ajouté, version `null`, ligne `logWarn` (texte fixe plus l'erreur IPC, aucun chemin) ; la ligne de version reste vide, comme avant. - **MEDIUM** — Canari sur les vrais fichiers : les deux CHANGELOG se lisent en un en-tête non publié puis des numéros seulement (avec et sans crochets), la même liste de versions publiées en FR et en EN, et la règle ouvre exactement la version de `tauri.conf.json` (celle que rend `getVersion()`). Tient parce que `/release` monte la version et ajoute les deux en-têtes dans le même commit. - **MEDIUM** — Docs : deux corrections d'exactitude hors de la liste de l'issue, sur la fonction touchée, la ligne « Changelog bilingue » de `CLAUDE.md` (prémisse fausse qui avait égaré le corps d'origine de l'issue) et le compte de `utils/` dans `docs/architecture.md` (16 → 19 : `startupConnection` et `rootFiles` n'avaient pas été comptés, plus `changelog`) ; dans le guide et `docs.settings`, l'étape et la fonctionnalité sont insérées juste après celles des Journaux (étapes suivantes du guide renumérotées), à l'identique en FR et en EN. - **MEDIUM** — Constat de l'auto-revue, corrigé dans `5decb98` : la carte Système du hub des paramètres listait encore l'historique avant les journaux. Puces remises dans l'ordre de la page, et un test compare l'ordre des titres de la page à celui de la carte. Écarté : un rendu séparé de `SettingsHomePage` (il faudrait `PageHelp` et un routeur, sans lier les deux ordres). ## Preuves - Sonde : `src/zz_tmp_probe.test.ts` avec un `expect(1).toBe(2)` → `npx vitest run src/zz_tmp_probe.test.ts` **sonde rc=1**, fichier supprimé. - `npm run build` vert (tsc + vite). `npm test` sur la tête `5decb98` : **141 fichiers / 2348 tests** verts dans le worktree, soit 3 fichiers et 43 tests de plus que la base. Aucun fichier Rust touché. - Mutations : implémentation commitée avant la première (`92b3e54`, puis `5decb98` pour H1 et la reprise de P1) ; une à la fois, restauration par `git checkout --`, `git status --short` vide après chacune. | # | Fichier | Mutation | Tests rouges | rc | |---|---|---|---|---| | R1 | `src/utils/changelog.ts` | version installée ignorée (`installed = undefined`) | 9 / 38 | 1 | | R2 | `src/utils/changelog.ts` | repli sur la première publiée retiré | 5 / 38 | 1 | | R3 | `src/utils/changelog.ts` | repli sur la première entrée (non publiée comprise) | 2 / 38 | 1 | | R4 | `src/utils/changelog.ts` | « Unreleased » vide gardé (`filter(() => true)`) | 9 / 38 | 1 | | R5 | `src/utils/changelog.ts` | toute entrée non publiée masquée, même avec du contenu | 2 / 38 | 1 | | R6 | `src/utils/changelog.ts` | « vide » = aucune section (sections sans élément gardées) | 1 / 38 | 1 | | R7 | `src/utils/changelog.ts` | publiée = libellé différent de `Unreleased` (le français échappe) | 12 / 38 | 1 | | R8 | `src/utils/changelog.ts` | crochets exigés dans l'en-tête de version | 9 / 38 | 1 | | R9 | `src/utils/changelog.ts` | un titre ne replie jamais sa version | 3 / 38 | 1 | | R10 | `src/utils/changelog.ts` | « tout déplié » dès qu'une version l'est (`some`) | 4 / 38 | 1 | | R11 | `src/utils/changelog.ts` | « Tout replier » ne replie jamais | 2 / 38 | 1 | | C1 | `ChangelogContent.tsx` | amorce vide (tout replié à l'ouverture) | 11 / 16 | 1 | | C2 | `ChangelogContent.tsx` | `aria-expanded` inversé | 9 / 16 | 1 | | C3 | `ChangelogContent.tsx` | test d'annulation retiré (réponse tardive appliquée) | 1 / 16 | 1 | | C4 | `ChangelogContent.tsx` | dépendances de l'effet `[]` (pas de rechargement au changement de langue) | 2 / 16 | 1 | | C5 | `ChangelogContent.tsx` | notes rendues même repliées | 3 / 16 | 1 | | C6 | `ChangelogContent.tsx` | clic sur un titre sans effet | 3 / 16 | 1 | | C7 | `ChangelogContent.tsx` | le bouton global ne fait que déplier | 1 / 16 | 1 | | C8 | `ChangelogContent.tsx` | conteneur des notes sans `id` (`aria-controls` orphelin) | 1 / 16 | 1 | | C9 | `ChangelogContent.tsx` | `title` Afficher / Masquer inversés | 1 / 16 | 1 | | P1 | `SystemsSettingsPage.tsx` | Journaux remis sous l'historique | 1 / 4 (2 / 5 sur `5decb98`) | 1 | | P2 | `SystemsSettingsPage.tsx` | historique monté avant la fin de `getVersion()` | 2 / 4 | 1 | | P3 | `SystemsSettingsPage.tsx` | rejet sans `setVersion(null)` (historique jamais monté) | 1 / 4 | 1 | | P4 | `SystemsSettingsPage.tsx` | rejet non écrit au Journal | 1 / 4 | 1 | | H1 | `SettingsHomePage.tsx` | puces de la carte Système remises dans l'ancien ordre | 1 / 5 | 1 | | I1 | `src/i18n/locales/en.json` | `changelog.hideNotes` retiré de l'anglais seulement | 1 / 8 (garde de #453) | 1 | Les mutations R* ont tourné sur `changelog.test.ts` et `ChangelogContent.test.tsx` (38 tests), C* sur `ChangelogContent.test.tsx`, P* et H1 sur `SystemsSettingsPage.test.tsx`, I1 sur `src/i18n/locales.keys.test.ts`. ## Vérifications manuelles dues (prochaine release) 1. Paramètres → Système, dans l'app lancée : les sections se suivent Version, Mise à jour, Journaux et commentaires, Historique des versions, puis la mention de sécurité des données ; la carte Journaux est visible sans faire défiler l'historique. Sur le hub Paramètres, les puces de la carte Système suivent le même ordre. 2. Historique d'un build de release : seule la version installée est dépliée, ses notes lisibles sans clic, toutes les autres sont repliées ; aucune carte « Non publié » / « Unreleased » (`[Unreleased]` est vidé au tag). Dans `npm run tauri dev`, avec du contenu sous `[Unreleased]`, la carte « Non publié » apparaît en tête, repliée. 3. Bouton « Tout déplier » : il déplie toutes les versions et devient « Tout replier », qui les replie toutes ; après avoir déplié une à une toutes les versions, il affiche « Tout replier ». 4. Clavier : Tab jusqu'au titre d'une version, Entrée puis Espace la déplient puis la replient, le focus reste visible sur le titre ; au survol, l'infobulle dit « Afficher les notes de cette version » ou « Masquer les notes de cette version » (en anglais, « Show / Hide this version's notes »). 5. Thèmes clair et sombre : titres, chevrons et bouton lisibles, survol visible. 6. Changement de langue depuis la barre latérale, sur cette page : l'historique se recharge dans l'autre langue et rouvre la version installée. ## À regarder - `isPublishedVersion` reconnaît une version à sa forme (`/^\d+\.\d+/`) : un en-tête qui ne commencerait pas par un chiffre serait traité comme non publié (masqué s'il est vide, jamais pris pour « la première version publiée »). Le canari sur les vrais fichiers le vérifie pour les 51 en-têtes de version actuels, avec et sans crochets. - La ligne `logWarn` d'un rejet de `getVersion()` est de niveau warn : elle peut partir avec une rétroaction si l'utilisateur coche « Inclure les derniers logs d'erreur » (`getRecentErrorLogs` prend warn et error). Elle ne contient qu'un texte fixe et l'erreur IPC, aucun chemin ni donnée de l'utilisateur. - Le canari de `changelog.test.ts` lie la suite à la règle de `/release` (version et en-têtes dans le même commit) : un tag dont l'en-tête manquerait dans un des fichiers ferait rougir `npm test`. - Niveau calculé : normal (aucune ligne Haut remplie : pas d'appel réseau ajouté ni modifié, le `fetch` local du CHANGELOG embarqué garde son URL ; `CLAUDE.md` et `docs/architecture.md` au moins normaux). 🤖 Generated with [Claude Code](https://claude.com/claude-code)
maximus added 2 commits 2026-10-18 22:10:26 +00:00
Settings → System now orders its sections Version, Update, Logs, version
history, data notice: the Journal is reachable without scrolling past the
whole changelog, which grows at each release.

The version history opens on the installed version's notes, every other
version folded behind its title (a button with aria-expanded, a chevron and
aria-controls), with an Expand all / Collapse all button. An empty
Unreleased heading is hidden; one with content (development build) stays.
State is a local Set seeded by a pure rule, in memory only.

parseChangelog moves unchanged to src/utils/changelog.ts with the rule:
installed version unfolded, or the first published version when the
installed one is unknown or absent; a published version is told from the
Unreleased / Non publié heading by its shape, so both languages read alike.
SystemsSettingsPage mounts ChangelogContent once getVersion() settles; a
failure is written to the Journal and leaves the version unknown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
docs: describe the Systems page order and the folded version history (#372)
All checks were successful
PR Check — Frontend / frontend (pull_request) Successful in 2m2s
0513d717c7
User guide (section 11) and the in-app docs.settings keys, FR and EN: the
order of Settings → System and how the version history folds. One Changed
entry in both changelogs. docs/architecture.md: the /settings/systems row,
why ChangelogContent keeps a local Set rather than useCollapsibleGroups,
and the utils count (19: startupConnection and rootFiles were not counted).
CLAUDE.md no longer describes /changelog as a page with the full history:
it redirects to Settings → System since #190.

Resolves #372

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
maximus added the
autopilot:pending-human
label 2026-10-18 22:10:42 +00:00
maximus added 1 commit 2026-10-18 22:13:35 +00:00
fix: list the System sections on the Settings home in the page's order (#372)
All checks were successful
PR Check — Frontend / frontend (pull_request) Successful in 1m56s
5decb985f1
Self-review of PR #470: the System card of the Settings home lists the
page's sections as chips, still with the version history before the logs.
The chips now follow the page (version, update, logs, history), and a test
renders the page and compares its section headings with the card, so the
two cannot drift apart again. SECTIONS is exported for that test, as
DocsContent exports its own. The /settings/systems row of
docs/architecture.md names both unreleased headings and the card.

Resolves #372

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Author
Owner

Niveau : normal
Verdict : APPROVE

Auto-revue de l'auteur (worker /autopilot), pas une revue indépendante. Le label status:approved n'est pas posé ; l'issue reste en status:review jusqu'à un /pr-review indépendant.

Niveau (Step 0bis, REVIEW.md de main)

14 fichiers. Aucune ligne Haut remplie : pas d'appel réseau ajouté ni modifié (le fetch local du CHANGELOG embarqué garde son URL, getVersion() est l'appel IPC existant), aucun consentement touché, aucun manifeste, lock, workflow ni fichier de la racine ajouté. CLAUDE.md et docs/architecture.md restent au moins normaux ; le code de src/**, les tests et les deux locales sont normaux ; les CHANGELOG et le guide sont bas. Cas examiné : la nouvelle ligne logWarn peut partir avec une rétroaction si l'utilisateur coche l'envoi des derniers logs (getRecentErrorLogs prend warn et error) ; elle ne porte qu'un texte fixe et l'erreur IPC, aucun chemin ni donnée de l'utilisateur, et ne change pas ce que l'appel de rétroaction envoie en nature. PR : normal.

Résumé

Paramètres → Système passe à Version, Mise à jour, Journaux et commentaires, Historique des versions ; l'historique s'ouvre sur la version installée, les autres versions repliées derrière un titre-bouton, avec « Tout déplier / Tout replier » ; « Unreleased » vide masqué. Conforme au « Plan d'exécution » de l'issue (pas de useCollapsibleGroups, Set local amorcé par une règle pure, montage après getVersion(), parseChangelog déplacé sans changement dans src/utils/changelog.ts, UpdateCard intact).

Checklist

  • Sécurité : aucun secret ; le texte du CHANGELOG est rendu en texte par React (aucun dangerouslySetInnerHTML) ; aucune dépendance ajoutée.
  • Exactitude : critères de l'issue couverts (Journal atteignable sans défiler l'historique, notes de la version installée sans clic, historique complet par titre ou « Tout déplier », une ligne repliée de plus par release au lieu d'une carte dépliée). Cas limites testés : version inconnue, absente du fichier, en-tête non publié vide ou avec contenu, sections sans élément, en-têtes sans crochets, fin de ligne Windows, fichier illisible, changement de langue, réponse tardive de l'ancienne langue. Le rejet de getVersion(), jusqu'ici non géré, est attrapé (src/pages/settings/SystemsSettingsPage.tsx:21).
  • Tests : 43 tests de plus dans 3 fichiers (harnais hookHarness, faux t de src/test/i18nMock.ts, rendus par renderToStaticMarkup) ; 26 mutations, toutes rouges (tableau du corps de la PR ; P1 rejouée sur 5decb98) ; sonde rc=1 ; npm run build et npm test verts (141 fichiers / 2348 tests) sur 5decb98. Ni skip ni only.
  • Qualité et conventions : toutes les chaînes visibles par i18next, en FR et en EN (garde de #453 verte, mutation I1 rouge) ; une entrée Changed / Modifié dans les deux CHANGELOG ; guide §11, docs.settings, docs/architecture.md et CLAUDE.md à jour. Aucune migration, aucun SQL.
  • Fermeture : timeline de l'issue 372, une seule entrée pull_ref de cette PR, de type fermeture ; aucun autre verbe de fermeture dans le corps ; le mot-clé de fermeture est dans les messages de 0513d71 et 5decb98.

Constats

  1. (corrigé dans 5decb98) La carte Système du hub des paramètres listait encore ses puces dans l'ancien ordre (historique avant journaux) : src/pages/settings/SettingsHomePage.tsx:44-47. Puces remises dans l'ordre de la page ; un test de src/pages/settings/SystemsSettingsPage.test.tsx compare désormais l'ordre des titres de la page aux puces (mutation H1 rouge, P1 rouge deux fois).

Aucun constat ouvert.

Suggestions (non bloquantes)

  • src/utils/changelog.ts:64-65 : une version se reconnaît à sa forme (/^\d+\.\d+/). Un futur en-tête de version qui ne commencerait pas par un chiffre (## v1.0.0) serait pris pour un en-tête non publié ; le canari de src/utils/changelog.test.ts le signalerait sur les vrais fichiers.
  • src/utils/changelog.test.ts:197-201 : le canari lit la version de tauri.conf.json et exige son en-tête dans les deux CHANGELOG. Il tient tant que /release monte la version et ajoute les en-têtes dans le même commit ; un tag incomplet ferait rougir npm test, ce qui est voulu.
  • src/components/settings/ChangelogContent.tsx:88 : l'infobulle (title) change avec l'état, en plus d'aria-expanded. Le nom accessible reste le numéro visible (Label in Name) ; à confirmer au lecteur d'écran lors des vérifications manuelles si Max le souhaite.
  • Vérifications manuelles dans l'app lancée : listées dans le corps de la PR (ordre de la page et des puces, version installée dépliée, bouton global, clavier, deux thèmes, changement de langue).
Niveau : normal Verdict : APPROVE **Auto-revue de l'auteur (worker /autopilot), pas une revue indépendante.** Le label `status:approved` n'est pas posé ; l'issue reste en `status:review` jusqu'à un `/pr-review` indépendant. ## Niveau (Step 0bis, `REVIEW.md` de `main`) 14 fichiers. Aucune ligne Haut remplie : pas d'appel réseau ajouté ni modifié (le `fetch` local du CHANGELOG embarqué garde son URL, `getVersion()` est l'appel IPC existant), aucun consentement touché, aucun manifeste, lock, workflow ni fichier de la racine ajouté. `CLAUDE.md` et `docs/architecture.md` restent au moins normaux ; le code de `src/**`, les tests et les deux locales sont normaux ; les CHANGELOG et le guide sont bas. Cas examiné : la nouvelle ligne `logWarn` peut partir avec une rétroaction si l'utilisateur coche l'envoi des derniers logs (`getRecentErrorLogs` prend warn et error) ; elle ne porte qu'un texte fixe et l'erreur IPC, aucun chemin ni donnée de l'utilisateur, et ne change pas ce que l'appel de rétroaction envoie en nature. PR : **normal**. ## Résumé Paramètres → Système passe à Version, Mise à jour, Journaux et commentaires, Historique des versions ; l'historique s'ouvre sur la version installée, les autres versions repliées derrière un titre-bouton, avec « Tout déplier / Tout replier » ; « Unreleased » vide masqué. Conforme au « Plan d'exécution » de l'issue (pas de `useCollapsibleGroups`, `Set` local amorcé par une règle pure, montage après `getVersion()`, `parseChangelog` déplacé sans changement dans `src/utils/changelog.ts`, `UpdateCard` intact). ## Checklist - Sécurité : aucun secret ; le texte du CHANGELOG est rendu en texte par React (aucun `dangerouslySetInnerHTML`) ; aucune dépendance ajoutée. - Exactitude : critères de l'issue couverts (Journal atteignable sans défiler l'historique, notes de la version installée sans clic, historique complet par titre ou « Tout déplier », une ligne repliée de plus par release au lieu d'une carte dépliée). Cas limites testés : version inconnue, absente du fichier, en-tête non publié vide ou avec contenu, sections sans élément, en-têtes sans crochets, fin de ligne Windows, fichier illisible, changement de langue, réponse tardive de l'ancienne langue. Le rejet de `getVersion()`, jusqu'ici non géré, est attrapé (`src/pages/settings/SystemsSettingsPage.tsx:21`). - Tests : 43 tests de plus dans 3 fichiers (harnais `hookHarness`, faux `t` de `src/test/i18nMock.ts`, rendus par `renderToStaticMarkup`) ; 26 mutations, toutes rouges (tableau du corps de la PR ; P1 rejouée sur `5decb98`) ; sonde rc=1 ; `npm run build` et `npm test` verts (141 fichiers / 2348 tests) sur `5decb98`. Ni `skip` ni `only`. - Qualité et conventions : toutes les chaînes visibles par i18next, en FR et en EN (garde de #453 verte, mutation I1 rouge) ; une entrée Changed / Modifié dans les deux CHANGELOG ; guide §11, `docs.settings`, `docs/architecture.md` et `CLAUDE.md` à jour. Aucune migration, aucun SQL. - Fermeture : timeline de l'issue 372, une seule entrée `pull_ref` de cette PR, de type fermeture ; aucun autre verbe de fermeture dans le corps ; le mot-clé de fermeture est dans les messages de `0513d71` et `5decb98`. ## Constats 1. (corrigé dans `5decb98`) La carte Système du hub des paramètres listait encore ses puces dans l'ancien ordre (historique avant journaux) : `src/pages/settings/SettingsHomePage.tsx:44-47`. Puces remises dans l'ordre de la page ; un test de `src/pages/settings/SystemsSettingsPage.test.tsx` compare désormais l'ordre des titres de la page aux puces (mutation H1 rouge, P1 rouge deux fois). Aucun constat ouvert. ## Suggestions (non bloquantes) - `src/utils/changelog.ts:64-65` : une version se reconnaît à sa forme (`/^\d+\.\d+/`). Un futur en-tête de version qui ne commencerait pas par un chiffre (`## v1.0.0`) serait pris pour un en-tête non publié ; le canari de `src/utils/changelog.test.ts` le signalerait sur les vrais fichiers. - `src/utils/changelog.test.ts:197-201` : le canari lit la version de `tauri.conf.json` et exige son en-tête dans les deux CHANGELOG. Il tient tant que `/release` monte la version et ajoute les en-têtes dans le même commit ; un tag incomplet ferait rougir `npm test`, ce qui est voulu. - `src/components/settings/ChangelogContent.tsx:88` : l'infobulle (`title`) change avec l'état, en plus d'`aria-expanded`. Le nom accessible reste le numéro visible (Label in Name) ; à confirmer au lecteur d'écran lors des vérifications manuelles si Max le souhaite. - Vérifications manuelles dans l'app lancée : listées dans le corps de la PR (ordre de la page et des puces, version installée dépliée, bouton global, clavier, deux thèmes, changement de langue).
Author
Owner

CI lue par l'orchestrateur du run /autopilot du 2026-10-18 : check-frontend vert sur la tête 5decb98 (run 576).

  • vitest : 141 fichiers et 2348 tests, tous verts. Les trois nouveaux fichiers ont tourné : src/utils/changelog.test.ts (22 tests), src/components/settings/ChangelogContent.test.tsx (16) et src/pages/settings/SystemsSettingsPage.test.tsx (5). La garde src/i18n/locales.keys.test.ts (8) est aussi verte.
  • check-rust ne s'applique pas à ce maillon (aucun chemin Rust touché).
  • Incident sans effet sur le diff : le premier npm ci du worker est parti du dossier reports/ et a réinstallé les node_modules de l'arbre principal à partir de son lock, qui n'a pas changé. L'arbre principal est resté propre (git status vide).
CI lue par l'orchestrateur du run `/autopilot` du 2026-10-18 : `check-frontend` **vert** sur la tête `5decb98` (run 576). - vitest : 141 fichiers et 2348 tests, tous verts. Les trois nouveaux fichiers ont tourné : `src/utils/changelog.test.ts` (22 tests), `src/components/settings/ChangelogContent.test.tsx` (16) et `src/pages/settings/SystemsSettingsPage.test.tsx` (5). La garde `src/i18n/locales.keys.test.ts` (8) est aussi verte. - `check-rust` ne s'applique pas à ce maillon (aucun chemin Rust touché). - Incident sans effet sur le diff : le premier `npm ci` du worker est parti du dossier `reports/` et a réinstallé les `node_modules` de l'arbre principal à partir de son lock, qui n'a pas changé. L'arbre principal est resté propre (`git status` vide).
Author
Owner

Niveau : normal

Verdict : APPROVE

Résumé

Paramètres → Système passe à Version, Mise à jour, Journaux et commentaires, Historique des versions, et l'historique s'ouvre sur la version installée, les autres versions repliées derrière un titre-bouton. Le code suit le « Plan d'exécution » de #372 et tient ses critères d'acceptation ; neuf mutations du relecteur sur dix rougissent, la survivante est une épingle manquante sur un code correct (suggestion 1).

Niveau (Step 0bis, REVIEW.md de main)

14 fichiers. Code de src/** : aucune ligne Haut remplie. Le fetch de ChangelogContent garde ses deux URL locales (/CHANGELOG.fr.md, /CHANGELOG.md, servies depuis public/), aucun appel réseau n'est ajouté, et la ligne logWarn ajoutée ne change pas la forme de ce qu'envoie la rétroaction (texte fixe et erreur IPC, aucun chemin). CLAUDE.md et docs/architecture.md restent au moins normaux ; les deux CHANGELOG et le guide sont bas. Aucun fichier ajouté, renommé ni supprimé à la racine ou dans src-tauri/. PR : normal.

Ce que j'ai exécuté

Copie hors dépôt (clone local, tête 5decb98 détachée), npm ci :

  • sonde (expect(1).toBe(2)) : rc=1 ;
  • npm run build vert (tsc + vite) ;
  • npx vitest run : 141 fichiers, 2348 tests verts, le compte du corps de la PR ; journal du run 576 de check-frontend lu : tête 5decb98, Node v24.22.0, même compte, « Job succeeded » ;
  • dix mutations du relecteur, une à la fois, restaurées par git checkout -- dans la copie (git status --short vide avant et après chacune), sur les trois fichiers de test de la PR (43 tests) :
# Fichier Mutation Tests rouges
V1 ChangelogContent.tsx .catch sans le test cancelled : un échec tardif de l'ancienne langue est appliqué 0 / 43, survivante
V2 ChangelogContent.tsx amorce faite une seule fois : un rechargement (changement de langue) garde l'état déplié précédent 1 / 43
V3 ChangelogContent.tsx câblage : entrées non filtrées par visibleChangelogEntries 7 / 43
V4 ChangelogContent.tsx première carte toujours dépliée 7 / 43
V5 changelog.ts toggleVersion modifie l'ensemble reçu au lieu d'en rendre un nouveau (React ignorerait le clic) 1 / 43
V6 SystemsSettingsPage.tsx historique monté pendant getVersion(), jamais après un échec 3 / 43
V7 changelog.ts repli sur la plus ancienne entrée au lieu de la première version publiée 6 / 43
V8 src-tauri/tauri.conf.json version montée à 0.17.3 sans ses en-têtes (canari) 1 / 43
V9 CHANGELOG.fr.md en-tête [0.17.1] retiré du français seul (canari) 1 / 43
V10 ChangelogContent.tsx id des notes posé seulement quand la version est dépliée (aria-controls orphelin) 1 / 43

Checklist

  • Sécurité : aucun secret ni jeton ; le texte des CHANGELOG est rendu en texte par React (aucun dangerouslySetInnerHTML) ; aucune dépendance ajoutée (les icônes viennent de lucide-react, déjà présent).
  • Vie privée (REVIEW.md) : la ligne logWarn du rejet de getVersion() porte un texte fixe et l'erreur IPC, aucun chemin ; elle peut partir avec une rétroaction si l'utilisateur coche l'envoi des derniers logs, ce que le corps de la PR signale.
  • Exactitude : ordre de la page et des puces du hub conformes ; règle de dépliage (version installée, sinon première version publiée) ; « Non publié » / « Unreleased » masqué quand il est vide, gardé replié avec du contenu ; changement de langue avec annulation de la réponse tardive ; rejet de getVersion() désormais géré. Le Set local plutôt que useCollapsibleGroups suit la décision de Max : le hook n'a qu'un defaultExpanded global (src/hooks/useCollapsibleGroups.ts:52).
  • Tests : 43 nouveaux tests, ni skip ni only ; les tests de ChangelogContent rendent de nouveau après chaque clic, comme le harnais l'exige (piège « Tests sans jsdom ») ; le canari sur les vrais fichiers sait échouer (V8, V9).
  • i18n : quatre clés changelog.* en FR et en EN ; l'élément ajouté à docs.settings.features et à docs.settings.steps est au même rang dans les deux langues (10 et 9 éléments de chaque côté) ; garde de #453 verte dans la suite complète.
  • Documentation : guide §11 et docs.settings à jour ; docs/architecture.md exact (ligne /settings/systems, note sous useCollapsibleGroups, utils/ à 19, soit les 18 fichiers de la base plus changelog.ts) ; CLAUDE.md exact (src/pages/ChangelogPage.tsx est un <Navigate to="/settings/systems" replace />) ; une entrée Changed / Modifié dans les deux CHANGELOG.
  • Fermeture : timeline de #372, une seule entrée pull_ref de cette PR, de type closes ; #453 et #190 cités sans fermeture (none). Resolves #372 figure aussi dans les messages de 0513d71 et 5decb98 : un merge ff ferme l'issue.
  • Commits : format conventionnel (feat:, docs:, fix:), en anglais.
  • Données : aucun SQL, aucune migration.

Suggestions (non bloquantes)

  1. Épingle manquante (V1) — src/components/settings/ChangelogContent.tsx:44 : le if (!cancelled) du .catch est correct, mais aucun test ne le tient ; sans lui, les 43 tests restent verts. Cas qu'il protège : changement de langue pendant le chargement, le fichier de l'ancienne langue échoue après la réponse du nouveau, et l'historique affiche « Aucune entrée disponible » alors que le bon fichier est lu. Peu probable (fichier embarqué), donc pas de tour de revue de plus : un test calqué sur « never lets a late answer of the previous language replace the current one », avec la réponse française rejetée au lieu de résolue, suffit, dans cette PR ou en suivi.
  2. Moment du canari — src/utils/changelog.test.ts (« the real changelogs ») ne garde pas le commit de release lui-même : /release lance npm test au pré-vol, avant le bump (étape 0), et le commit de release va sur main sans PR ni CI ; une PR qui ne toucherait que les CHANGELOG ou src-tauri/ ne lance pas check-frontend non plus. Un en-tête oublié rougira donc la première PR suivante qui touche src/, sans lien avec elle (l'app, elle, retombe sur la première version publiée). Pour l'attraper au bon moment : npx vitest run src/utils/changelog.test.ts après l'étape 3 de /release. .claude/skills/release/** est de niveau haut : issue de suivi, pas dans cette PR.
  3. Libellé « Journal » — CHANGELOG.md:7 (« pushes the Journal to the bottom ») : l'interface anglaise ne dit jamais « Journal » (aucune occurrence dans en.json ; carte « Logs », section « Logs and feedback »), et ce texte s'affiche dans l'app. « the logs » se lirait mieux. Même remarque, plus légère, pour « le Journal » de CHANGELOG.fr.md:7 (carte « Journaux »). L'entrée anglaise de #395, dans la 0.17.2, emploie déjà ce mot.

Vérifications manuelles

Les six points de la section « Vérifications manuelles dues » du corps restent dus dans l'app lancée : cette revue n'a pas lancé l'app (ni thèmes, ni clavier, ni lecteur d'écran).

Actions faites

  • Copie hors dépôt /tmp/pr470-review/ supprimée en fin de revue. Reste dans /tmp un pr470-review.md qui n'est pas de cette revue : brouillon de l'auto-revue du worker /autopilot (même texte que le commentaire 25221), laissé en place.
  • Label de #372 : status:review → status:approved.
Niveau : normal **Verdict : APPROVE** ## Résumé Paramètres → Système passe à Version, Mise à jour, Journaux et commentaires, Historique des versions, et l'historique s'ouvre sur la version installée, les autres versions repliées derrière un titre-bouton. Le code suit le « Plan d'exécution » de #372 et tient ses critères d'acceptation ; neuf mutations du relecteur sur dix rougissent, la survivante est une épingle manquante sur un code correct (suggestion 1). ## Niveau (Step 0bis, `REVIEW.md` de `main`) 14 fichiers. Code de `src/**` : aucune ligne Haut remplie. Le `fetch` de `ChangelogContent` garde ses deux URL locales (`/CHANGELOG.fr.md`, `/CHANGELOG.md`, servies depuis `public/`), aucun appel réseau n'est ajouté, et la ligne `logWarn` ajoutée ne change pas la forme de ce qu'envoie la rétroaction (texte fixe et erreur IPC, aucun chemin). `CLAUDE.md` et `docs/architecture.md` restent au moins normaux ; les deux CHANGELOG et le guide sont bas. Aucun fichier ajouté, renommé ni supprimé à la racine ou dans `src-tauri/`. PR : **normal**. ## Ce que j'ai exécuté Copie hors dépôt (clone local, tête `5decb98` détachée), `npm ci` : - sonde (`expect(1).toBe(2)`) : rc=1 ; - `npm run build` vert (tsc + vite) ; - `npx vitest run` : **141 fichiers, 2348 tests verts**, le compte du corps de la PR ; journal du run 576 de `check-frontend` lu : tête `5decb98`, Node v24.22.0, même compte, « Job succeeded » ; - dix mutations du relecteur, une à la fois, restaurées par `git checkout --` dans la copie (`git status --short` vide avant et après chacune), sur les trois fichiers de test de la PR (43 tests) : | # | Fichier | Mutation | Tests rouges | |---|---|---|---| | V1 | `ChangelogContent.tsx` | `.catch` sans le test `cancelled` : un échec tardif de l'ancienne langue est appliqué | **0 / 43, survivante** | | V2 | `ChangelogContent.tsx` | amorce faite une seule fois : un rechargement (changement de langue) garde l'état déplié précédent | 1 / 43 | | V3 | `ChangelogContent.tsx` | câblage : entrées non filtrées par `visibleChangelogEntries` | 7 / 43 | | V4 | `ChangelogContent.tsx` | première carte toujours dépliée | 7 / 43 | | V5 | `changelog.ts` | `toggleVersion` modifie l'ensemble reçu au lieu d'en rendre un nouveau (React ignorerait le clic) | 1 / 43 | | V6 | `SystemsSettingsPage.tsx` | historique monté pendant `getVersion()`, jamais après un échec | 3 / 43 | | V7 | `changelog.ts` | repli sur la plus ancienne entrée au lieu de la première version publiée | 6 / 43 | | V8 | `src-tauri/tauri.conf.json` | version montée à 0.17.3 sans ses en-têtes (canari) | 1 / 43 | | V9 | `CHANGELOG.fr.md` | en-tête `[0.17.1]` retiré du français seul (canari) | 1 / 43 | | V10 | `ChangelogContent.tsx` | `id` des notes posé seulement quand la version est dépliée (`aria-controls` orphelin) | 1 / 43 | ## Checklist - **Sécurité** : aucun secret ni jeton ; le texte des CHANGELOG est rendu en texte par React (aucun `dangerouslySetInnerHTML`) ; aucune dépendance ajoutée (les icônes viennent de `lucide-react`, déjà présent). - **Vie privée** (`REVIEW.md`) : la ligne `logWarn` du rejet de `getVersion()` porte un texte fixe et l'erreur IPC, aucun chemin ; elle peut partir avec une rétroaction si l'utilisateur coche l'envoi des derniers logs, ce que le corps de la PR signale. - **Exactitude** : ordre de la page et des puces du hub conformes ; règle de dépliage (version installée, sinon première version publiée) ; « Non publié » / « Unreleased » masqué quand il est vide, gardé replié avec du contenu ; changement de langue avec annulation de la réponse tardive ; rejet de `getVersion()` désormais géré. Le `Set` local plutôt que `useCollapsibleGroups` suit la décision de Max : le hook n'a qu'un `defaultExpanded` global (`src/hooks/useCollapsibleGroups.ts:52`). - **Tests** : 43 nouveaux tests, ni `skip` ni `only` ; les tests de `ChangelogContent` rendent de nouveau après chaque clic, comme le harnais l'exige (piège « Tests sans jsdom ») ; le canari sur les vrais fichiers sait échouer (V8, V9). - **i18n** : quatre clés `changelog.*` en FR et en EN ; l'élément ajouté à `docs.settings.features` et à `docs.settings.steps` est au même rang dans les deux langues (10 et 9 éléments de chaque côté) ; garde de #453 verte dans la suite complète. - **Documentation** : guide §11 et `docs.settings` à jour ; `docs/architecture.md` exact (ligne `/settings/systems`, note sous `useCollapsibleGroups`, `utils/` à 19, soit les 18 fichiers de la base plus `changelog.ts`) ; `CLAUDE.md` exact (`src/pages/ChangelogPage.tsx` est un `<Navigate to="/settings/systems" replace />`) ; une entrée Changed / Modifié dans les deux CHANGELOG. - **Fermeture** : timeline de #372, une seule entrée `pull_ref` de cette PR, de type `closes` ; #453 et #190 cités sans fermeture (`none`). `Resolves #372` figure aussi dans les messages de `0513d71` et `5decb98` : un merge ff ferme l'issue. - **Commits** : format conventionnel (`feat:`, `docs:`, `fix:`), en anglais. - **Données** : aucun SQL, aucune migration. ## Suggestions (non bloquantes) 1. **Épingle manquante (V1)** — `src/components/settings/ChangelogContent.tsx:44` : le `if (!cancelled)` du `.catch` est correct, mais aucun test ne le tient ; sans lui, les 43 tests restent verts. Cas qu'il protège : changement de langue pendant le chargement, le fichier de l'ancienne langue échoue après la réponse du nouveau, et l'historique affiche « Aucune entrée disponible » alors que le bon fichier est lu. Peu probable (fichier embarqué), donc pas de tour de revue de plus : un test calqué sur « never lets a late answer of the previous language replace the current one », avec la réponse française rejetée au lieu de résolue, suffit, dans cette PR ou en suivi. 2. **Moment du canari** — `src/utils/changelog.test.ts` (« the real changelogs ») ne garde pas le commit de release lui-même : `/release` lance `npm test` au pré-vol, avant le bump (étape 0), et le commit de release va sur `main` sans PR ni CI ; une PR qui ne toucherait que les CHANGELOG ou `src-tauri/` ne lance pas `check-frontend` non plus. Un en-tête oublié rougira donc la première PR suivante qui touche `src/`, sans lien avec elle (l'app, elle, retombe sur la première version publiée). Pour l'attraper au bon moment : `npx vitest run src/utils/changelog.test.ts` après l'étape 3 de `/release`. `.claude/skills/release/**` est de niveau haut : issue de suivi, pas dans cette PR. 3. **Libellé « Journal »** — `CHANGELOG.md:7` (« pushes the Journal to the bottom ») : l'interface anglaise ne dit jamais « Journal » (aucune occurrence dans `en.json` ; carte « Logs », section « Logs and feedback »), et ce texte s'affiche dans l'app. « the logs » se lirait mieux. Même remarque, plus légère, pour « le Journal » de `CHANGELOG.fr.md:7` (carte « Journaux »). L'entrée anglaise de #395, dans la 0.17.2, emploie déjà ce mot. ## Vérifications manuelles Les six points de la section « Vérifications manuelles dues » du corps restent dus dans l'app lancée : cette revue n'a pas lancé l'app (ni thèmes, ni clavier, ni lecteur d'écran). ## Actions faites - Copie hors dépôt `/tmp/pr470-review/` supprimée en fin de revue. Reste dans `/tmp` un `pr470-review.md` qui n'est pas de cette revue : brouillon de l'auto-revue du worker `/autopilot` (même texte que le commentaire 25221), laissé en place. - Label de #372 : `status:review` → `status:approved`.
All checks were successful
PR Check — Frontend / frontend (pull_request) Successful in 1m56s
This pull request can be merged automatically.
You are not authorized to merge this pull request.
View command line instructions

Checkout

From your project repository, check out a new branch and test the changes.
git fetch -u origin issue-372-systems-journal-first:issue-372-systems-journal-first
git checkout issue-372-systems-journal-first

Merge

Merge the changes and update on Forgejo.
git checkout issue-449-cargo-locked
git merge --no-ff issue-372-systems-journal-first
git checkout issue-449-cargo-locked
git merge --ff-only issue-372-systems-journal-first
git checkout issue-372-systems-journal-first
git rebase issue-449-cargo-locked
git checkout issue-449-cargo-locked
git merge --no-ff issue-372-systems-journal-first
git checkout issue-449-cargo-locked
git merge --squash issue-372-systems-journal-first
git checkout issue-449-cargo-locked
git merge --ff-only issue-372-systems-journal-first
git checkout issue-449-cargo-locked
git merge issue-372-systems-journal-first
git push origin issue-449-cargo-locked
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#470
No description provided.