63bf6be3e17a9c982cd1cc785facaa5eb6a46387
4
Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
498579f27b |
Dis à l'application quelle version elle est, et sous quelle licence
Page « À propos » (/a-propos) : manuel annoncé à venir, contact, site de l'auteur, version publiée avec sa date de build, et licence AGPL v3 avec le lien vers le dépôt — l'AGPL attend que les utilisateurs d'un service en réseau puissent en obtenir la source, ce lien n'est donc pas un ornement. L'application ne connaissait pas sa version : elle vivait dans le manifeste du paquet et dans les tags git, jamais dans le binaire. `build/publier-release.sh` pose désormais `-p:Version` et `-p:MaBibliDateBuild` ; l'API rend les deux par `GET /api/version`. ⚠️ L'horodatage est le TÉMOIN de l'injection, et rien ne le calcule côté MSBuild. Sans lui, la version lue serait le « 1.0.0 » que le SDK pose par défaut : il se lirait comme une vraie version alors qu'il ne désigne rien, et c'est exactement la valeur qu'on ira chercher pour diagnostiquer un appareil au cache dépareillé. Mieux vaut ne rien annoncer — un binaire compilé à la main se déclare « version de développement », ce qui est vrai. Autres décisions : - l'entrée du menu est DÉTACHÉE des six destinations, par un filet au-dessus sur téléphone et à gauche en rangée sur PC : « À propos » est une annexe, pas une septième destination. Ses règles vivent en feuille GLOBALE, comme tout le menu — une règle scopée n'atteint pas ce que rend un NavLink ; - le « mailto: » reste un lien même hors-ligne : il ne charge aucune page et passe la main au client de messagerie, qui sait mettre un message en attente. Le site et le dépôt, eux, basculent en boutons désactivés portant leur motif, comme les liens d'export des envies ; - la version est un sixième instantané hors-ligne : on la lit justement quand quelque chose ne va pas, et un appareil qu'on soupçonne est souvent celui qui n'a plus de réseau. L'écran dit alors que c'est la dernière version vue du serveur. Le point de rupture de 40 rem reste identique dans les deux feuilles, et /a-propos est inscrite dans la table de remontée des routes. Vérifié en exécution, l'API lancée : sans injection `{"numero":null,"publiee":false}`, avec `-p:Version=0.4.1 -p:MaBibliDateBuild=…` `{"numero":"0.4.1","publiee":true}`. Le rendu des écrans n'a PAS été vérifié en navigateur. 618 tests au vert (605 avant). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
0976da90be |
Sors du chemin de la consultation d'une revue ce qui la modifie
La fiche d'une revue portait tout à la fois : ses numéros, le formulaire d'ajout, les champs de la revue et sa suppression. Elle prend la forme déjà tenue par la fiche d'un livre et par celle d'une série — une route pour regarder, une route pour changer. « Ajouter un numéro » et « Modifier la revue » remontent à droite du titre, dans le bloc d'en-tête partagé avec la fiche d'une série : les deux actions sont visibles sans descendre au bas d'une collection de trente numéros. ⚠️ Modifier et retirer un numéro n'existent plus QUE dans /revues/{id}/edition. En consultation, ces deux boutons se déclenchaient sous le pouce en faisant défiler la liste — même raison que les flèches d'ordre d'une série, reléguées sur leur propre écran. ⚠️ Ajouter un numéro, lui, RESTE en consultation, et ce n'est pas une entorse : le geste ne touche pas à la fiche de la revue, il range un objet de plus, comme noter un prêt depuis la fiche d'un livre. Le formulaire se replie derrière son bouton, et s'ouvre de lui-même quand on arrive du scanner avec un numéro lu sur l'add-on EAN-2 : demander un clic de plus pour saisir ce qu'on tient en main serait un détour. Un retrait de numéro se confirme désormais, comme la suppression d'un livre ou d'une revue : il ne se défait pas, et la liste s'égrène sous le pouce. ⚠️ Les deux routes partagent le paramètre {id} : le routeur ne redessine rien en passant de l'une à l'autre, d'où l'abonnement à LocationChanged — piège déjà rencontré sur la fiche livre. Quitter l'édition referme au passage ce qui n'a de sens que là : formulaire de numéro ouvert, retrait ou suppression en attente de confirmation. /revues/{id}/edition entre dans la table de RemonteeRoutes : elle retombait jusqu'ici sur le repli de branche, donc sur la liste des revues au lieu de la fiche qu'on venait de quitter. Deux tests de service viennent avec, sur ce dont l'écran dépend sans le recalculer : la revue rendue par la modification d'un numéro revient déjà rangée (corriger une parution déplace le numéro, les numéros sans date fermant toujours la liste), et un retrait ne touche qu'au numéro visé. 605 tests au vert. Pas de vérification en navigateur : le rendu repose sur la relecture. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
94f0ef15c0 |
Compte les pages d'un livre, et fais des envies une liste à deux moitiés
Lot U — le nombre de pages `Livre.NombrePages` est nullable, sans valeur par défaut : « 0 page » se lirait comme une donnée là où l'on veut dire « on ne sait pas ». Même raison que pour `TypeDocument.NonPrecise` — un défaut qui ne prétend rien n'a rien à reprendre, d'où une migration réduite à un `AddColumn`. Le service refuse un zéro plutôt que de l'écrire ; effacer le champ reste la façon de revenir à « inconnu ». Le préremplissage vient de `dc:format`, que rien ne lisait jusqu'ici. ⚠️ Ce champ n'est pas un nombre mais une phrase décrivant le support, et les notices déjà enregistrées sous Fixtures/ le montrent : « 1 vol. (113 p.) : ill., couv. ill. en coul. ; 18 cm », « 503 p. : couv. ill. ; 17 cm ». Les règles sont donc étroites — un nombre suivi de « p. » ou de « page(s) », rien d'autre — et tout le reste rend `null`. L'erreur n'est pas symétrique : un champ vide se remplit à la main en trois secondes, un chiffre faux s'enregistre sans que personne ne le voie. « 1 vol. » ne vaut pas 1, « 30 cm » ne vaut pas 30, et « (p. 45-90) », qui est une pagination de contribution, ne vaut rien. La valeur reste proposée dans un champ modifiable, et rien n'est déduit pour un ebook. Lot X — éditer une envie, et souhaiter une revue `PUT /api/souhaits/{id}` recalcule la clé d'œuvre et l'auteur normalisé : sans ce recalcul, le rapprochement « déjà au catalogue » continuerait de se faire sur l'ancienne forme, et le signalement mentirait sans le dire. Le filtre sur l'appelant fait partie de la clé de recherche, pas d'une vérification ultérieure — l'envie d'un autre est introuvable (404), jamais refusée (403). ⚠️ Une édition peut heurter l'unicité (utilisateur, œuvre, auteur), ce qu'un ajout ne peut pas : renommer une envie en une autre déjà présente répond par un message lisible, jamais par « UNIQUE constraint failed ». 400 et non 409, contrairement au doublon du catalogue : là-bas posséder deux exemplaires est légitime et l'appel se reconfirme, ici l'index l'interdit et il n'y a rien à confirmer. Le rang n'est pas touché — l'ordre a son propre point d'entrée. ⚠️ La couverture n'est écrite que si la charge utile en porte une. Aucun écran n'offre de champ « URL de couverture » pour une envie (décision actée), donc un remplacement inconditionnel l'aurait effacée à la première faute de frappe corrigée. `RevueSouhaitee` est une table sœur, et non des colonnes de plus sur `LivreSouhaite` : un numéro n'a pas d'auteur et se distingue par son numéro, deux choses que la clé d'unicité des envies de livres ne sait pas exprimer sans devenir fausse pour tout le monde. `NumeroNormalise` est NOT NULL avec un défaut vide — SQLite tient deux NULL pour distincts, et « Médor, sans numéro » s'ajouterait autant de fois qu'on cliquerait. L'ISSN est canonisé avec son tiret, seul code du projet rangé ainsi. Le coût de la table sœur est payé partout où il devait l'être : affichage, `.txt`, `.csv` et instantané hors-ligne `souhaits-revues`. ⚠️ Les revues forment une SECTION à part plutôt que des lignes entrelacées : chaque table numérote son rang indépendamment, et mélanger deux suites sans rapport produirait un ordre que personne n'a choisi. Le `.txt`, groupé par auteur, ne pouvait de toute façon pas les accueillir — elles n'en ont pas, et « Auteur non précisé » désigne des livres dont l'auteur est inconnu. Le CSV gagne une colonne « Type » : sans elle, un tri par titre rendrait revues et livres indiscernables, et la colonne des codes mêlerait ISBN et ISSN en silence. `ServiceRenormalisation` connaît la nouvelle table, avec la règle de collision déjà en place. ⚠️ L'ISSN y est canonisé à part : `Renormaliser` n'applique rien quand la clé ne bouge pas, un ISSN mal formé sur une ligne au titre inchangé y échapperait. `RevueSouhaitee` ne porte PAS de `CoverUrl` : rien à ajouter au garde de `GET /api/couvertures`. Vérifié en exécution : ISSN « 24666718 » rangé « 2466-6718 », édition de l'envie d'un autre en 404, et les deux exports portant bien les deux moitiés. 602 tests au vert (552 au départ), aucun avertissement de compilation. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |
||
|
|
1b47828c11 |
Remonte le type de document, colle le menu, et fais du retour une remontée
Cinq retours d'usage du 2026-08-21 qui ne touchent que l'interface (lots Q, R, S, T et V d'IDEES.md). Aucune migration, aucune entité modifiée. Q — L'ordre des champs du formulaire livre est une décision, pas une mise en page : type de document, thèmes, auteurs, rôles, puis le reste. Le type commande la suite de la saisie — les rôles ne se posent que là — et il fallait descendre tout le formulaire pour dire « c'est une BD », c'est-à-dire après avoir saisi ce qui en dépend. Rien n'est présélectionné : « non précisé » ne prétend toujours rien, et les rôles gardent leur règle actée (deux auteurs au moins, BD ou non). Des tests verrouillent la préservation des rôles à chaque frappe, que ce réordonnancement ne doit pas entamer. R — Bandeau et menu passent dans un même conteneur collant : sur PC la rangée des six destinations défilait avec la page et devenait inatteignable au bas d'une longue liste. Un seul conteneur, et non deux éléments collants superposés, qui auraient obligé à écrire en dur la hauteur d'un bandeau qui varie avec la pastille hors-ligne et le nom d'utilisateur. Sur téléphone le menu déployé occupe l'écran entier : sous le bandeau, il partageait l'écran avec la liste qu'on quittait. Trois portes de sortie s'ajoutent à la fermeture déjà en place sur LocationChanged — croix, Échap (le calque prend le focus à l'ouverture, comme celui d'agrandissement des couvertures) et clic hors des liens. Le plein écran est explicitement annulé au-delà de 40 rem, sans quoi un menu ouvert au doigt puis une fenêtre agrandie laisseraient un calque sans bascule pour le refermer. Toutes les règles du menu restent en feuille globale. S — ⚠️ Le retour du bandeau devient une remontée hiérarchique d'un cran de route, ce qui RENVERSE la décision actée le 2026-08-20 (« le retour passe par l'historique du navigateur, jamais par une destination calculée »). Le motif d'alors reste vrai — un même écran s'atteint par plusieurs chemins — mais l'historique remonte aussi les allers-retours (filtre, ordre, édition) et l'on cliquait cinq fois sans quitter le même écran. La parenté est une table explicite et testable, pas un découpage naïf d'URL : toutes les routes n'ont pas la forme d'une arborescence, /auteurs/{id}/bibliographie remontant à la liste des auteurs, dont il n'existe pas de fiche. Le garde-fou « ne jamais sortir de l'application » y vit désormais aussi : la fonction rend toujours un chemin interne, là où history.length ne disait pas ce qu'on croyait dans une PWA standalone. js/navigation.js n'a plus d'utilisateur et disparaît. T — Sur la fiche d'une série, « Modifier » et « Changer l'ordre » rejoignent la ligne du titre et de l'avancement, groupés à droite comme la bibliographie et la liste des auteurs le font déjà. Reléguées au bas de l'écran, les actions d'une saga de vingt tomes ne se découvraient qu'après avoir déroulé la liste. « Changer l'ordre » n'apparaît toujours qu'à partir de deux tomes ou deux sous-séries. V — Dans la liste des revues, toute la ligne ouvre la fiche, comme la carte entière le fait au catalogue. Le titre reste un vrai lien — adresse, clavier, clic-milieu — et son clic ne remonte pas jusqu'à la ligne, qui naviguerait une seconde fois ; toute action posée un jour sur cette ligne devra faire de même. ⚠️ Aucune vérification en navigateur : le rendu de ces écrans repose sur la compilation et la relecture. 552 tests au vert (506 avant ce lot). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> |