diff --git a/CLAUDE.md b/CLAUDE.md index 12c8d33..31f9a44 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -30,6 +30,11 @@ Application self-hosted de gestion de bibliothèque personnelle, à héberger su | Auth / multi-utilisateur | SSO YunoHost via **en-têtes SSOwat** (`YNH_USER`) | Pas de login custom. OIDC **écarté** : non documenté par YunoHost (vérifié le 2026-08-17). Voir « Intégration SSO » | | Portée des données | **Collection commune** à tous les utilisateurs, avec traçabilité de qui a ajouté chaque livre | Usage familial : une bibliothèque de foyer, pas des collections étanches. Laisse la possibilité de cloisonner plus tard sans migration lourde | | Ebooks | **Fiches uniquement**, pas de stockage de fichiers | Inventaire, pas hébergement. Évite l'espace disque YunoHost, les sauvegardes lourdes, et garde le cache hors-ligne léger | +| Architecture serveur | **x86_64** → publish `linux-x64` | Serveur PC/VPS confirmé par l'utilisateur | +| Production des binaires | **Compilation locale + release manuelle**, via un script réutilisable en CI plus tard | Ne pas se bloquer sur l'outillage ; Gitea Actions nécessiterait un runner, non vérifié | +| Cache hors-ligne | **IndexedDB** (pas le cache du service worker) | Seule option permettant recherche et tri hors-ligne sur toute la bibliothèque, et l'affichage de la date de dernière synchro | +| Notices BnF multiples | **Demander systématiquement** à l'utilisateur | Exactitude de l'édition privilégiée sur la vitesse de saisie en série | +| AOT WebAssembly | **Désactivé par défaut**, à réévaluer après mesure | Le mode interprété devrait suffire (~5-10 ms/frame estimés) ; ne pas payer le coût de build avant d'avoir constaté un problème | | Hébergement | YunoHost, installation **native** (pas Docker) | YunoHost déconseille Docker pour ses apps (moins fiable, plus lourd) ; installation native = meilleures perfs sur petit matériel | | Packaging YunoHost | S'inspirer de [`radarr_ynh`](https://github.com/YunoHost-Apps/radarr_ynh) | Radarr est aussi en .NET, packagé sans Docker sur YunoHost. Leur `manifest.toml` montre un déploiement **self-contained** (`dotnet publish -r linux-x64 --self-contained`), donc pas besoin d'installer `dotnet-runtime` via apt côté serveur — le binaire embarque son propre runtime | | Scan ISBN | **ZXing.Net** (C#, Apache 2.0) exécuté dans le WASM ; le JS ne fournit que les pixels caméra | Décodage en C#, réutilisable hors navigateur si le projet évolue en scanner de bibliothèque. Voir la section dédiée ci-dessous | @@ -189,6 +194,56 @@ Conversion ISBN-13 → ISBN-10 (uniquement pour le préfixe `978`) : retirer `97 - **Limite connue** : se déconnecter du portail YunoHost ne déconnecte pas des apps, chacune conservant sa propre session/cookie. - En développement local, il n'y a pas de SSOwat : prévoir un utilisateur simulé (en-tête forcé ou configuration de dev) plutôt que de désactiver l'auth. +## Architecture de déploiement YunoHost + +### Trois projets .NET, un seul service + +Le client Blazor WebAssembly n'est **pas** un serveur : compilé, ce ne sont que des fichiers statiques (HTML/CSS/`.wasm`) **servis par l'API**. Un seul processus tourne donc sur le serveur. + +``` +DÉVELOPPEMENT COMPILATION DÉPLOIEMENT +MaBibli.Client ─┐ +MaBibli.Shared ─┼──► dotnet publish ──► un dossier ──► un service systemd +MaBibli.Api ─┘ MaBibli.Api unique sur 127.0.0.1:PORT +``` + +`MaBibli.Api` référence `MaBibli.Client` ; à la compilation, les fichiers du client atterrissent dans le `wwwroot` de l'API. + +Commande de publication cible : + +``` +dotnet publish MaBibli.Api -c Release -r linux-x64 --self-contained +``` + +Le self-contained embarque le runtime .NET dans le binaire : **aucun `dotnet-runtime` à installer** côté serveur, pas de conflit de versions. C'est le modèle de `radarr_ynh`. + +### Deux dépôts distincts + +| Dépôt | Contenu | Rôle | +|---|---|---| +| `mabibli` | Le code C#, les 3 projets | Ce qui est développé | +| `mabibli_ynh` | `manifest.toml`, scripts, conf nginx/systemd | Comment l'installer sur YunoHost | + +Le paquet `_ynh` **ne contient aucun code C#** : il porte des instructions d'installation et une URL vers une archive compilée, avec son empreinte SHA256. + +``` +mabibli_ynh/ +├── manifest.toml ← identité, version, URL du binaire + sha256 +├── conf/ +│ ├── systemd.service ← lancement du service, port +│ └── nginx.conf ← reverse proxy + intégration SSO +└── scripts/ + ├── install / remove + ├── upgrade + └── backup / restore +``` + +### Chaîne de publication + +Compilation **locale**, puis dépôt manuel de l'archive en release sur le Gitea de l'utilisateur, et mise à jour du `sha256` dans le `manifest.toml`. Prévoir un **script de build** encapsulant ces étapes, écrit pour être réutilisable tel quel dans une CI (Gitea Actions) si l'utilisateur bascule plus tard. + +**Ne jamais compiler sur le serveur** à l'installation : cela imposerait le SDK .NET complet sur la machine YunoHost, pour une compilation lente — l'inverse exact de ce que permet le self-contained. + ## Modèle de données (base de départ, à affiner) ``` @@ -241,8 +296,10 @@ Conclusion : aucune des deux solutions existantes ne coche toutes les cases (pr ## Questions ouvertes -Les grands choix structurants ont été tranchés le 2026-08-17 (offline, portée des données, sources ISBN, SSO, ebooks). Restent : +**Tous les choix structurants ont été tranchés le 2026-08-17** — voir le tableau des décisions. Le cadrage est clos, le développement peut commencer. -- **Choix de la notice quand la BnF en renvoie plusieurs** pour un même ISBN : proposer le choix à l'utilisateur, ou retenir la plus récente. À trancher au moment d'écrire l'écran d'ajout. -- **Support technique du cache hors-ligne** : IndexedDB ou cache du service worker sur les routes `GET`. À trancher au moment de l'implémenter, une fois les écrans connus. -- **Activation de l'AOT WASM** (`RunAOTCompilation`) : à décider après mesure du scan sur un vrai téléphone. Ne pas l'activer par défaut, le build devient nettement plus lent. +Points à réévaluer en cours de route, sans blocage : + +- **AOT WASM** : mesurer le scan sur un vrai téléphone une fois fonctionnel. Activer `RunAOTCompilation` seulement si la fluidité est insuffisante. +- **Runner Gitea Actions** : à vérifier le jour où l'utilisateur voudra automatiser les releases. +- **Wikidata en 3ᵉ source ISBN** : uniquement si la cascade BnF → OpenLibrary montre ses limites en usage réel.