Découverte à la mesure : l'EAN-2 est DÉSACTIVÉ par défaut dans zbar. Il ne
suffisait donc pas de cesser de le filtrer — il n'était jamais produit.
Vérifié sur un EAN-13 + EAN-2 rendus en canvas : un symbole par défaut,
deux après setConfig(ZBAR_EAN2, ZBAR_CFG_ENABLE, 1).
L'EAN-5 reste désactivé : il porte un prix, pas un numéro.
Ce qui reste non vérifié — que les magazines réels y mettent bien leur
numéro de parution — est dit à l'utilisateur : le numéro est proposé dans
un champ modifiable, sous une invitation à le comparer à la couverture.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Clôt la décision du premier lot, qui écartait les périodiques faute de
modèle. Douze numéros d'un magazine ne font plus douze fiches identiques.
Table à part, pour la troisième fois et pour le même motif que la liste
d'envies et les séries : logée dans Livres, une revue entrerait dans le
catalogue, ses compteurs, les doublons et les bibliographies, et il
faudrait écrire « et qui n'est pas une revue » à chaque lecture.
Un numéro est recensé, rien de plus — ni prêt ni statut, tous deux liés à
Livre par clé étrangère. Réversible.
« Créer ou retrouver » et non « créer » : scanner le numéro suivant du même
magazine retombe forcément sur la même revue. L'unicité de l'ISSN est un
index partiel, sans quoi les revues sans ISSN se bloqueraient entre elles.
Le flux 977 mène désormais à la fiche de la revue, et ne pré-remplit plus
le formulaire d'un livre.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Rien n'empêchait de rescanner un livre déjà catalogué. Plutôt qu'un index
unique — qui interdirait le second exemplaire, cas parfaitement légitime —
la création répond 409 avec les fiches semblables, et « confirmerDoublon »
enregistre la même saisie.
Deux critères, dont aucun n'est une clé : ISBN identique, ou clé d'œuvre
et auteur communs. La clé d'œuvre étant un préfixe de TitreNormalise, SQL
dégrossit sur la colonne indexée et l'égalité exacte se vérifie ensuite en
mémoire.
Vérifié en exécution : avertissement, retour au formulaire intact, et ajout
confirmé créant bien un second exemplaire.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Six lots, issus d'IDEES.md. Les décisions actées sont reportées dans
CLAUDE.md, et les entrées traitées retirées d'IDEES.md.
1. Douchette USB, ISSN et enchaînement du scan
- Champ ISBN focalisé à l'ouverture : c'est tout ce qu'exige une
douchette USB, qui se présente au système comme un clavier. Remède
au scan caméra, qui rate sur la webcam d'un PC (optique, pas
décodage).
- Un EAN en 977 est un périodique : il porte un ISSN, donc un titre de
revue. Intercepté AVANT la validation ISBN (c'est un EAN-13
parfaitement valide), l'ISSN est déduit du code puis nommé via
bib.issn. Auparavant la cascade s'exécutait en entier pour finir sur
« aucun résultat ».
- L'enchaînement après scan existait déjà mais était invisible : une
étape « Recherche » affiche désormais le code interrogé.
2. ISBN affichés avec des tirets
Tables extraites du RangeMessage.xml officiel — plusieurs tranches ne
sont pas celles qu'on suppose. Le francophone est découpé en entier,
ailleurs on s'arrête au groupe et à la clé : aucune coupure fausse.
Corrige au passage l'export CSV, où un ISBN nu était lu comme un
nombre par Excel.
3. Hors-ligne : la liste d'envies
ListerSouhaitsAsync était le seul point de lecture hors du dispositif
hors-ligne, d'où le « 404 Not Found » brut à l'écran. Cinquième
instantané, écritures refusées, plus aucun message HTTP. Même défaut
corrigé sur la bibliographie.
4. Navigation par onglets
Catalogue / Auteurs / Prêts / Envies dans MainLayout ; les barres
d'actions ne portent plus que des actions. Filtres repliés derrière un
bouton compteur, ligne « format » masquée quand le fonds n'a qu'un
format. Une seule entrée d'ajout, désactivée hors-ligne — pas masquée.
5. Liste d'envies : ordre, recherche, couvertures
Migration RangDesEnvies. Le remplissage reconduit l'ordre affiché
jusqu'ici : sans lui, les listes existantes se seraient réordonnées
toutes seules. Réordonnancement par flèches et glisser-déposer (le
drag & drop HTML5 ne marche pas au doigt). Ajout dans son propre
écran, avec recherche par titre (bib.title) et couvertures enfin
alimentées.
6. Bibliographie : une source muette n'est pas une liste vide
L'écran affichait « BnF injoignable » PUIS « la BnF ne connaît aucun
livre de cet auteur » — la seconde phrase étant fausse. Les deux cas
s'excluent désormais, et un bouton Réessayer est offert.
Vérifié en exécution : le diagnostic d'IDEES.md était faux sur un
point. Robert A. Harper a bien 7 œuvres à la BnF (85 notices
annoncées) ; c'était le même délai dépassé observé deux fois, pris
pour deux causes distinctes.
380 tests, dont un qui applique réellement la migration (EnsureCreated
n'en joue aucune) et un qui verrouille les messages atteignant
l'utilisateur.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Le piege que CLAUDE.md signale : en Blazor WebAssembly le code tourne dans le
navigateur alors que SQLite vit sur le serveur, et le service worker ne met en
cache que les assets. Sans travail explicite, l'application demarre hors-ligne
et affiche une bibliotheque vide.
- js/cache-hors-ligne.js : instantanes JSON dans IndexedDB, et surveillance des
bascules online/offline. Aucune logique metier.
- CacheHorsLigne / EtatReseau : lecture-ecriture des instantanes, et etat reseau
combinant navigator.onLine (fiable seulement par sa negation) avec le sort
reel des appels HTTP.
- ServiceLivresApi : les lectures retombent sur le cache, les ecritures sont
refusees. Le catalogue entier est memorise, pas les reponses filtrees : c'est
ce qui rend la recherche hors-ligne possible sur tout le fonds.
- FiltreLivresLocal : pendant navigateur de FiltreLivres, avec un test qui
confronte les deux implementations sur les memes donnees.
- Interface : pastille et bandeau d'etat avec la date de synchronisation, et
actions d'ecriture desactivees avec leur raison plutot que boutons morts.
- js/mise-a-jour.js : les empreintes WASM etant desactivees, le service worker
est le seul cache-busting du projet. L'enregistrement journalise desormais ses
echecs, et un bandeau propose la nouvelle version sans attendre la fermeture
de tous les onglets.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Le decodage EAN-13/EAN-8 est fait en C# par ZXing.Net (IsbnScanner), conformement
a la decision actee dans CLAUDE.md : le JavaScript ne fournit que les pixels de la
camera, aucune logique de decodage ne lui est confiee.
Le scan se greffe en amont du flux d'ajout par ISBN existant : des qu'un code est
lu et reconnu comme ISBN-13 valide, la recherche de notices est declenchee sans
que l'utilisateur ait a retaper quoi que ce soit. La saisie manuelle reste
accessible en permanence, y compris quand la camera echoue.
Points traites explicitement :
- camera arriere par defaut (facingMode "environment", en "ideal" pour ne pas
echouer sur un PC sans camera arriere) ;
- liberation de la camera a l'annulation, au succes et au demontage du composant ;
- cadence limitee a ~12 images/s et decodage restreint a la bande centrale
reduite a 640 px de large : inutile de decoder chaque frame en pleine taille ;
- messages distincts pour permission refusee, absence de camera, camera occupee
et contexte non securise (getUserMedia exige HTTPS ou localhost : une IP de
reseau local en http ne marchera jamais, c'est une source de confusion garantie).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
API
- CRUD complet sur /api/livres : liste filtrable (format, statut) et
cherchable (titre, auteur), consultation, creation, modification,
changement de statut isole, suppression.
- Aucune lecture ne filtre sur AjoutePar : la bibliotheque est commune au
foyer. Le critere n'existe meme pas dans CritereLivres, pour qu'on ne
puisse pas s'en servir par inadvertance. Deux tests verrouillent
l'invariant, dont un par reflexion sur le type des criteres.
- AjoutePar est renseigne par le serveur a la creation, jamais par le
client, et n'est pas reecrit a l'edition (pas plus que DateAjout).
- Identite lue dans les en-tetes SSOwat (YNH_USER, YNH_USER_EMAIL,
YNH_USER_FULLNAME), avec repli sur un utilisateur simule configure en
developpement uniquement. Sans en-tete ni simulation, l'identite reste
inconnue plutot qu'inventee. Expose par GET /api/moi.
- Migration appliquee au demarrage : pas d'etape manuelle a l'installation.
Interface Blazor, pensee mobile d'abord
- Catalogue unique (physiques et numeriques melanges, distingues par le
format) avec recherche, filtres et changement de statut directement dans
la liste.
- Ajout par ISBN : quand la cascade rend plusieurs notices, un ecran de
choix les presente en mettant en avant editeur et annee, seuls elements
qui les departagent. Le formulaire reste ensuite entierement modifiable.
- Ajout manuel, edition, suppression avec confirmation explicite.
- Couvertures : l'URL OpenLibrary n'est jamais validee par un appel
prealable (502 intermittents mesures en phase 2) ; un attribut onerror
masque l'image cassee et laisse apparaitre un substitut.
Decisions prises la ou CLAUDE.md etait muet
- Tri alphabetique par titre.
- Un ISBN saisi doit etre valide, mais reste facultatif.
- Ecran de choix affiche seulement a partir de deux candidats.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>