#:schema https://raw.githubusercontent.com/YunoHost/apps/master/schemas/manifest.v2.schema.json packaging_format = 2 id = "mabibli" name = "MaBibli" description.fr = "Gestion de bibliothèque personnelle : catalogue, prêts et scan ISBN" description.en = "Personal library manager: catalogue, loans and ISBN scanning" version = "0.4.0~ynh1" maintainers = ["mathieu"] [upstream] license = "AGPL-3.0-or-later" code = "https://git.akbar.nohost.me/mathieu/mabibli" [integration] yunohost = ">= 12.1.38" helpers_version = "2.1" # x86_64 uniquement : CLAUDE.md acte un serveur PC/VPS, et la chaîne de publication # ne produit qu'un binaire `linux-x64`. Déclarer d'autres architectures promettrait # des archives qui n'existent pas. architectures = ["amd64"] # Une seule instance : la bibliothèque est commune au foyer (CLAUDE.md, « Portée des # données »). Deux instances voudraient dire deux collections étanches, ce qui est # exactement ce que le projet a écarté. multi_instance = false # L'application ne parle pas à LDAP : elle lit l'identité dans les en-têtes que # SSOwat injecte. C'est bien une intégration SSO, mais pas une intégration LDAP. ldap = false sso = true # ~170 Mo de publish self-contained (runtime .NET embarqué), plus la base et la marge # de décompression de l'archive. disk = "500M" ram.build = "50M" ram.runtime = "200M" [install] [install.domain] type = "domain" # Pas de question `path` : MaBibli s'installe sur un domaine entier. # # Ce n'est pas un oubli. Le client Blazor WebAssembly fige son `` # et les empreintes de `service-worker-assets.js` **à la compilation**. Servir # l'application sous un sous-chemin demanderait de réécrire `index.html` sur le # serveur, ce qui invaliderait les empreintes d'intégrité du service worker et # casserait le mode hors-ligne. Comme le paquet ne compile rien sur le serveur, # la seule option honnête est le domaine entier. # # Conséquence côté YunoHost : `resources.permissions.main.url` étant une chaîne, # le cœur classe l'app en « full_domain » et refusera un changement d'URL vers # un sous-chemin. [install.init_main_permission] type = "group" default = "all_users" help.fr = "Qui peut accéder à la bibliothèque. MaBibli n'a pas de connexion propre : l'identité vient du portail YunoHost, et la collection est commune à toutes les personnes autorisées." help.en = "Who may access the library. MaBibli has no login of its own: identity comes from the YunoHost portal, and the collection is shared between all allowed users." [resources] [resources.sources.main] # Archive **déjà compilée** (publish self-contained linux-x64), produite par # `build/publier-release.sh` et déposée en release sur le Gitea de l'utilisateur. # Le SDK .NET n'est jamais installé sur le serveur : c'est tout l'intérêt du # self-contained (CLAUDE.md, « Ne jamais compiler sur le serveur »). # # Ces deux valeurs sont réécrites par `build/publier-release.sh`. amd64.url = "https://git.akbar.nohost.me/mathieu/mabibli/releases/download/v0.4.0/mabibli-0.4.0-linux-x64.tar.gz" amd64.sha256 = "09addf9b057ebd9b051a1a512a787a89ae78eca101c00a6905e62f5a4f122b64" # L'archive dépose ses fichiers à la racine, sans dossier intermédiaire. in_subdir = false # Pas d'`autoupdate` : les releases sont déposées à la main sur un Gitea privé, # aucune stratégie amont connue de YunoHost ne s'y applique. [resources.system_user] [resources.install_dir] # Le service tourne sous `mabibli` mais ne doit **pas** pouvoir réécrire ses # propres binaires : propriétaire root, application en lecture seule. Cela va de # pair avec `ProtectSystem=strict` dans l'unité systemd. owner = "root:rwx" group = "__APP__:rx" [resources.data_dir] # La base SQLite vit ici, et **pas** à côté du binaire : c'est ce qui permet à une # mise à jour de remplacer intégralement `install_dir` sans toucher aux données. owner = "__APP__:rwx" group = "__APP__:rx" [resources.permissions] # Toute l'application derrière le SSO, `/api` compris : la bibliothèque est # familiale, rien n'a vocation à être public. `auth_header` vaut `true` par # défaut, c'est lui qui autorise SSOwat à injecter `YNH_USER` — sans quoi # l'application ne saurait jamais qui la consulte. main.url = "/" main.auth_header = true [resources.ports] # Port interne uniquement. `exposed` vaut `false` par défaut : le pare-feu reste # fermé, et l'unité systemd n'écoute que sur 127.0.0.1. [resources.apt] # `sqlite3` sert aux sauvegardes : la base est en mode WAL (vérifié), un simple # `cp` du fichier `.db` ne suffit pas. Voir `scripts/backup`. packages = "sqlite3"