Traduction de l'application #4
Labels
No labels
bug
duplicate
enhancement
help wanted
invalid
priority
high
priority
low
priority
medium
question
step
backlog
step
delivered
step
done
step
in-progress
step
todo
wontfix
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
maxime/OrganisateurFamilial#4
Loading…
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Description
Gérer le multilingue français/anglais de l’application avec
@nextcloud/l10nettranslationtool.L’application suit la langue du compte Nextcloud après rechargement, sans réglage propre à l’ExApp. Couvrir l’interface et l’accessibilité, les formats de dates, les erreurs/validations/avertissements API, les notifications et rappels, ainsi que le mode hors ligne et le manifeste. Les données des familles, identifiants, routes et formats d’échange restent inchangés. Sources anglaises, catalogue français complet, anglais de secours.
Conception terminée le 6 septembre 2026 ; développement non commencé. Le guide technique détaillé contient les décisions, les fichiers concernés, les contrats internes, les dépendances entre lots, les critères de validation et les pièges AppAPI vérifiés sur l’instance locale. Il permet de reprendre ce ticket sans le contexte de la conversation.
Plan d'action
Recette
fetch()ni sous-ressource.make l10n-check,make lint typecheck test,make build-frontendet la vérification IIFE, puiscd e2e && npm test; tests de dates hors UTC et build de l’image de production.branch-reviewet revue prévue par Workflow ; consigner et corriger les retours dans le ticket.Plan de MEP
1.0.xune livraison cohérente : image Node, frontend/worker, catalogues et archive AppAPI ; ne pas publier à l’App Store dans ce ticket.Conception technique — ticket #4
Plan préparé le 6 septembre 2026 sur
main, commitc6748b2. Ce commentaire est le guide d’exécution ; les cases du corps du ticket suivent l’avancement. Aucun développement n’a été effectué pendant cette conception.1. Comportement attendu et limites
fr,fr_FR,fr-CAsélectionnent le français ;en,en_GB,en-USl’anglais. Une langue non prise en charge ne doit ni casser l’application ni créer de requêtes en boucle.kinddans l’application ; les titres des abonnements restent des données. Aucun renommage de masse, aucune migration SQL, aucun déclenchement de reprojection lié à un changement de langue.translationtoolest un outil local/de CI ; PHP/gettext ne sont que des dépendances de construction, jamais du runtime Node.Cette évolution remplace, dans le périmètre i18n, la règle actuelle « toute chaîne utilisateur en français » par « sources anglaises extractibles + catalogue français complet ». Conserver l’anglais pour le code, les tests, les commentaires et les nouvelles sections du wiki.
2. État existant et preuves à connaître
ex_app/src/main.ts, dépendance@nextcloud/l10ndéjà installée (API v3)t/nglobaux servent déjà les composants Nextcloud, mais les chaînes applicatives sont en dur. Ne pas installer vue-i18n.ex_app/l10n/README.mduniquementservices/format.ts,services/relative-day.ts,constants/*.tscôté frontendLOCALE = 'fr-FR', libellés et pluriels à remplacer.ex_app/lib/src/errors.ts,routes/*-schema.ts, schémas dans les routes,services/access.tsmessageetissues[].messagetels quels. Beaucoup de validations Zod n’ont pas de message explicite.services/notification.ts,list.ts,shopping.ts,reminder.ts,transfer-import.ts,ocs/client.tsoffline/shell.html,sw.ts,services/offline-snapshot.ts,offline-prefetch.tsDockerfile,compose.yaml,dev/setup.sh,Makefileex_app/l10n, mais cela ne fournit pas les catalogues à Nextcloud.Vérifié en lecture seule dans AppAPI installé sur la stack Nextcloud 34 :
lib/Service/AppAPIService.php::prepareRequestToExApprenseigneAccept-Languagevial10nFactory->findLanguage(appId)si absent. Exploiter cet en-tête pour les réponses Node ; ne pas ajouter un appel OCS de préférence à chaque requête.lib/Notifications/ExAppNotifier.php::prepareobtient le catalogue de l’ExApp avec la langue du destinataire, traduitrich_subjectpuis appliquerich_subject_params. Envoyer une clé anglaise non traduite et des paramètres riches ; ne pas traduire avec la langue de l’auteur et ne pas rechercher la langue de tous les membres.lib/Listener/LoadMenuEntriesListener.phppasse aussi le display name du menu dans le catalogue de l’ExApp.lib/Fetcher/ExAppArchiveFetcher.php::installTranslationsinstalle les catalogues sur Nextcloud. Enmanual-install, fournir explicitement<writable-apps>/organisateur_familial/l10n/. N’y copier aucunappinfo/info.xml: Nextcloud pourrait prendre le dossier pour une app PHP.Références : traductions AppAPI, API @nextcloud/l10n, translationtool, source de l’extracteur. Lire aussi le wiki Architecture (D19, D26, D31–D37), Workflow, Code guidelines et le skill
nextcloud-exapp-dev.3. Décisions d’implémentation
A. Une chaîne de génération, un catalogue commun
Le domaine est littéralement
organisateur_familial. Frontend :import { translate as t, translatePlural as n } from '@nextcloud/l10n', puist('organisateur_familial', 'Lists')etn('organisateur_familial', '%n item remaining', '%n items remaining', count). Ne pas utilisert(domain, variable)pour des textes sources ; les appels doivent porter les littéraux extractibles. Utiliser des phrases complètes et des paramètres nommés, jamais des morceaux concaténés ourestant(s).Conserver
ex_app/l10n/{fr.js,fr.json}comme sorties distribuées ; l’anglais fonctionne comme langue source. Un catalogue anglais explicite peut être généré si le packaging l’exige, sans entretenir une deuxième traduction identique. Sources PO :translationfiles/fr/organisateur_familial.po, modèletranslationfiles/templates/organisateur_familial.pot, à la racine du dépôt.L’extracteur officiel reconnaît
.ts,.htmlet prépare les.vue, avect:2etn:2,3. Il découvre les apps par leur dossierl10net attend leurappinfo/info.xmlau même niveau. La disposition actuelle du dépôt ne correspond pas à ce layout. Ajouter un script de staging dansdev/: construire un dossier temporaireorganisateur_familial/avecappinfo/info.xml,l10n/, les sources frontend/backend utiles et les PO ; y lancer les deux commandes officielles ; recopier uniquement les sorties prévues. Exclure node_modules, dist, tests, e2e et fichiers générés. Ne pas créer plusieurs racines d’app détectables dans le staging.Épingler le PHAR officiel par commit et somme SHA-256 et le runtime PHP/gettext par une version reproductible. Aucun téléchargement pendant le fonctionnement de l’application. Ajouter
make l10n-extract,make l10n-build,make l10n-check. Le dernier régénère dans un temporaire, compare les contenus (normaliser uniquement les métadonnées volatiles du POT), vérifie les placeholders/pluriels et refuse les entrées françaises vides/fuzzy. Un test d’extraction doit prouver que Vue, TS backend, notifications et hors ligne figurent dans le POT.B. Frontend et formatage
Utiliser les catalogues injectés par Nextcloud. Vérifier qu’ils sont enregistrés avant l’évaluation des constantes contenant
t(...). Si ce n’est pas le cas sur la version testée, déplacer l’évaluation dans les fonctions/computed utilisées après initialisation ; ne pas introduire un import dynamique qui casse l’IIFE. Conserver les globalst/nattendus par@nextcloud/vue.Les vocabulaires restent centralisés dans
constants/lists.ts,meals.ts,calendars.ts, etc. Pour un décompte, exposer une fonction prenant le nombre et appelantnavec des sources littérales par kind ; ne pas garder un suffixe grammatical dansremaining. Traduire attributs accessibles et messages des stores/composables autant que les templates. Vue doit afficher les paramètres comme du texte : tester&, apostrophes et<...>afin d’éviter double échappement ou XSS ; pas dev-htmlpour une phrase traduite.Dans
services/format.ts, remplacer la constante fixe pargetCanonicalLocale()(disponible dans la dépendance installée), avec validation/repli de locale. Inclure la locale dans la clé du cache des formatteurs. GarderformatDay(... timeZone: 'UTC')pour les jours nus et le fuseau local pour les instants.relative-day.tsfournit des libellést(...). Aucun parsing de dates localisées ; ISO reste le format de stockage et d’échange.C. Backend : traduction à la frontière HTTP
Ajouter de petits modules
ex_app/lib/src/i18n/: résolution de langue, lecture des JSON générés, interpolation de paramètres, description d’un message et erreur localisable. Pas de dépendance navigateur, pas de variable globale « langue courante », pas de modification globale de Zod par requête.Contrat interne proposé :
MessageDescriptor = { source: string; params?: Record<string, string | number> };LocalizedErrorconservestatusCodeet ce descripteur. Le marqueur backendt(domain, source)est une fonction identité pour l’extraction (retourne la source, ne traduit pas) ; les services construisent un descripteur à partir de cette source et de paramètres distincts.renderMessage(descriptor, language)s’utilise dans le handler/presenter. Ne jamais tenter de retrouver une clé en remplaçant des fragments dans une ancienne phrase française interpolée.resolveLanguage(Accept-Language)traite les tags, variantes_/-, pondérations,q=0, entrée absente/malformée et langues inconnues ; retourne seulementfrouen, secoursen. Les JSON chargés sont immuables ; chemins basés sur cette liste fermée, jamais sur l’en-tête brut. Ne pas interpréterpluralFormaveceval/Function: seules les deux règles fr/en sont nécessaires si un message serveur a un pluriel.Dans
errors.ts, traduire les erreurs locales connues, préserver les codes HTTP et les champs publics ; conserver 404 pour absent et non-membre. Pour une erreur technique inconnue, exposer un message générique localisé et logger le détail ; ne pas envoyer le texte brut de Nextcloud comme traduction. Couvrir aussi les refus d’authentification/parser et les réponses anticipées des routes. Les réponses lifecycle restent conformes au protocole (corps vide en cas de succès, pas d’appel utilisateur).Pour Zod v3, traduire au moment de la réponse à partir du
ZodIssueet de ses limites/type/path ; déclarer les messages métiers personnalisés avec des clés extractibles, et garder leurs paramètres séparés si nécessaire. Couvrir min/max, type, enum, format/date, refinements et lessafeParsemanuels qui répondent hors du handler global. Aucunz.setErrorMapdépendant de la langue : deux utilisateurs simultanés doivent rester isolés.Les warnings internes deviennent des descripteurs jusqu’au presenter ; le contrat sur le fil reste
string[]. Faire de même pour toute raison lisible exportée/retournée, sans changer les enums de diagnostic ni la version du format de transfert. Ne pas utiliser un hook qui parcourt récursivement chaque chaîne JSON : il traduirait aussi les données des familles. Le client continue d’affichermessage,issues[].message,warnings, sans logique de traduction ni branchement sur les statuts.D. Notifications
Remplacer tous les sujets construits par interpolation par une source littérale marquée, par exemple
t('organisateur_familial', '{user} added ingredients from {recipe} to {list}'), avecuser,recipe,listdansrichSubjectParams. Utiliser les paramètres riches Nextcloud appropriés (user,highlightpour un texte sans ressource Nextcloud native), vérifier leur rendu réel. Les rappels « Tomorrow: {event} » suivent le même mécanisme. Garder un objet de paramètres, même vide, comme le fait déjàsendNotification.Ne pas appeler
renderMessageavant l’envoi : le notifier Nextcloud assure la langue du destinataire et la traduction à la lecture. Préserver préférences, exclusion de l’auteur etvoid notifyFamily(...). Préférer les formulations sans décompte pour les notifications : le notifier observé appellet, pasn. Une nouvelle traduction ne doit ajouter aucun appel OCS par membre.E. Hors ligne et manifeste
Étendre
OfflineMetaaveclanguageetlocalefacultatifs pour lire les caches déjà existants.saveMetales écrit depuis le contexte Nextcloud de la page ; le préchargement reste l’unique chemin existant, sans second écrivain de l’index ni suppression des gardes de révision. Au prochain chargement connecté, enregistrer les nouvelles valeurs même si les listes n’ont pas changé.La page hors ligne embarque les deux langues au build à partir des catalogues communs (un sous-ensemble de ses messages suffit). Ajouter un petit helper local de traduction de texte à
offline/shell.htmlou un module de build dédié ; garder des appels sources extractiblest(domain, '...'). Injecter les JSON via le build desw.ts/vite.config.sw.tsavec sérialisation sûre (<échappé dans le script HTML), jamais par concaténation de données utilisateur. Aucun import de@nextcloud/l10n, Vue ouwindow.OCdans le worker/la page autonome.Lire la langue/locale de la méta, mettre à jour
html.lang, title, titre, bouton et tous les états vides/erreurs. Ancienne méta sans langue : repli français pour préserver les anciens snapshots ; aucune méta : repli anglais explicite. Échec de lecture du cache : état d’erreur autonome, sans dépendance réseau. Les dates utilisent la locale mémorisée. Les données restent échappées via le mécanisme existant.D35 reste inchangé : aucun
fetch()dans le worker, pas de catalogue distant, aucune sous-ressource nécessaire hors ligne. Navigation preload et lecture de Cache Storage uniquement.Le manifeste est PUBLIC, il ne peut pas dépendre d’une session.
installOfflineManifest()fournit?lang=fr|en;routes/static.tsvalide cette liste et traduitshort_name, renseignelang, garde le nom propre et le scope/start_url existants. La variante doit figurer dans l’URL pour éviter de partager un manifeste de la mauvaise langue. Sans paramètre : anglais. Tester via le proxy sans credentials ; pas de nouvelle route ni accès utilisateur.F. Distribution des catalogues
ex_app/l10nen lecture seule dans le conteneur backend de développement, à un chemin explicite correspondant à celui utilisé en production (config dédiée si nécessaire).dev/setup.sh, réutilisée parmake reloadaprès génération. Copier uniquement les catalogues, propriétaire lisible par www-data. Vérifier aussi les mises à jour/caches Nextcloud, pas seulement la première installation./l10n/*comme substitut à l’installation côté Nextcloud.organisateur_familial/,appinfo/info.xmletl10n/au niveau attendu par AppAPI. Les sources PO ne sont pas requises au runtime. Fournir une cible de packaging si elle n’existe pas ; ne pas publier à l’App Store dans ce ticket.4. Lots ordonnés pour l’implémentation
Chaque lot doit compiler et avoir ses tests ciblés avant le suivant. Créer une branche
feat/issue-4-i18ndepuis le main actualisé ; si HEAD a changé, relire les fichiers touchés et ajuster le plan. Ne pas pousser sans demande.build(i18n): ...). Ajouter staging, PHAR épinglé, PO/POT/JSON/JS, commandes Make et contrôle CI. Brancher montage backend/synchronisation Nextcloud. Faire passer une chaîne Vue française/anglaise, une clé backend et une clé de notification dans la génération. Critère : FR chargé réellement dans le navigateur via Nextcloud et extraction TS/Vue/HTML prouvée. Résoudre tout problème de chargement avant la conversion massive.feat(i18n): localize API feedback). Ajouter modules i18n, erreurs/descripteurs, conversion Zod, migration des warnings et des réponses anticipées, en conservant contrats et autorisation. Critère : même requête invalide → mêmes statut/path, messages FR/EN différents ; requêtes concurrentes isolées ; warnings de succès traduits.feat(i18n): translate navigation and lists).App.vue,routes.tspour les seuls libellés éventuels,Welcome, switcher, famille/paramètres, home, listes, composants et constantes associés. Remplacer les décomptes par de vrais pluriels. Critère : première utilisation et parcours liste FR/EN, aucun nom saisi modifié.feat(i18n): translate planning and settings). Vues/composants/composables/stores restants, tousconstants/*.ts, formatage et dates relatives. Inclure filtres, récurrence, validation des formulaires, import/export et panneaux d’administration. Critère : chaque écran visité en anglais et français, responsive/accessibilité conservés, locale de date indépendante de la langue.feat(i18n): translate notifications through AppAPI). Adapter producteurs/paramètres riches et testsactivity,reminder, shopping/import. Critère : deux destinataires FR/EN lisent la même activité dans leur langue sans lookup de préférence supplémentaire.feat(i18n): localize offline view and manifest). Méta compatible, catalogue embarqué, formatage, manifeste paramétré, tests worker/build. Critère : démarrage hors ligne après chargement EN/FR et cache ancien, zéro requête réseau du worker et contenu inchangé.test(i18n): ...,docs(i18n): ...si séparables). Compléter/revoir le PO français, prouver sa couverture, corriger les tests existants au niveau des assertions de texte seulement. Ajouter les e2e ciblés, vérifier image/artefact et mettre le wiki à jour. Ne pas déplacer la mécanique métier pendant une traduction.5. Matrice de vérification obligatoire
q=0&, apostrophes,<img ...>Tests recommandés : nouveaux
ex_app/lib/src/i18n/*.test.ts, extension deapp.test.ts/tests erreurs et services concernés ;format.test.ts,relative-day.test.ts, tests vocabulaires/pluriels etoffline-snapshot.test.ts; une2e/tests/i18n.spec.tscouvrant les parcours et notifications réels. Fixer explicitement la langue FR de la suite existante et restaurer les préférences des comptes dans setup/teardown ; ne pas se contenter dulocalePlaywright, qui ne change pas la préférence Nextcloud. Les tests i18n utilisent comptes/fixtures imposés par la suite et ne doivent pas rendre les specs suivantes anglaises par accident.À la recette :
make l10n-check,make lint typecheck test,make build-frontend, vérifierjs/main.jsIIFE puiscd e2e && npm test. Exécuter aussi les tests de dates hors UTC (cd ex_app/src && npm run test:tz) et construire l’image de production pour vérifier les chemins des JSON. Les e2e passent par AppAPI et un frontend réellement reconstruit. Si échec inexpliqué, établir deux runs cohérents du main de référence avant d’accuser le diff. Revuebranch-reviewet revue technique prévue par Workflow ; consigner les retours dans le ticket.6. Documentation et mise en production
À la fin du développement, ajouter la prochaine décision libre dans Architecture (D37 est la dernière à la date du plan ; ne pas réserver aveuglément D38), mettre à jour UX (langue Nextcloud, hors ligne), Scope (FR/EN), Code guidelines et AGENTS.md (sources anglaises et catalogues), Dev environment (génération/synchronisation),
ex_app/l10n/README.mdet les références du skill pour les mécanismes AppAPI mesurés. Revoir les métadonnées anglaises/françaises d’appinfo/info.xml: elles décrivent encore un dossier/carnet d’adresses, contraire à D23. Ne pas présenter le ticket comme livré avant validation.MEP : livrer ensemble image Node, frontend/worker et catalogues côté Nextcloud dans la version du jalon ; contrôler une installation manuelle et le contenu de l’archive destinée à AppAPI. Prévoir la procédure de rafraîchissement des catalogues pour une mise à jour existante. Pas de migration SQLite, pas de réimport des données, pas de reprojection. Smoke test FR/EN connecté, erreur API, notification et consultation hors ligne. Retour arrière : restaurer image/artefact et catalogues de la même version, recharger la page/worker ; les métadonnées ajoutées sont facultatives et les anciens caches restent lisibles. Intégration linéaire seulement après recette ; aucune publication/push automatique autorisée par ce plan.
Revue technique —
main...efa26d3Portes mécaniques vertes avant lecture :
make lint typecheck test(466 + 378),make l10n-check,make build-frontend+ bundle IIFE, e2e 97/97.Hors i18n, gardé sur la branche
6bbc3e6— un événement journée entière sansDTEND(légal, fréquent dans les flux externes D33 et les imports) était filtré par le<c:time-range>de Nextcloud dès que la période commençait le jour même : jamais visible en vue Jour, absent le lundi en semaine, le 1er en mois, et le jour J sur l'accueil et dans le rappel de la veille.eventsBetweenlit désormais un jour plus tôt et recoupe par chevauchement, commeupcomingEvents. Nos propres événements n'étaient pas touchés (ical/build.tsécrit toujoursDTEND). Le mock DAV des tests unitaires applique maintenant le filtre tel que mesuré.efa26d3corrige le sélecteur « Fermer » ambigu du spec d'abonnement.Retours
t()/n()de@nextcloud/l10néchappent les paramètres par défaut, et rien n'est rendu en HTML : « L'épicerie & co » s'afficheL'épicerie & co(reproduit). Touche les messages de transfert, le titre de l'accueil, les agendas masqués, le dialogue d'agenda externe, l'export, la suppression d'une famille, et des aria-label / alt.stores/lists.tscalculeOFFLINE_WRITE_MESSAGEau chargement du module, avant l'enregistrement du catalogue.errors.tsabsorbe le 413 de Fastify (photo > 5 Mo, import) : rien ne dit que c'est la taille (reproduit ;mainrenvoyait au moins le texte de Fastify).'attendu : AAAA-MM-JJ'(events.ts,calendars.ts,meals.ts) et'attendu : un identifiant iCalendar'(events.ts) ne sont pas marqués : un compte anglais les reçoit tels quels (reproduit) et l'extracteur ne les voit pas.7e402fe(1 —services/l10n.ts, texte brut pour tous les appels du front),4d6ef3c(2),a9960f0(3 et 4), règle consignée dans AGENTS.md et la référence ExApp (e93dab8). Chaque correctif a un test qui échoue sans lui ; portes vertes, e2e 97/97.Revue fonctionnelle FR/EN —
main...e93dab8Visite de 16 écrans et dialogues en français et en anglais, sur desktop (1280) et sur mobile (390) : 64 captures, plus un balayage des templates à la recherche de libellés en dur. La famille de test portait des noms piégés (apostrophes,
&,<co>). Le compte admin a été basculéfr/enparocc, puis remis en français ; l'instance est propre.Conforme
Aucune entité HTML visible (le correctif de la revue technique tient à l'écran), aucun anglais résiduel sur les écrans français, pluriels justes (« 1 member », « 1 item remaining out of 2 »), aucun débordement horizontal sur mobile. Les fixtures de langue sont bien réinitialisées :
imposeFrenchau reset, comptes des specs supprimés.Retours
Modifier {event} — {jour|membre}dansTimetableAgenda,TimetableDay,TimetableMonth,TimetableMembers(×2, dont « sans attribution ») etWeekDayColumn; « Heure actuelle » (WeekDayColumn) ; le libellé visibleÉtape N(RecipeFormDialog) ; « Aucun membre dans cette famille. » (EventMemberPicker).kind.Intlplace le quantième avant le nom du jour quand le mois est absent.Non couvert par cette visite, mais couvert par les tests : anglais avec locale
fr-FR, rendu des notifications dans Nextcloud, page hors ligne.Hygiène de la suite
i18n.specsupprime son compte anglais avant la famille créée par ce compte ; la famille reste orpheline jusqu'au reset suivant, qui retire la ligne en base directement.Hors périmètre i18n : le bouton « Noter » du dialogue de repas est tronqué en « No… » dans les deux langues, identiquement sur
main— signalé à part.i18n.spec:6368243. Revérifié à l'écran en anglais, desktop et mobile — plus aucun libellé français, agendas nommés « Family events / Tasks / Meals », « Monday, Sep 14 », heures « 12 AM », titre de période complet sur mobile. Portes vertes (469 + 385) et e2e 97/97. Le bouton « Noter » reste ouvert dans #16.Intégré —
mainavance en fast-forward jusqu'à74983db18 commits, historique linéaire, pas de merge commit.
Cochées à l'intégration : installation neuve vérifiée sur volumes vides (catalogues présents dans l'image — 409 entrées — et dans
custom_apps/organisateur_familial/l10n, worker hors ligne porteur de son français, deux suites e2e complètes consécutives à 97/97) ; copie des catalogues en installation manuelle appliquée pardev/setup.sh; absence de migration SQL, de renommage et de reprojection confirmée, anciens caches hors ligne lus sans migration.La moitié « mise à jour des catalogues » est sans objet : rien n'a encore été livré, donc il n'y a aucune version installée à mettre à jour.
Trouvé en faisant cette dernière vérification, et corrigé dans
74983db:vite.config.sw.tslit../l10n/fr.jsonpour compiler le catalogue de la page hors ligne dans le worker, et le contexte de l'étape frontend estex_app/srcseul.make buildpassait pourtant — il compile les sources là où elles sont, pas l'image qui les embarque. Un job CI construit désormais l'image, sans la pousser.bringToZerofixait la langue du compte de service avant de le provisionner, etocc user:settingsur un compte absent emportait tout le reset.orphaned-familyn'était pas un flake :createFamilydistinguait les deux atterrissages avant que l'un des deux soit rendu, et la coquille se monte maintenant un instant plus tard puisqu'elle attend le catalogue. Deux suites sur trois en échec, le spec passant seul.Restent ouvertes, et volontairement : la livraison cohérente du jalon
1.0.x, les smoke tests d'après-livraison et le retour arrière. Elles appartiennent à la livraison de la release, pas à ce ticket — à reprendre au passage endelivered.