Compare commits

...
2 Commits
Author SHA1 Message Date
mathieuandClaude Opus 5 718df2c986 Consigner les retours d'usage du 2026-08-19 (3ᵉ série)
Trois points remontés, tous avec leur arbitrage identifié mais non tranché :

- doublon à l'ajout : vérifié, CreerAsync ne contrôle rien et l'index sur
  Isbn n'est pas unique. Reste à décider refus ou avertissement, un second
  exemplaire étant légitime ;
- retirer l'envie correspondante à l'ajout : la difficulté est la portée
  (catalogue commun, envies personnelles), pas le rapprochement ;
- BD et magazines : les BD demandent surtout un type de document, les
  magazines rouvrent la décision actée de ne pas cataloguer les périodiques.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 00:35:17 +02:00
mathieuandClaude Opus 5 281d74a29d Documenter le choix de la bibliothèque de code-barres, à trancher
L'ISBN 9782846391009 n'est pas décodé par l'application, mais l'est par
une application d'essai avec ZBar, sur le même appareil et le même livre.

Le raisonnement qui écartait ce sujet était faux : CLAUDE.md conclut que
« le décodeur n'y est pour rien » à partir de mesures de VITESSE, qui ne
disent rien du taux de réussite.

Poids mesuré sur le publish Release de l'application d'essai : ZBar coûte
~168 Ko brotli, contre ~346 Ko déjà documentés pour ZXing.Net — dont la
queue d'assemblies BCL (Regex à 98 Ko, Numerics) que ZBar ne traîne pas.
Le remplacement allégerait l'application d'environ 180 Ko, à confirmer
par une comparaison de deux publish du projet.

Rien n'est acté : la décision se paie du départ du décodage hors du C#,
qui était la justification du choix de ZXing.Net.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-19 00:33:47 +02:00
+157
View File
@@ -84,6 +84,163 @@ L'échec est donc **au décodage de l'image**, pas au lookup. Rejoint le point c
⚠️ À reproduire en saisissant l'ISBN à la main avant de conclure : si la saisie manuelle échoue ⚠️ À reproduire en saisissant l'ISBN à la main avant de conclure : si la saisie manuelle échoue
aussi, le défaut est ailleurs et ce diagnostic tombe. aussi, le défaut est ailleurs et ce diagnostic tombe.
## Choix de la bibliothèque de lecture de code-barres — à trancher
**Constat qui rouvre le sujet, 2026-08-19.** L'ISBN `9782846391009` n'est pas décodé par
l'application, alors qu'il l'est par une application d'essai (`~/Code/TestBarcode`) sur le
**même appareil et le même livre**, avec **ZBar**.
⚠️ **Le raisonnement qui écartait ce sujet était faux.** `CLAUDE.md` conclut que « le décodeur
n'y est pour rien » à partir de mesures de **vitesse** (4-6 ms/frame en WASM interprété). Or la
vitesse ne dit **rien du taux de réussite** : un décodeur peut être rapide et rater. Les mesures
existantes ne pouvaient donc pas soutenir cette conclusion, et l'essai la contredit.
### Ce que l'essai établit, et ce qu'il n'établit pas
**Établi** : ZBar lit ce code-barres, ZXing.Net (portage C#) ne le lit pas, dans les mêmes
conditions physiques.
**Non établi** : que le moteur soit seul en cause. Notre implémentation ne fait pas que décoder,
elle **prétraite** — réduction à 640 px de large, puis **recadrage sur la bande centrale**
(`PartHauteur = 0,45`). ZBar, lui, analyse l'image entière. Deux causes candidates cohabitent
donc, et l'essai ne les sépare pas :
1. le moteur (ZXing.Net est un portage d'une version ancienne de ZXing, réputé moins robuste que
`zbar` ou que `zxing-js`) ;
2. notre prétraitement (bande trop étroite, ou résolution insuffisante pour la largeur de module
à la distance de prise de vue).
Adopter ZBar rendrait la seconde question sans objet : le composant gère lui-même la caméra et
l'image.
### Le poids : mesuré, et à l'inverse de ce qu'on croyait
Somme brotli réelle du publish `Release` de l'application d'essai :
| Fichier | brotli |
|---|---|
| `zbar.wasm` (moteur C compilé) | 138 938 o |
| `ZBar.Blazor.<empreinte>.wasm` (assembly .NET) | 21 232 o |
| `zbar.js` | 5 247 o |
| `camera.js` + `image.js` + `scanner.js` | 2 457 o |
| CSS isolé | 199 o |
| **Total ZBar** | **≈ 168 Ko** |
À comparer au coût de ZXing.Net **déjà documenté dans `CLAUDE.md`** : **≈ 346 Ko brotli**, dont
seulement 192 Ko d'assembly — le reste étant les assemblies BCL que le trimmer ne peut plus
retirer (`System.Text.RegularExpressions` passant de 7 à 98 Ko parce que ZXing utilise Regex,
plus `System.Runtime.Numerics`).
Vérifié dans le publish d'essai : `System.Text.RegularExpressions` y pèse **7 137 o**, et
`System.Runtime.Numerics` est **absent**. ZBar ne traîne pas cette queue.
**Le remplacement allégerait donc l'application d'environ 180 Ko brotli**, au lieu de l'alourdir.
⚠️ Chiffre à confirmer par une comparaison de deux publish de *notre* application, comme l'a été
celui de ZXing.Net : le coût d'une bibliothèque n'est pas le poids de son assembly.
### Ce qu'on perdrait
- **Le décodage quitte le C#.** C'est l'argument qui avait fait retenir ZXing.Net : « réutilisable
hors navigateur si le projet évolue en scanner de bibliothèque ». Cet usage est **hypothétique
et n'a jamais été exercé** ; il se paie aujourd'hui en codes-barres non lus.
- **`IsbnScanner`, `BancEssaiScan`, `ScannerCodeBarres` et `wwwroot/js/scanner-camera.js`**
disparaîtraient au profit du composant `ZBarCamera`.
- **Une dépendance jeune** : `ZBar.Blazor` 1.1.0. À regarder avant de s'engager (maintenance,
licence, taille de la communauté).
### Ce qu'on gagnerait, au-delà du code lu
- **Le format est remonté** (`ISBN_13` vs `EAN_13`), là où nous le déduisons du préfixe.
- **Les add-ons EAN-5 (prix) et EAN-2 (numéro) sont décodés** et rattachables au code principal —
l'EAN-2 est précisément ce qui accompagne les périodiques en `977`.
- **Plus de pipeline image maison** à entretenir (capture, réduction, recadrage, `RGBLuminanceSource`).
---
# Retours d'usage du 2026-08-19 (3ᵉ série)
## Bug — un livre déjà catalogué peut être réencodé
Vérifié dans le code : `ServiceCatalogue.CreerAsync` ne fait **aucun** contrôle de doublon, et
`HasIndex(l => l.Isbn)` n'est **pas** unique. Scanner deux fois le même livre crée deux fiches.
⚠️ **À trancher avant de coder : refuser, ou avertir ?** Refuser tout net serait un piège, car
posséder deux exemplaires est légitime — on garde le sien et on prête l'autre. Et l'ISBN est
facultatif, donc il ne peut pas être le seul critère.
Trois critères candidats, de plus en plus large :
| Critère | Attrape | Rate / gêne |
|---|---|---|
| **ISBN identique** | le rescan du même livre, cas visé | rien si l'ISBN manque ; refuse un second exemplaire |
| **Clé d'œuvre + auteur** (`CleOeuvre`, comme la liste d'envies) | la saisie manuelle sans ISBN | confond le poche et le grand format, qui sont deux éditions possédées |
| **les deux, en avertissement** | tout ce qui précède | demande une confirmation de plus |
Piste privilégiée : **avertir et laisser confirmer** (« Vous avez déjà *Germinal* — ajouter
quand même ? »), plutôt que l'index unique qui interdirait le second exemplaire. La liste
d'envies, elle, refuse — mais elle décrit une envie, pas un objet, et deux exemplaires d'une
envie n'ont pas de sens.
## À l'ajout d'un livre, retirer l'envie correspondante
Demandé : si le livre ajouté figure dans la liste d'envies, l'en retirer.
⚠️ **La difficulté est la portée, pas le rapprochement.** Le catalogue est **commun**, la liste
d'envies est **personnelle** — ce sont les deux portées que `CLAUDE.md` oppose explicitement.
« Retirer l'envie » n'a donc pas une seule réponse :
- **la sienne uniquement** : simple, sûr, ne franchit aucune frontière. Mais si Camille souhaitait
le livre et que Mathieu l'ajoute, Camille garde une envie pour un livre que le foyer possède.
- **celle de tout le monde** : cohérent avec « le livre est commun », mais **modifie
silencieusement la liste d'un autre**, et lui fait perdre sa note (« demandé à Noël »). L'API
ne sait pas — délibérément — écrire dans la liste d'autrui : ce serait une brèche à ouvrir
dans un invariant tenu jusqu'ici.
- **ne rien supprimer, mais signaler** : la liste d'envies marque l'entrée « déjà au catalogue ».
Non destructif, respecte la frontière, et l'écran de bibliographie sait déjà distinguer
`Possede` de `Souhaite`.
⚠️ Le rapprochement se ferait par `CleOeuvre` + auteur, avec les mêmes limites que la
bibliographie (titre retraduit, tome, intégrale — voir `CLAUDE.md`). Une suppression sur un
rapprochement faillible est **irréversible** ; un signalement ne l'est pas. C'est un argument de
poids pour la troisième voie.
## Bandes dessinées et magazines
Deux demandes distinctes, de coût très différent.
### Les BD : surtout une question de type de document
Une BD est déjà catalogable telle quelle — elle a un ISBN, la BnF la connaît (vérifié au lot 6 :
la BD de Dobbs tirée de *La bête humaine* remonte bien). Ce qui manque est de pouvoir **la
distinguer** : `Format` dit physique ou numérique, pas roman ou BD.
Piste : un `TypeDocument` (roman / BD / magazine…) à côté de `Format`, avec migration, filtre au
catalogue et étiquette. ⚠️ Suivre la règle déjà actée pour le format : **n'afficher que ce qui
n'est pas le cas par défaut**, sinon chaque ligne du catalogue porte une étiquette qui n'apprend
rien.
Champs propres à la BD (série, tome, scénariste/dessinateur) : à ne faire que si le besoin se
confirme. Le modèle actuel met tous les auteurs dans `LivreAuteur` sans distinguer les rôles.
### Les magazines : cela rouvre une décision actée
⚠️ `CLAUDE.md` (lot 1) écarte **délibérément** le catalogage des périodiques : « le modèle de
données n'a ni numéro ni date de parution, et les deux chiffres de parution du code ne sont pas
exploitables comme numéro fiable — douze numéros d'un même magazine partagent leur ISSN et
créeraient douze fiches identiques ». Le scan d'un code `977` nomme donc la revue et bascule sur
la saisie manuelle, **sans** l'ISBN.
Les supporter vraiment demande de lever exactement ce qui avait motivé le refus :
- un **ISSN** distinct de l'ISBN (le ranger dans `Livre.Isbn` casserait tout lookup ultérieur) ;
- un **numéro** et une **date de parution**, seuls capables de distinguer deux exemplaires ;
- de décider si un magazine est **une fiche par numéro** ou **une fiche par revue avec des
numéros rattachés** — c'est le vrai choix de modélisation, et il change la migration ;
- de reprendre le flux `977` pour qu'il crée au lieu d'expliquer.
À trancher avant tout code. Le reste (filtres, prêts, hors-ligne) suit mécaniquement une fois le
modèle arrêté.
## Auteurs et bibliographie ## Auteurs et bibliographie
### Homonymes : « Between two worlds », un autre Robert Harper ### Homonymes : « Between two worlds », un autre Robert Harper