Aller au contenu

Add Changelog Entry

Author a new changelog entry for the Quoi de neuf ? page in bricksoffice-projects. The entry is for non-technical end users (ops, customer-success, finance, sales). It must read like a product release note — not a commit log.

When to use

  • User asks to "add a changelog entry", "release a new version of the BO", "publish what's new", or runs /add-changelog-entry.
  • Concrete reference: projects/bricksoffice-projects/src/modules/changelog/data/entries.ts already holds the seed entry (v1.0.0, 2026-05-20). New entries are prepended so entries[0] is always the latest.

Inputs to gather (ask if not provided)

  1. Version — bumped by patch (default), minor, or major from entries[0].version. The version renders on the page as a v1.1.0 badge next to the date, AND is used as the localStorage key (bo:changelog:lastSeenVersion) so the red dot clears when the user has seen the latest entry. Don't bump package.json; the data file IS the source of truth.
  2. Release title — short headline that frames the release for the user (e.g. M5 · Virements à assigner). The team uses M<n> · prefixes internally; keep them only in the title, never in description copy.
  3. Diff scope — default is git log since the latest entry's date. The user can override with a different --since or a branch name (<branch>..HEAD).

Scope of a changelog entry

A changelog entry ships atomically with the PR that introduces it. Include changes from the current branch even if they're not yet committed — run git status --short plus a working-tree diff and treat staged-and-untracked files as in-scope. The seed v1.0.0 already followed this rule by forward-listing /virements-a-assigner before its route file landed. Only exclude truly speculative scaffolds that won't ship in this PR.

Concrete signal that the bundle ships together: the changelog data file (entries.ts) itself is uncommitted on the branch you're working on.

Procedure

1. Read the current state

  • Read src/modules/changelog/data/entries.ts.
  • Extract entries[0]version (for the bump) and date (for the git log --since cutoff). Abort if the file or array is empty.

2. Collect candidate commits

Run, scoped to paths that actually affect the BO Projects UX:

git log --no-merges --since="<latestDate>" \
  --pretty=format:'%h %s' --date=short HEAD -- \
  projects/bricksoffice-projects \
  projects/common/back-office \
  projects/common/both/api-communication-bricksoffice

If the user wants the new entry to summarise the current branch only (typical case when a feature ships from a single branch), prefer:

git log --no-merges <baseBranch>..HEAD --pretty=format:'%h %s' -- <same paths>

where <baseBranch> is develop (this app's main branch — see CLAUDE.md).

Optional context for hints:

git diff --stat <latestRef>..HEAD -- projects/bricksoffice-projects

2b. Second pass — UX wins hidden inside refactors and shared-lib changes

Commit subjects routinely undersell user-facing wins. feat(dependencies): add dnd-kit unlocks drag-reorder columns; feat(management-fees) smuggled in the DisabledTooltip primitive and the column-config UI used across every table. Always run this second pass before filtering — read the file list, not just the subject.

# Added files in BO design-system — new primitives usually map to a user-visible UX win
git log --diff-filter=A --name-only --pretty=format:'COMMIT %h %s' <latestRef>..HEAD -- \
  projects/common/back-office/src/design-system/components \
  projects/common/back-office/src/design-system/tables \
  projects/common/back-office/src/design-system/inputs \
  projects/common/back-office/src/design-system/modals

# Working tree (since the bundle ships atomically — see Scope above)
git status --short
git diff --stat HEAD -- projects/common/back-office/src/design-system projects/bricksoffice-projects

# Rule files — a new bullet in table.mdc / form.mdc / modal.mdc almost always
# reflects a user-visible affordance worth a changelog line.
git diff <latestRef>..HEAD -- .cursor/rules/bo/

Map common BO file changes to user-facing copy (extend this table over time):

BO file added/changed Surfaces as user-facing
tables/hooks/use-table-column-config.ts + dnd-kit deps Personnalisation des colonnes (glisser-déposer, épinglage, masquer, réinitialiser)
tables/hooks/use-table-page-size-persistence.ts or persistAs: arg on use-table-url-search Persistance de la taille de page par tableau
tables/hooks/use-compact.ts (module singleton replacing per-table provider) Préférence d'affichage compact/étendu persistante
tables/exporters/xlsx.* or exportTableToXlsx wired into actions-menu.tsx Export Excel (XLSX) en plus du CSV
components/disabled-tooltip.tsx Boutons désactivés plus explicites (raison au survol)
inputs/read-only-field.tsx Champs en lecture seule plus lisibles dans les modales
New cell-highlight-* / row-highlight-* utility in styles/tables.css Mise en avant visuelle des retards / valeurs anormales
New status-badge-tone-* utility in styles/badges.css Badges de statut homogènes
New modules/changelog/ or routes/_authenticated/changelog.tsx Page « Quoi de neuf ? »

3. Filter aggressively — this is for end users

Keep only commits whose effect a non-technical user can see or feel.

Conventional prefix Decision
feat: / feat(...) Keep as feature only if it changes something the user sees or does. feat(api): for a not-yet-consumed endpoint → skip.
fix: / fix(...) Keep as fix only if it's a user-facing bug. Test fixes, CI fixes, type-only fixes → skip.
perf: Keep as improvement. Frame the benefit, not the mechanism ("la liste se charge plus vite" — not "memoised the row renderer").
security fixes / CVE-driven dep bumps Keep as improvement with copy "Renforcement de la sécurité de l'application.". Never disclose the vector, the CVE id, or the package name.
refactor: Skip pure internal reshuffles (file moves, dead-code removal). Keep as improvement when the refactor re-shapes a user-visible affordance — e.g. TableCompactProvider → module-level useCompact() makes the compact preference app-wide instead of per-table, which the user feels. The 2b table is your reference.
style:, docs:, test:, ci:, chore:, build: Skip outright. Dep bumps included — except when 2b shows the dep unlocks a UX win (e.g. dnd-kit → drag-reorder columns); then keep as improvement and frame the win, not the dep.
Anything ambiguous Check the 2b table and the rule-file diffs first; if still unclear, ask the user. Better to skip than ship refactor(table): … user-facing.

For each kept feature, scan the diff for new route files under src/routes/_authenticated/:

git diff --name-only --diff-filter=A <latestRef>..HEAD -- 'projects/bricksoffice-projects/src/routes/_authenticated/*'

Map the file path to a route path:

  • src/routes/_authenticated/foo.tsxto: '/foo'
  • src/routes/_authenticated/projects/bar.tsxto: '/projects/bar'
  • src/routes/_authenticated/index.tsxto: '/'

If multiple new route files match and you can't unambiguously assign one to the feature, ask the user.

5. Rewrite each kept commit as user-facing French

For every commit that survived the filter, write:

  • label — 5–10 words in plain French. Use the domain noun ("Virements à assigner", "Échéancier"). Never quote the codebase: no module / file / endpoint / hook names, no commit hashes, no PR numbers, no English, no M5, no [BRI-...].
  • description — 1–2 sentences, ~25 words max, plain French. Subject is the user, not the codebase.
  • For feature: 1 sentence on what it is + 1 sentence on where / how. Example: "Affectez les virements reçus aux bons projets quand le rapprochement automatique n'a pas pu être fait. Accessible depuis le menu de gauche."
  • For improvement: state what changed and the benefit. Example: "Les filtres se conservent désormais entre deux visites — vous retrouvez votre vue à l'identique."
  • For fix: state what was broken and is now resolved. Don't expose the root cause. Example: "Le tri par date dans la liste des projets ne renvoyait pas le bon ordre. Corrigé."

Forbidden in user copy: "Refactor", "DataTable", "Drawer", "Sheet", "TanStack", "Query", "Mutation", endpoint names, prefix codes like M5, English verbs ("Add / Fix / Update"), commit hashes, PR numbers, file paths.

6. Compute today's date

date +%Y-%m-%d

7. Bump the version

Starting from entries[0].version:

  • patch1.0.01.0.1 (small UX fixes, polishes)
  • minor1.0.01.1.0 (a new page or substantial feature)
  • major1.0.02.0.0 (a breaking change in how users interact)

The version renders as a v<x.y.z> badge on the page, so keep it readable semver.

8. Prepend the entry

Use Edit to insert the new entry at the top of the array in src/modules/changelog/data/entries.ts, immediately before the existing first entry. Schema:

{
  version: '<bumped-version>',
  date: '<YYYY-MM-DD>',
  title: '<release title>',
  changes: [
    {
      type: 'feature',           // 'feature' | 'improvement' | 'fix'
      label: '<short headline>',
      description: '<1–2 sentences>',
      to: '<route path>',        // optional — only when a new page exists
    },
    // …more changes
  ],
},

Order inside changes: feature first, then improvement, then fix. The page renders sections in this same order, so authoring in this order keeps file diff order ≈ visual order.

9. Stop. Show the diff

Do not commit. Per CLAUDE.md: the user reviews and commits manually. Show the diff (git diff src/modules/changelog/data/entries.ts) and stop.

Worked example

Given the seed entry (v1.0.0, 2026-05-20) and a branch that ships two new pages, the "Quoi de neuf ?" page itself, AND a set of cross-cutting table improvements smuggled in via a feat(dependencies) commit (dnd-kit) plus a feat(management-fees) commit that landed DisabledTooltip and useTableColumnConfig, the skill produces:

{
  version: '1.1.0',
  date: '2026-05-21',
  title: 'Budget chantier, frais de gestion & confort des tableaux',
  changes: [
    {
      type: 'feature',
      label: 'Suivi du budget chantier',
      description:
        "Suivez les demandes de virement de budget chantier transmises par les promoteurs, et déclenchez les approbations ou les transferts vers l'échéancier en quelques clics.",
      to: '/projects/budget-chantier',
    },
    {
      type: 'feature',
      label: 'Suivi des frais de gestion',
      description:
        'Visualisez les frais de gestion à percevoir avec mise en avant des retards, et marquez les paiements reçus ou déclenchez les transferts en un clic.',
      to: '/suivi-frais-gestion',
    },
    {
      type: 'feature',
      label: 'Page « Quoi de neuf ? »',
      description:
        "Retrouvez ici l'historique des nouveautés et améliorations apportées au back-office. Un point rouge dans la sidebar signale les nouveautés à découvrir.",
      to: '/changelog',
    },
    {
      type: 'improvement',
      label: 'Personnalisation des colonnes',
      // Source: feat(dependencies) (dnd-kit) + new `useTableColumnConfig` hook in BO.
      // Surfaced by step 2b — the commit subject said nothing about columns.
      description:
        "Depuis le menu Colonnes, réorganisez les colonnes par glisser-déposer, épinglez-les à gauche ou à droite, masquez celles dont vous n'avez pas besoin, et réinitialisez l'ensemble. Le choix est mémorisé par tableau.",
    },
    {
      type: 'improvement',
      label: 'Export Excel (XLSX)',
      // Source: `exportTableToXlsx` wired into `actions-menu.tsx` (step 2b).
      description:
        "En plus de l'export CSV, vous pouvez désormais exporter chaque tableau au format Excel depuis le menu Actions.",
    },
    {
      type: 'improvement',
      label: 'Boutons désactivés plus explicites',
      // Source: new `components/disabled-tooltip.tsx` primitive (step 2b).
      description:
        "Les actions grisées affichent désormais la raison du blocage au survol — plus besoin de deviner.",
    },
  ],
},

Notice how every improvement is sourced from step 2b (file-list scan), not from the commit subjects. That's the point of the second pass — without it, this entry would have been the two pages only.

What NOT to do

  • ❌ Bump package.json version. The entries[0].version IS the source of truth for the "Nouveau" pastille.
  • ❌ Quote commit messages verbatim. They're written for the codebase, not the user.
  • ❌ Include refactor / chore / test / docs / ci / build commits, even if they "feel important" internally.
  • ❌ Disclose security vectors, CVE ids, or package names in security-flavoured entries.
  • ❌ Use English, codebase nouns (DataTable, Drawer, TanStack…), prefix codes (M5, BRI-…), commit hashes, or PR numbers in user-facing label / description.
  • ❌ Auto-commit the diff. The user reviews before any commit.
  • ❌ Hand-edit routeTree.gen.ts — the route file from the diff is enough; the plugin regenerates the tree.
  • ❌ Skip a commit because its conventional-commit subject doesn't mention the UX win (e.g. feat(dependencies) that ships drag-reorder columns, feat(management-fees) that smuggles in DisabledTooltip and useTableColumnConfig). Always run step 2b — read the file list, not just the subject.
  • ❌ Limit the entry to committed work when the changelog data file itself is uncommitted on the same branch — that's the canonical signal the whole bundle ships together. Pull in working-tree changes too.