V41 — le site dit ce qu'il est : docs indexables, vrai 404, accueil à jour, CHANGELOG extrait du plan - #73
Merged
Conversation
…atest wave One entry per wave (V7 to V40, sub-waves included, V12 pending excluded), newest first, generated by \ pm run changelog\ from the roadmap tables. A unit test compares the committed file with the generator's output byte for byte, so the changelog cannot drift from the plan in either direction; three plan rows (V25-V27) have no rationale cell and are kept with an empty one rather than dropped. package.json (and the lockfile's root entries) now read 1.40.0 - major 1, minor = wave - which the home page will read to name the latest wave. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…ibes itself Measured on production (29 Sep 2026): the twelve /docs/<slug> URLs the sitemap advertised were served by the root fallback - the home page's title, Open Graph tags and canonical, and an empty root - so a crawler saw twelve duplicates of the home page and a shared tutorial link previewed the wrong page. Each doc page now gets its own prerendered shell (docs/<slug>.html, served at the clean URL Pages and vite preview both resolve) carrying the compiled article, its title, its summary and its canonical. The home page's description opened mid-sentence because only the highlighted half of the title was prepended; and / was the one section painting nothing before JavaScript, so index.html now carries the home hero with HomePage's exact classes. The doc shells stay out of the service worker precache (~1.5 MB the app already renders offline from its DOCS module); docs/index.html remains. shells.spec.ts now reads every URL the sitemap lists and asserts its own canonical, og:url, a unique title and an <h1> in the HTML itself. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…uting under test Measured with wrangler pages dev: the one rule in _redirects, /* /index.html 200, was INVALID and ignored - Pages strips /index.html from URLs, so the rewrite would loop - and the 200 every unknown address answered came from the default single-page fallback. A misspelled URL was a soft 404. The build now emits 404.html (served with a 404 by Pages, painting the not-found hero before JavaScript) and shell.html (the site card, an empty root, noindex), and _redirects lists only the routes that have no file of their own - a run, a comparison, a share link - rewritten to the clean URL /shell with a 200, exact sources before splats. The service worker's navigation fallback moves to shell.html so an offline run page no longer flashes the home hero. Two tests hold it together: src/app/redirects.test.ts derives the expected rule set from router.tsx and the shell routes in vite.config.ts, so a route added to one side and not the other fails; e2e/routing.spec.ts runs in a new Playwright project against wrangler pages dev, the one server that applies _redirects, _headers and 404.html the way production does - 404 on unknown addresses and missing assets, 200 on dynamic routes, the CSP actually served. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…s to the drop zone The status card said « the three modules are live » and listed them - a sentence written at V22 and untouched through the eighteen waves that followed (SQL, the local chat, forecasts, documentation, the privacy page). It is now « What's new »: a current one-paragraph map of the five areas, the latest delivered wave read from the build version (Vite define from package.json, which the changelog test pins to PLAN.md's last wave) and a link to the CHANGELOG. Both languages; HomePage.test.tsx checks the wave, the link and that the old sentence is gone. The « PS: » about dataset size leaves the /ml lede - a hero is not the place for a postscript - and becomes a short note under the drop zone, where the file arrives. The README carried the same LIMITATION line twice; once is enough. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
PLAN.md section N records V41 - six corrections to what the site said about itself, each measured on production first - and what the wave deliberately leaves aside. \ pm run changelog\ picks the row up (37 waves, version 1.41.0), so the home card now reads V41. The README counts what the suite measures today (813 unit tests, 122 e2e across four projects), says every page has a shell, lists the changelog script and points at CHANGELOG.md. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
…claims that match the code The V32 row of PLAN.md held an unescaped pipe inside inline code, so the changelog generator read four cells and published the tail of the content as the wave's rationale; the byte-for-byte test could not see it because the generator agreed with itself. The pipe is escaped (and the spacing the same defect had eaten restored), and extractWaves now refuses a wave row with more than three cells or with a status other than delivered/pending - a row skipped in silence would leave the version a wave behind with every test green - while still ignoring the benchmark tables whose rows merely mention a wave. The changelog comparison normalises line endings: a Windows checkout with autocrlf hands the committed file back as CRLF, and the test failed on every line for a \\r. Statements corrected to what the code does: _redirects said Pages served files before rules (it is the reverse - a rule must never overlap a real file); a vite.config comment still called index.html the SPA fallback; the shell eyebrow now uses <Eyebrow>'s own classes instead of a copper label the app repainted teal on mount; the README counts twelve documentation URLs, not twenty-four, and five Playwright projects, not four. One French sentence on the drop zone reads like French now. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Copilot review overview
🟡 Changes recommended
The service-worker fallback restores soft 404s for controlled clients, and several new guarantees are inaccurate or incompletely enforced.
Review effort: Balanced
Findings: 2
Open (4)
What changed in this PR
Adds accurate prerendering, routing metadata, 404 handling, and an automatically generated changelog.
Changes:
- Prerenders home and documentation pages with page-specific metadata.
- Adds Cloudflare Pages routing and 404 tests.
- Generates
CHANGELOG.mdand synchronizes the application version.
| File | Description |
|---|---|
vite.config.ts |
Generates shells, metadata, sitemap, and PWA fallback. |
src/types/app.d.ts |
Declares the injected application version. |
src/locales/fr.json |
Updates French status and upload guidance. |
src/locales/en.json |
Updates English status and upload guidance. |
src/lib/changelog.test.ts |
Tests changelog generation and version synchronization. |
src/features/ml/components/DropZone.tsx |
Displays dataset-size guidance. |
src/features/home/HomePage.tsx |
Adds current-wave and changelog information. |
src/features/home/HomePage.test.tsx |
Tests the updated status card. |
src/app/redirects.test.ts |
Validates redirects against application routes. |
scripts/changelog.mjs |
Generates the changelog and synchronizes versions. |
scripts/changelog.d.mts |
Types the changelog module. |
README.md |
Updates capabilities, test counts, and scripts. |
public/_redirects |
Replaces the catch-all with dynamic-route rewrites. |
playwright.config.ts |
Adds Cloudflare Pages routing tests. |
PLAN.md |
Records V41 and repairs the V32 table row. |
package.json |
Updates version and adds the changelog script. |
package-lock.json |
Synchronizes the root package version. |
e2e/shells.spec.ts |
Verifies sitemap-page metadata and prerendering. |
e2e/routing.spec.ts |
Tests production-like routing, 404s, and headers. |
CHANGELOG.md |
Adds the generated delivery history. |
.prettierignore |
Excludes generated changelog formatting. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+65
to
+73
| if (head[2] === 'pending') continue; | ||
| // An unescaped pipe inside a cell splits the row and turns the tail of the | ||
| // content into the « why » — measured on the V32 row, whose inline code | ||
| // held one. The byte-for-byte test cannot see it, so the generator refuses. | ||
| if (cells.length > 3) { | ||
| throw new Error( | ||
| `PLAN.md: wave V${head[1]} has ${cells.length} cells — an unescaped | inside a cell? Write it as \\|`, | ||
| ); | ||
| } |
| ], | ||
| // V41 — the bare shell, not the home page: offline, a run or a share | ||
| // link must not flash the home hero for a frame before the app mounts. | ||
| navigateFallback: '/shell.html', |
| "noRequests": "runs locally · no requests", | ||
| "dropTitle": "Drop a CSV or Excel file", | ||
| "dropHint": "or click to browse — the file is read right here in your browser, nothing is uploaded", | ||
| "sizeNote": "Ideal size: 1–30 MB. Larger files still train, but the browser takes longer to answer.", |
| "noRequests": "exécution locale · aucune requête", | ||
| "dropTitle": "Déposez un fichier CSV ou Excel", | ||
| "dropHint": "ou cliquez pour parcourir — le fichier est lu ici même, dans votre navigateur ; rien n'est téléversé", | ||
| "sizeNote": "Taille idéale : 1 à 30 Mo. Au-delà, l'entraînement fonctionne quand même, mais le navigateur met plus de temps à répondre.", |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.


Pourquoi
Analyse du dépôt et du site en production (29/09/2026,
curl). Rien à redire au labo lui-même ; en revanche, ce que le site déclare de lui-même ne correspondait plus à ce qu'il est :/docs/<slug>annoncées par le sitemap étaient servies par le fallback racine : titre et Open Graph de l'accueil, canonical pointant vers/,<div id="root">vide. Pour un moteur de recherche, douze doublons de l'accueil ; pour un lien de tutoriel partagé, l'aperçu de la mauvaise page.wrangler pages devrévèle que la seule règle de_redirects(/* /index.html 200) était invalide et ignorée par Pages ; le 200 venait du fallback SPA par défaut.package.jsonétait à1.0.0.Ce que fait la PR
dist/docs/<slug>.html, article compilé, titre, résumé, canonical propre)shells.spec.ts: chaque URL du sitemap répond avec sa canonical, un titre unique et un<h1>sans JavaScript404.html,shell.htmlnu (noindex) pour les routes dynamiques,_redirectslimité aux quatre routes sans fichier propre, fallback du service worker surshell.html, héros de l'accueil dansindex.htmlredirects.test.ts(dérive la liste attendue derouter.tsx) ; nouveau projet Playwrightpagesqui rejouerouting.spec.tscontrewrangler pages dev— le seul serveur qui applique_redirects,_headerset404.htmlcomme la prodHomePage.test.tsx/mlpour la zone de dépôt ; doublon LIMITATION retiré du READMECHANGELOG.mdextrait de PLAN.md (npm run changelog, 37 vagues),package.jsonaligné sur1.<vague>.0changelog.test.ts: comparaison octet par octet, version épinglée à la dernière vagueDétails et mesures dans la ligne V41 de PLAN.md §N.
Ce que la relecture a rattrapé
Une relecture indépendante de la branche a trouvé deux points importants, corrigés dans le dernier commit :
|non échappé dans du code inline ; le générateur lisait quatre cellules et publiait un fragment du contenu comme raison de la vague. Le pipe est échappé, et le générateur refuse désormais toute ligne de vague à plus de trois cellules ou au statut inconnu, plutôt que de la sauter en silence.Plus quelques énoncés remis d'aplomb : l'ordre réel de Pages (les règles avant les fichiers — une règle ne doit jamais recouvrir un fichier existant), l'eyebrow des coquilles aligné sur le composant
<Eyebrow>(il était cuivre depuis V9 et repeint en teal au montage), les compteurs du README.À vérifier sur la preview avant de fusionner
Mesures
817 tests unitaires (+29), 122 e2e (+11, dont le projet
pages), build et Lighthouse inchangés. Précache du service worker : 97 entrées (+1,shell.html) — les douze coquilles de doc en sont exclues (~1,5 Mo évités, l'app les rend déjà hors-ligne depuis son moduleDOCS).Volontairement laissé de côté
Traduire le CHANGELOG (les titres sont ceux du journal, en anglais — la carte n'affiche que le numéro), prérendre la doc en français (les coquilles sont anglaises comme les sections ; l'app bascule au montage), ajouter des
hreflang(la langue est celle de l'app, pas de l'URL). Quelques points mineurs de la relecture sont notés dans la conversation de session et peuvent faire l'objet d'un suivi.