<p align="center"><img src="resources/branding/Logo_Globinours_maxi.png" alt="Logo Globinours" width="180"></p>
<h1 align="center">Globinours</h1>
<p align="center"><strong>Nouveau :</strong> suivi structuré des chirurgies et comptabilité vétérinaire légère (factures, avoirs, règlements et justificatifs privés).</p>
<p align="center">Les factures sont corrigeables depuis leur ligne et leur suppression passe par une corbeille qui les exclut des totaux sans effacer la preuve.</p>
<p align="center">Le pilotage comptable analyse les paiements par structure et par année, les échéances, les règlements et le coût moyen rapproché des animaux, avec exports CSV et impression PDF.</p>
<p align="center">Les factures se filtrent par recherche, année, structure, statut, type de pièce et moyen de règlement ; les indicateurs et l’export suivent le même périmètre.</p>
<p align="center"><strong>La gestion quotidienne d’un refuge, pensée pour rester humaine, rapide et lisible.</strong><br>Né de l’histoire de Twix, conçu pour protéger les suivants.</p>
<p align="center">
  <img alt="PHP 8.1+" src="https://img.shields.io/badge/PHP-8.1%2B-777BB4?logo=php&logoColor=white">
  <img alt="SQLite" src="https://img.shields.io/badge/SQLite-WAL-003B57?logo=sqlite&logoColor=white">
  <img alt="Interface française" src="https://img.shields.io/badge/interface-fran%C3%A7aise-E8A838">
  <img alt="Application légère" src="https://img.shields.io/badge/application-l%C3%A9g%C3%A8re-2FB344">
  <img alt="En développement" src="https://img.shields.io/badge/%C3%A9tat-en%20d%C3%A9veloppement-F59F00">
</p>

---

## 🐾 Le projet

Globinours est une application web de gestion de refuge animalier, développée à partir de besoins concrets observés sur le terrain.

Elle centralise les animaux, leur santé, leurs documents, leurs liens familiaux, les familles d’accueil, les contacts et les actions quotidiennes. Son objectif est simple : permettre aux bénévoles et responsables de trouver ou saisir une information en quelques secondes, sans traverser une succession d’écrans complexes.

Globinours privilégie :

- une interface claire et entièrement française ;
- un fonctionnement rapide sur ordinateur comme sur tablette ;
- une installation légère, sans framework serveur ni dépendances Composer ;
- la traçabilité des actions importantes ;
- la maîtrise locale des données du refuge.

Une recherche globale accessible par `Ctrl+K` ou `⌘K` retrouve instantanément animaux, contacts, événements et factures. Chaque utilisateur ne voit que les catégories autorisées par son rôle ; aucune note ni pièce médicale sensible n’est indexée.

L’identité de l’association est personnalisable, logo compris. Ce logo est conservé dans l’espace privé de l’installation, sauvegardé avec les données et prévu pour alimenter les documents officiels.

Le pied de page identifie clairement le projet, son année de développement, sa version et son développeur, [OverSu](https://oversu.fr), avec un accès direct au [code source](https://nnsprod.com/git/oversu/Globinours).

Le récit complet est conservé dans l’[Histoire de TWIX et Globinours](HISTORIQUE.md). Les changements techniques et fonctionnels sont consignés dans le [CHANGELOG](CHANGELOG.md). La feuille de route synthétique reste disponible plus bas et sa version illustrée dans l’application via **Évolutions**.

## 🐈 De TWIX à Globinours

Le projet est né au sein d’un refuge pilote, face à un constat très concret : les logiciels existants répondaient mal au travail quotidien. Les informations restaient dispersées, certaines opérations exigeaient trop de manipulations et des besoins vétérinaires ou administratifs essentiels manquaient.

L’ambition initiale n’était pas de construire un produit commercial, mais un compagnon de travail **pensé par un refuge, pour un refuge**. Le premier nom du logiciel fut **TWIX**, en hommage au premier chat sauvé par l’association.

Les premières versions reposaient déjà sur une architecture volontairement légère : PHP, SQLite, Bootstrap puis Tabler, une organisation modulaire et DomPDF pour les premiers documents. SQLite s’est imposé pour quatre raisons : aucune infrastructure de base de données complexe, sauvegardes simples, déplacement facile de l’installation et adaptation aux petites structures.

La fiche animale est devenue le premier véritable cœur fonctionnel, avant que le suivi vétérinaire — traitements, vaccins, protocoles, quarantaines, soins, poids et graphiques — puis la production documentaire ne prennent une place centrale. L’ergonomie est ensuite devenue un chantier permanent : réduire les clics, accélérer la saisie et préserver la lisibilité sur des écrans utilisés plusieurs centaines de fois par semaine.

Lorsque le projet a commencé à pouvoir servir d’autres associations, son code et son identité ont été progressivement ouverts et réorganisés. **TWIX est alors devenu Globinours**, surnom affectueux du même chat. La nouvelle identité graphique conserve cette histoire à travers une silhouette féline inspirée de Twix, des formes simples et des couleurs chaleureuses.

L’architecture a continué à s’alléger : DomPDF et les dépendances Composer ont finalement été remplacés par l’impression HTML/CSS du navigateur pour les fiches générées, tandis que LibreOffice reste utilisé pour convertir les modèles ODT lorsque cela est nécessaire.

## ✨ Ce que propose Globinours

### Gestion complète des animaux

- gestion multi-espèces : chats, chiens, NAC, animaux de ferme, faune sauvage et espèces personnalisées ;
- référentiel administrable avec catégorie, libellé, icône, couleur, ordre et désactivation sans perte des dossiers existants ;
- choix de l’espèce à la création, filtre dédié et badge visuel dans le listing ; les fonctions strictement félines, comme le FIV/FeLV et les portées, restent réservées aux chats ;
- identité, statut, localisation, âge, sexe, robe, race et identification ;
- historique automatique des changements de statut, salle, box et adresse, avec état avant/après et utilisateur responsable ;
- profil de vie en trois états — oui, non ou inconnu — pour les chiens, chats, enfants et la propreté, avec lecture compacte et tris dédiés dans le listing ;
- entrée structurée avec date, mode, motif, déposant lié à l’annuaire, commune d’origine et circonstances, synchronisée avec le registre administratif ; les décès et entrées en EHPAD du propriétaire sont distingués ;
- listing opérationnel limité par défaut aux animaux vivants actuellement pris en charge, avec accès filtré aux dossiers adoptés, décédés ou enfuis ;
- choix mémorisé par utilisateur entre un tableau détaillé et une mosaïque photographique responsive pouvant afficher sept animaux par ligne ;
- suivi FIV/FeLV, stérilisation, poids, vaccins, traitements, ordonnances, analyses biologiques et notes médicales ;
- traçabilité vaccinale du fabricant, du lot et de son expiration, du vétérinaire et de la personne ayant réellement administré le vaccin ;
- historique chronologique attribué aux utilisateurs ;
- ouverture systématique des fiches sur l’onglet Identité, sauf lorsqu’une action redirige explicitement vers un onglet concerné ;
- exports CSV unitaires ou regroupés en ZIP pour assurer la portabilité des données ;
- dossier de décès avec cause, contexte, vétérinaire, crématorium et prise en charge ;
- registre des sorties synchronisé avec les modifications du dossier de décès ;
- parcours chronologique des réservations, placements en famille d’accueil, adoptions définitives, retours et annulations, sans mode d’essai ;
- photos publiques, privées et médicales ;
- mini-site public facultatif alimenté par les animaux disponibles à l’adoption, avec trois thèmes légers, page libre, dons et contact ;
- aperçu agrandi des photos directement au survol du listing ;
- orientation, redimensionnement et compression automatiques des nouvelles images, avec suppression de leurs métadonnées ;
- archivage, corbeille et restauration ;
- fiche A4 imprimable ou enregistrable en PDF ;
- cartographie des lieux de récupération et d’accueil ;
- parcours des chats libres avec site ou colonie, commune, localisation interne, référent, capture, remise en liberté et état de suivi ;

### Portées et groupes inséparables

- création rapide d’une portée et de ses chatons ;
- parents connus, partiellement connus ou inconnus ;
- génération automatique des noms ;
- regroupement visuel des frères et sœurs ;
- groupes d’animaux devant être adoptés ensemble.

### Suivi médical et tournées sur tablette

- tournée du matin ou du soir ;
- salles collectives ou compartimentées entièrement configurables (nom, couleur, ordre et statut associé), avec deux salles collectives, une infirmerie et une quarantaine proposées par défaut ;
- nombre et libellé des box adaptables à chaque refuge, sans effacer l’historique des espaces désactivés ;
- plusieurs animaux par box ;
- traitements attendus affichés pendant la tournée ;
- référentiel de médicaments trié alphabétiquement et création à la volée lors du démarrage d’un traitement ;
- validation individuelle ou collective ;
- suivi de l’alimentation, de l’eau, des selles, des urines et de l’état général ;
- commentaire et photo en cas d’anomalie ;
- incidents ajoutés à l’historique de l’animal.

### Annuaire du refuge

- familles d’accueil, bénévoles, dirigeants et adoptants ;
- déposants, vétérinaires, cabinets et crématoriums ;
- personnes et structures distinguées visuellement ;
- lignes et fiches d’annuaire cliquables réunissant coordonnées, rôles, rattachements et animaux liés ;
- compteur d’animaux adoptés dans le listing et historique des adoptions sur la fiche de l’adoptant, y compris pour les animaux archivés ou décédés lorsque le lien historique existe ;
- outil de réconciliation des adoptions I‑CAD, exécutable d’abord en simulation puis avec sauvegarde et transaction, pour restaurer ou créer les fiches historiques, adoptants, dates, placements, sorties et historiques ;
- fusion sécurisée des doublons de l’annuaire malgré l’ordre prénom/nom, les accents, la casse, les tirets et les fautes typographiques mineures, avec transfert de toutes les relations vers la fiche la plus complète ;
- recalcul de la photographie actuelle depuis le dernier placement : une adoption synchronise statut, archivage, adresse de l’adoptant, sortie et historique, et les futurs imports ASM3 appliquent automatiquement ce devenir ;
- possibilité de consolider les adoptions historiques attestées par le refuge lorsque l’export source est incomplet, en conservant leur provenance dans le parcours et l’historique ;
- correction des fiches archivées sans restauration : l’identité et les données administratives restent modifiables tandis que statut, emplacement et archivage sont protégés côté interface et serveur ;
- dépenses cumulées et détail par animal sur la fiche des structures facturantes ;
- création de contacts depuis certains formulaires médicaux ou d’adoption.

### Documents et administratif

- registre annuel des entrées et sorties ;
- bilans statistiques filtrables et imprimables par commune d’origine pour accompagner les demandes de subvention ;
- prise en charge de modèles ODT propres à chaque association depuis `resources/documents/` ;
- contrats d’adoption et documents d’abandon préremplis ;
- certificat de visite pré-adoption disponible en ODT et en PDF imprimable depuis l’administration ;
- documents pour bénévoles et familles d’accueil ;
- conversion PDF avec LibreOffice ;
- documents HTML A4 imprimables depuis le navigateur.

### Utilisateurs et protection des données

- connexion nominative ;
- rôles administrateur, responsable, bénévole et lecture seule ;
- journal d’audit et attribution des événements ;
- paramètres administrables pour l’identité de l’association, les tarifs, la quarantaine et la conservation des sauvegardes ;
- sauvegarde ZIP complète, téléchargeable et restaurable ;
- sauvegarde d’urgence automatique avant restauration.

## 📚 Documentation utilisateur

Le [manuel d’utilisation complet](docs/README.md) est écrit en Markdown et se consulte directement dans Forgejo. Son sommaire accompagne les bénévoles et responsables depuis la première connexion jusqu’aux animaux, soins, tournées, statistiques, documents et fonctions administratives. Des chapitres séparés couvrent les paramètres, permissions, sauvegardes, migrations ASM3, confidentialité, PWA et application Android.

La documentation suit les écrans réellement disponibles et reste versionnée avec le code : une installation donnée conserve ainsi le manuel correspondant à sa version.

Le projet possède également un **site promotionnel autonome** dans le dépôt voisin `Website/`. Cette vitrine statique, sans CDN ni compilation, présente clairement Globinours comme un « Logiciel de gestion de refuge » puis explique qu’il s’agit d’une application web utilisable dans un navigateur, sans installation sur les postes de l’équipe. Elle met en avant son origine bretonne avec le Gwen ha Du, illustre ses principaux parcours et prépare l’intégration d’une vidéo de démonstration sous-titrée.

Les repères français et bretons du site utilisent des drapeaux SVG locaux. Le bloc historique repose sur une silhouette cartographique réelle de la Bretagne, créditée dans le projet `Website`, et la grille fonctionnelle présente également la continuité par sauvegarde ainsi que le référentiel multi-espèces.

## 🖥️ Philosophie produit

Globinours ne cherche pas à devenir une suite universelle. Il couvre précisément le quotidien d’un refuge, avec des parcours courts et compréhensibles.

Le dashboard répond à la question **« Que devons-nous surveiller aujourd’hui ? »**. Les fiches animales conservent le détail. La tournée tablette accompagne le travail sur le terrain. L’espace administratif rassemble les documents et les futurs bilans annuels.

---

## 🛠️ Architecture technique

Application PHP rendue côté serveur, organisée autour de contrôleurs, services et vues :

```text
refuge/
├── app/
│   ├── Controllers/       # Routes et actions
│   ├── Services/          # Base, sécurité, documents, sauvegardes…
│   └── Views/             # Interfaces HTML/PHP
├── data/
│   ├── association/       # Fichiers propres à l’association
│   └── refuge.sqlite      # Base locale — à exclure de Git
├── migrations/            # Évolution versionnée de SQLite
├── public/                # Racine web, assets et médias
├── resources/
│   ├── branding/          # Identité visuelle livrée avec Globinours
│   └── documents/         # Modèles ODT locaux de l’association, non versionnés
├── storage/
│   ├── backups/           # Sauvegardes ZIP
│   └── logs/              # Journal PHP local et privé
├── tests/                 # Tests isolés sans base de production
├── CHANGELOG.md           # Historique versionné des changements
└── README.md
```

### Technologies

| Couche | Technologie |
|---|---|
| Serveur | PHP 8.1 ou supérieur |
| Données | SQLite, PDO, clés étrangères et journal WAL |
| Interface | HTML5, CSS, JavaScript natif et Tabler |
| Calendriers | Flatpickr en français |
| Graphiques | Chart.js |
| Cartographie | Leaflet et OpenStreetMap/Nominatim |
| Documents | ODT/XML, ZIP, LibreOffice headless et impression HTML/CSS A4 |
| Images | ImageMagick, WebP et conservation de l’original en mode de repli |
| Sauvegardes | ZipArchive, SHA-256 et contrôle d’intégrité SQLite |

Les bibliothèques d’interface (Tabler, Chart.js, Flatpickr et Leaflet) sont livrées dans `public/assets/vendor/`. Aucun CDN, `composer install` ni `npm install` n’est nécessaire pour utiliser l’interface sur le réseau local.

## 🔐 Sécurité

### Authentification

- mots de passe avec `password_hash()` et `password_verify()` ;
- minimum de 10 caractères dans l’interface ;
- régénération de l’identifiant de session après connexion ;
- expiration après 30 minutes d’inactivité et durée absolue de 12 heures, configurables par environnement ;
- verrouillage de 15 minutes après 5 échecs ;
- limitation complémentaire des échecs par adresse IP et comparaison factice pour les comptes inconnus ;
- comptes désactivables ;
- protection empêchant un administrateur de retirer ses propres droits.

### Sessions et requêtes

- cookies `HttpOnly` et `SameSite=Strict` ;
- attribut `Secure` activé sous HTTPS ;
- mode de session PHP strict et cookies uniquement, avec prise en charge explicite des reverse proxies de confiance ;
- jeton CSRF aléatoire vérifié sur les requêtes POST ;
- écritures autorisées selon le rôle ;
- redirections après connexion limitées aux chemins internes ;
- en-têtes `nosniff`, anti-iframe, HSTS sous HTTPS, politique CSP, politique de référent limitée à l’origine et permissions navigateur restrictives ;
- routes de maintenance limitées au mode développement, à la machine locale et aux administrateurs.

Les délais peuvent être adaptés avec `GLOBINOURS_SESSION_IDLE_SECONDS` et `GLOBINOURS_SESSION_ABSOLUTE_SECONDS`. Derrière YunoHost ou un autre reverse proxy non local, `GLOBINOURS_TRUSTED_PROXIES` doit contenir exclusivement ses adresses IP séparées par des virgules ; les en-têtes transférés provenant d’autres clients sont ignorés.

### Base et affichage

- requêtes paramétrées PDO et émulation désactivée ;
- clés étrangères SQLite activées ;
- échappement HTML des valeurs affichées ;
- migrations transactionnelles ;
- suppression logique des animaux avec possibilité de restauration.

### Téléversements et audit

- inspection MIME des photos côté serveur ;
- médias privés stockés hors de `public/`, servis uniquement par une route authentifiée et autorisée ;
- documents médicaux réservés aux rôles médicaux et chaque consultation privée journalisée ;
- audit nominatif des actions ;
- mots de passe et jetons CSRF exclus des métadonnées d’audit.

### Sauvegardes

- snapshot cohérent par `VACUUM INTO` ;
- manifeste versionné et empreinte SHA-256 de chaque fichier ;
- extraction fichier par fichier et rejet des chemins dangereux, liens symboliques et entrées absentes du manifeste ;
- `PRAGMA integrity_check` avant restauration ;
- sauvegarde automatique avant remplacement ;
- reconnexion obligatoire après restauration.

### Exports

- accès réservé aux administrateurs et téléchargement journalisé ;
- CSV UTF-8 compatibles avec Excel et LibreOffice ;
- neutralisation des cellules pouvant être interprétées comme des formules ;
- exclusion des mots de passe, sessions, secrets de configuration et médias.

> [!IMPORTANT]
> L’application manipule des données personnelles et médicales. Une installation en réseau doit utiliser HTTPS, des permissions système restrictives et des sauvegardes externes.

## 📦 Prérequis

- PHP 8.1+ ;
- extensions `pdo_sqlite`, `sqlite3`, `zip`, `curl`, `fileinfo` et `mbstring` ;
- LibreOffice, facultatif mais nécessaire pour convertir les ODT en PDF ;
- ImageMagick, recommandé pour optimiser automatiquement les images téléversées ;
- écriture autorisée dans `data`, `public/media` et `storage` ;
- accès Internet uniquement pour les fonds cartographiques et les intégrations externes (géocodage, I-CAD, notifications distantes) ; le cœur de l’interface reste utilisable sans Internet.

Exemple Debian/Ubuntu :

```bash
sudo apt install php php-sqlite3 php-zip php-curl php-mbstring libreoffice imagemagick
```

## 🚀 Installation locale

```bash
git clone <URL_DU_DEPOT> globinours
cd globinours
```

Créer un fichier `.env` uniquement si les intégrations correspondantes sont utilisées :

```dotenv
ICAD_LOGIN=
ICAD_PASSWORD=
GEOCODER_EMAIL=contact@example.org
APP_ENV=production
```

Préparer les permissions puis lancer le serveur de développement :

```bash
chmod -R u+rwX data public/media storage
php -d upload_max_filesize=250M -d post_max_size=260M -d max_execution_time=600 -S 127.0.0.1:8000 -t public
```

Ouvrir `http://127.0.0.1:8000/setup`. L’assistant contrôle PHP, PDO SQLite, les extensions requises, ZIP, cURL, le traitement d’images et les droits d’écriture. Il affiche la racine publique à déclarer, recueille l’identité de l’association, la langue, le mode du mini-site et crée le premier administrateur. Les migrations SQL sont appliquées automatiquement au démarrage et l’assistant devient inaccessible dès qu’un compte existe.

Pour une démonstration temporaire à distance, le routeur `public/router.php` permet d’utiliser le serveur PHP intégré, puis un tunnel HTTPS éphémère. Cette méthode est réservée aux tests et doit être arrêtée après la présentation.

## 🌐 Déploiement

La racine du serveur web doit pointer vers `public/`, jamais vers la racine complète du projet. `data/` et `storage/` ne doivent pas être servis par HTTP.

Ainsi, si le projet se trouve dans `/var/www/globinours`, la racine documentaire du domaine doit être `/var/www/globinours/public`. L’adresse publique reste alors `https://refuge.example.org/` — il ne faut pas ajouter `/public/` dans l’URL. Le fichier `public/.htaccess` fourni redirige les routes applicatives vers `index.php` sur Apache ou LiteSpeed, sous réserve que les règles `.htaccess` soient autorisées.

Configuration Nginx équivalente dans le bloc du domaine :

```nginx
root /var/www/globinours/public;
index index.php;

location / {
    try_files $uri $uri/ /index.php?$query_string;
}
```

Le bloc PHP-FPM habituel de l’hébergeur doit ensuite exécuter les fichiers `.php`. Sur un panneau d’hébergement, ce réglage porte généralement le nom **Document root**, **Racine du document** ou **Dossier public**.

Avant la mise en production :

- activer HTTPS ;
- désactiver l’affichage public des erreurs PHP ;
- protéger `.env` et SQLite par les permissions système ;
- vérifier les limites PHP de téléversement ;
- créer et télécharger une sauvegarde depuis **Paramètres → Sauvegardes** ;
- copier régulièrement les ZIP vers un autre support.

Les routes internes `/dev/*` sont désactivées par défaut. Elles exigent simultanément `APP_ENV=development`, une connexion depuis la machine locale et un compte administrateur.

## 💾 Sauvegardes

Une archive Globinours contient la base, les photos, les médias médicaux, le logo personnalisé de l’association, les justificatifs privés des subventions et un manifeste d’intégrité. Les modèles et éléments graphiques livrés avec le logiciel restent dans `resources/` et ne sont pas dupliqués dans chaque sauvegarde. `.env` est volontairement exclu afin de ne pas diffuser les identifiants externes.

Les 10 sauvegardes les plus récentes sont conservées localement. Elles peuvent être téléchargées, supprimées et restaurées depuis l’interface.

## 🧪 Vérifications

L’organisation physique du dépôt et les éléments temporaires sont détaillés dans [l’audit des fichiers](docs/15-audit-structure-fichiers.md). Les anciennes sources de récupération résident dans le dossier voisin `ARCHIVES/Globinours-recuperation-2026/` et les scripts concernés demandent leur chemin explicitement. Les migrations SQL font partie intégrante de l’application et ne doivent jamais être supprimées d’un paquet ou d’un déploiement.

```bash
find app public -name '*.php' -print0 | xargs -0 -n1 php -l
php scripts/check_translations.php
php tests/run.php
```

La suite fonctionne sans Composer et crée une base SQLite temporaire hors du projet. Elle contrôle une installation vierge complète, les migrations, l’intégrité de la base, les paramètres, l’authentification, les permissions, un parcours médical et d’adoption, les alertes et le contenu des sauvegardes ZIP. Elle ne lit ni ne modifie la base du refuge.

## 🩺 Santé et notifications

**Paramètres → Santé de Globinours** exécute un diagnostic en lecture seule : versions PHP/SQLite, extensions, droits d’écriture, intégrité et relations SQLite, migrations, espace disque, âge de la dernière sauvegarde, médias absents ou orphelins, configuration des erreurs et erreurs journalisées durant les sept derniers jours. Les erreurs applicatives sont dirigées vers `storage/logs/php-errors.log`, hors de la racine publique.

Le dashboard conserve un unique bloc opérationnel « Points à surveiller ». **Paramètres → Notifications** réutilise ces échéances, complétées par les vermifuges et l’ancienneté des sauvegardes, pour envoyer leur résumé immédiatement ou préparer un envoi quotidien/hebdomadaire. L’hébergeur doit exécuter régulièrement :

```bash
php scripts/send-notifications.php
```

La commande respecte la fréquence et la date du dernier envoi. Elle utilise la fonction `mail()` de PHP : le transport de courrier reste donc à configurer sur le serveur.

## 🗺️ Feuille de route

| Étape | État | Contenu |
|---|:---:|---|
| Origines du projet | ✅ Historique | Besoin terrain d’un refuge pilote, socle PHP/SQLite, premières fiches animales, médical et documents PDF |
| Passage à Globinours | ✅ Historique | Ouverture à d’autres associations, réorganisation du code, nouvelle identité et hommage durable à Twix |
| Fondations | ✅ Livré | Animaux, portées, médical, annuaire, documents, adoptions et tournées tablette |
| Continuité | ✅ Livré | Utilisateurs, audit, sauvegarde/restauration, archives recherchables et triables, consultation des fiches archivées, corbeille et décès |
| Dashboard opérationnel | ✅ Livré | Synthèse des urgences, soins, échéances, quarantaines, poids, tournées du jour et qualité des fiches |
| Statistiques du refuge | ✅ Livré | Comparaison N−1, activité, médical, profils, couleurs, races, âges, origines, séjours et photographie actuelle |
| Bilans communaux | ✅ Livré | Filtre annuel ou global, villes cliquables, indicateurs recalculés, impression et couverture distinguant communes documentées, déduites par fratrie et inconnues |
| Rôles et permissions | ✅ Livré | Accès par groupe et par module, séparation voir/modifier, navigation adaptée et contrôle serveur |
| Lieux de vie | ✅ Livré | Chronologie avant/après des statuts, salles, box, familles et adresses, attribution utilisateur et export CSV |
| Médias plus légers | ✅ Livré | Compression, orientation, redimensionnement et nettoyage des métadonnées à l’import |
| Bilans annuels et subventions | ✅ Livré | Statistiques, bilan, demandes, checklist intelligente, validité des pièces, alertes et coffre documentaire privé |
| Portabilité | ✅ Livré | Exports CSV par domaine et archive ZIP complète, sans secrets ni mots de passe |
| Nettoyage et durcissement | ✅ Livré | Migrations strictes, erreurs non divulguées, routes DEV verrouillées, HTML et intégrité SQLite contrôlés |
| Profil de vie | ✅ Livré | Compatibilité chats, chiens et enfants, propreté en trois états et indicateurs compacts dans le listing |
| Entrées structurées | ✅ Livré | Mode et motif d’entrée, déposant, commune de provenance, circonstances, registre synchronisé et statistiques dédiées |
| Situations du propriétaire | ✅ Livré | Décès, santé ou hospitalisation et entrée durable en EHPAD/établissement distingués dans les fiches, exports et statistiques |
| Traçabilité vaccinale | ✅ Livré | Fabricant, lot, expiration, intervenant réel, vétérinaire et distinction avec l’utilisateur ayant saisi l’acte |
| Référentiel des médicaments | ✅ Livré | Sélection alphabétique et création à la volée du nom, de la molécule et de la forme depuis un nouveau traitement |
| Chats libres | ✅ Livré | Statut actif distinct du refuge, site ou colonie, référent d’annuaire, capture, remise en liberté, suivi et statistiques dédiées |
| Navigation des fiches | ✅ Livré | Identité ouverte par défaut et conservation des liens ciblés vers le médical, les photos, les portées et les autres onglets |
| Certificat pré-adoption | ✅ Livré | Modèle administratif vierge en ODT et aperçu PDF, à remettre au moins sept jours avant la cession |
| Identification structurée | ✅ Livré | Type, numéro, date de pose, statut d’enregistrement et synchronisation manuelle I-CAD compatible avec les formulaires actuels et historiques |
| Stérilisation structurée | ✅ Livré | État inconnu/non/oui, date, vétérinaire, cabinet et synchronisation depuis les notes médicales |
| Parcours d’accueil | ✅ Livré | Réservations, familles d’accueil, adoptions définitives, retours, annulations, contacts, motifs et registre synchronisé, sans essai d’adoption |
| Disponibilité à l’adoption | ✅ Livré | État à définir/non disponible/disponible, date d’ouverture, motif et filtre opérationnel du listing |
| Migration depuis ASM3 | ✅ Livré | Assistant administratif : exports MySQL ou PostgreSQL, analyse, simulation, sauvegarde transactionnelle et import des animaux, contacts, mouvements, médical, poids et portées, en fusion ou remplacement |
| Photothèque ASM3 | ✅ Livré | Rattachement DBFS, import idempotent, optimisation, visibilité publique et choix automatique des photos principales |
| Vues du listing | ✅ Livré | Tableau de gestion ou mosaïque photographique responsive, choix conservé par utilisateur et aperçu agrandi au survol |
| Filiation et familles d’accueil | ✅ Livré | Création d’une portée depuis des fiches existantes, rattachement ultérieur de chatons et sélection d’une FA de l’annuaire lors d’un changement d’emplacement |
| Réinitialisation et démonstration | ✅ Livré | Remise à zéro sécurisée ou chargement d’un jeu fictif depuis les paramètres, avec sauvegarde automatique et conservation des comptes et réglages |
| Gestion multi-espèces | ✅ Livré | Référentiel extensible, catégories, icônes et couleurs, filtre du listing, imports compatibles et fonctions félines affichées uniquement pour les chats |
| Mémoire des décès | ✅ Livré | Total historique complet, causes globales et séparation explicite entre décès datés et décès sans date certaine |
| Décès connus à l’année | ✅ Livré | Précision annuelle sans fausse date, âge au décès, décès après adoption et médailles mémorielles conservés dans les imports historiques |
| Statistiques historiques réconciliées | ✅ Livré | Entrées, sorties, adoptions, naissances, vaccinations et médical consolidés depuis les fiches métier, avec événements non datés séparés de la chronologie |
| Vermifuges | ✅ Livré | Catalogue distinct des médicaments (9 produits initiaux), historique structuré, échéances selon l’âge, rythme trimestriel adulte, administration groupée des portées et aperçu médical |
| Ordonnances et analyses | ✅ Livré | Documents privés, photo sur tablette, saisie verticale au clavier, résultats structurés, courbes et quatre bilans configurables par espèce : complet, rénal, hépatique et thyroïdien |
| Mini-site public | ✅ Livré | Accueil, navigation directe par espèce, fiches d’adoption, page libre, dons, contact cartographié, identité légale en pied de page, coordonnées protégées des robots simples et trois thèmes CSS légers |
| Installation guidée | ✅ Livré | Contrôle des prérequis et écritures, identité associative, langue, mode public, premier administrateur et verrouillage après installation |
| Santé et maintenance | ✅ Livré | Intégrité SQLite, migrations, stockage, sauvegardes, médias, configuration PHP et erreurs récentes depuis une page en lecture seule |
| Notifications | ✅ Livré | Réutilisation des alertes opérationnelles sans doublon visuel, résumé manuel ou planifié pour vaccins, traitements, vermifuges et sauvegardes |
| Tests automatisés | ✅ Socle livré | Base temporaire, installation vierge, migrations, intégrité, paramètres, authentification, permissions, médical/adoption, notifications et sauvegardes ZIP |
| Tarifs et coûts | ✅ Livré | Grilles de structures, coût net figé, résumé dédié dans la fiche animale et statistiques financières |
| Navigation des paramètres | ✅ Livré | Une liste unique garantit les mêmes rubriques, icônes et ordre dans la roue et dans la navigation interne |
| Internationalisation | ✅ Livré | Interface, parcours métier, validations, impressions, confirmations sensibles et mini-site public couverts par des catalogues FR/EN contrôlés automatiquement |
| Annuaire structuré | ✅ Livré | Personnes et structures : familles d’accueil, vétérinaires, cabinets, fourrières, crématoriums, adoptants, bénévoles et partenaires |
| Fiches de l’annuaire | ✅ Livré | Lignes entièrement cliquables, animaux adoptés/accueillis/déposés — y compris archivés ou décédés —, personnes rattachées, compteur d’adoptions et dépenses cumulées des structures |
| Réconciliation I‑CAD | ✅ Livré | Consolidation transactionnelle des adoptants et dates d’adoption, création des fiches historiques manquantes et fusion contrôlée des doublons de contacts |
| Cohérence du parcours | ✅ Livré | Statut et emplacement recalculés depuis le dernier placement, historique et sortie synchronisés, corrections d’archives sans restauration |
| Confidentialité et conservation | ✅ Livré | Export d’un contact, anonymisation contrôlée précédée d’une sauvegarde, révision selon une durée configurable, registre des fichiers privés et pages légales du mini-site |
| Qualité de production | 🚧 En progression | Étendre les tests aux parcours HTTP complets et documenter la comparaison avec Animal Shelter Manager |
| Déploiement reproductible | ✅ Livré | Nginx/PHP-FPM/systemd, maintenance, sauvegarde avant mise à niveau, migrations contrôlées et retour arrière du code |
| Publication YunoHost | 🧪 Prêt à tester | Paquet v2 audité et bundle local signé disponibles ; valider installation, mise à niveau, sauvegarde et restauration sur une instance YunoHost avant de figer l’archive publique |
| Paquets ZimaOS et CasaOS | 💡 À étudier | Préparer des applications légères fondées sur Docker, avec volumes persistants, installation guidée et mises à niveau sauvegardées ; vérifier d’abord les contraintes propres à chaque catalogue |
| Interface mobile et PWA | ✅ Socle livré | Navigation tactile, formulaires et fenêtres adaptatifs, installation PWA sans mise en cache des données métier |
| Appareils de confiance | ✅ Livré | Session persistante 90 jours sans stockage du mot de passe, registre personnel et révocation unitaire ou globale |
| Wrapper Android | 🧪 APK debug livré | Dépôt Java natif autonome sans bibliothèque applicative, instance HTTPS configurable, WebView cloisonnée, cookies persistants, verrouillage par la sécurité Android et APK signé de test ; validation sur appareils à réaliser |

La roadmap illustrée et l’historique des grandes évolutions sont également consultables directement dans l’application depuis le lien **Évolutions** du pied de page. Le détail exhaustif destiné au suivi Git se trouve dans [CHANGELOG.md](CHANGELOG.md).

### Confidentialité et conservation

La rubrique **Paramètres → Confidentialité / RGPD** offre un export portable par contact et des durées distinctes pour adoptants, familles d’accueil, bénévoles et autres contacts. La liste de révision bloque les dossiers encore actifs ; l’anonymisation exige un motif, la confirmation d’une vérification humaine et une sauvegarde préalable. Les relations non nominatives nécessaires aux statistiques sont conservées. Le registre des accès aux fichiers privés possède sa propre rétention et peut être purgé par la maintenance planifiée, sans jamais supprimer automatiquement un contact.

## 💊 Pharmacie et stocks

La pharmacie sépare médicaments, vermifuges et vaccins. Chaque produit possède une unité et un seuil minimal ; chaque lot conserve quantité, fournisseur, coût unitaire, numéro et péremption. Réceptions, administrations, pertes et corrections forment un journal nominatif. Les vaccins et vermifuges peuvent consommer directement un lot depuis la fiche animale. Une consommation tarifée rejoint automatiquement le coût estimé de l’animal et les statistiques financières. Les seuils bas et péremptions sous trente jours alimentent les notifications.

## ⏱ Sauvegarde automatique vérifiée

La fréquence quotidienne ou hebdomadaire se règle dans **Paramètres → Sauvegardes**. La commande `php scripts/maintenance.php run`, appelée régulièrement par cron ou systemd, crée uniquement les archives arrivées à échéance. Chaque ZIP est immédiatement rouvert : manifeste, empreintes SHA-256 et intégrité SQLite doivent tous être valides avant que l’exécution soit considérée réussie. La même page permet de revérifier manuellement n’importe quelle archive.

## 📅 Agenda partagé

L’agenda réunit rendez-vous généraux ou vétérinaires, transports, visites pré-adoption et tâches. Chaque élément peut être relié à un animal, un contact, un utilisateur responsable et plusieurs bénévoles issus de l’annuaire, avec priorité, lieu, description, horaire ou journée entière et rappel. Les filtres isolent son propre agenda, un responsable, un bénévole, une catégorie ou une recherche ; les rappels médicaux peuvent être masqués temporairement. Globinours avertit lorsqu’une même personne reçoit deux missions qui se chevauchent. L’équipe choisit une vue mensuelle ou hebdomadaire ; ce choix est conservé sur son compte. Un clic dans l’espace libre d’une journée ouvre la création avec la date déjà renseignée, y compris au clavier. La période affichée peut être téléchargée au format iCalendar (`.ics`). Chaque utilisateur peut également créer un lien d’abonnement privé compatible avec les principaux agendas, puis le révoquer ou le régénérer ; seul son hash SHA-256 est conservé en base. Les répétitions quotidiennes, hebdomadaires et mensuelles sont développées dans le calendrier sans dupliquer les enregistrements. Les rappels vaccinaux, prochains vermifuges ainsi que les dates de début et de fin des traitements déjà enregistrés dans les fiches animales apparaissent automatiquement dans le calendrier et ouvrent directement la bonne section du suivi médical, sans double saisie. Les échéances sous vingt-quatre heures rejoignent le dashboard et les notifications. Les droits de consultation et de modification sont configurables par groupe comme les autres modules.

### Déploiement et YunoHost

Les exemples pour Nginx, PHP-FPM et le service de démonstration sont dans [`deploy/`](deploy/README.md). `scripts/update.sh` vérifie une archive de version, sauvegarde les données, conserve le code précédent, active le mode maintenance, applique les migrations et contrôle SQLite ; `scripts/rollback.sh` restaure explicitement un snapshot de code sans tenter de rétrograder silencieusement la base.

Après la finalisation du paquet YunoHost, la feuille de route prévoit l’étude de paquets **ZimaOS** et **CasaOS**. Globinours devra disposer d’une image reproductible, de volumes persistants clairement séparés et d’un parcours de sauvegarde et de mise à niveau sûr avant toute publication dans un catalogue.

Le paquet **YunoHost packaging v2** vit désormais dans un dépôt voisin léger, `yunohost/`, et ne duplique plus le code de Globinours. Après le premier tag stable, il téléchargera l’archive officielle avec contrôle SHA-256. Les données réelles, médias et documents privés vivront dans le répertoire persistant YunoHost et ne seront pas exposés par la racine web.

### Mobile, PWA et Android

L’interface dispose d’un socle responsive commun aux ordinateurs, tablettes et smartphones : barre supérieure défilable, navigation tactile, onglets horizontaux, formulaires lisibles sans zoom iOS, modales adaptées et zones d’action suffisamment grandes. Le manifeste PWA permet d’installer Globinours depuis un navigateur compatible. Son service worker ne met en cache que l’enveloppe graphique publique et jamais les pages authentifiées ni les données du refuge.

La connexion peut créer un appareil de confiance pendant 90 jours sans conserver le mot de passe. Chaque utilisateur retrouve ses appareils depuis le menu du compte et peut les révoquer individuellement ou tous ensemble. Le dépôt voisin `Android/` contient un wrapper Java fondé uniquement sur les API natives : choix d’une instance HTTPS, WebView limitée à ce domaine, ouverture des liens externes dans le navigateur, cookies persistants et déverrouillage par la sécurité biométrique ou le code Android. Un APK debug signé est fourni pour les essais, sans vocation à être publié sur un store.

### Remise à zéro et base de démonstration

La page **Paramètres → Données et démo** est réservée aux administrateurs. Elle propose deux opérations protégées par une phrase de confirmation : vider toutes les données métier, ou les remplacer par un jeu entièrement fictif. Sa fiche vitrine Twix réunit photographie, identité, quarantaine, consultation, traitement, poids, vaccination, vermifugation, antécédent résolu, prise de sang et rendez-vous d’agenda ; les autres animaux restent volontairement plus légers pour illustrer l’annuaire, une portée, un groupe inséparable, une famille d’accueil et un décès. Une sauvegarde ZIP complète est créée avant chaque opération.

Les utilisateurs, rôles et permissions, paramètres de l’association, identité visuelle, modèles documentaires et sauvegardes existantes sont conservés. Les médias animaliers et justificatifs de subvention liés aux anciennes données sont retirés après validation de la transaction. Le jeu fictif est destiné aux démonstrations et ne doit jamais être confondu avec des données réelles.

### Analyser une sauvegarde ASM3

L’analyseur ne modifie ni le dump source ni la base Globinours. Il accepte les exports MySQL composés d’instructions `INSERT`, y compris lorsque leurs contenus occupent plusieurs lignes, ainsi que les sauvegardes PostgreSQL `.pgsql` utilisant les blocs `COPY ... FROM stdin`.

```bash
php scripts/asm3-analyze.php chemin/vers/dump.sql
php scripts/asm3-analyze.php chemin/vers/dump.sql --output rapport.md
php scripts/asm3-analyze.php chemin/vers/dump.sql --json
php scripts/asm3-plan.php chemin/vers/dump.sql plan-migration.json
php scripts/asm3-import.php chemin/vers/dump.sql
# Après lecture de la simulation uniquement :
php scripts/asm3-import.php chemin/vers/dump.sql --apply
php scripts/asm3-contacts.php chemin/vers/dump.sql
# Puis, après contrôle de la simulation :
php scripts/asm3-contacts.php chemin/vers/dump.sql --apply
php scripts/asm3-movements.php chemin/vers/dump.sql --apply
php scripts/asm3-clinical.php chemin/vers/dump.sql --apply
php scripts/asm3-litters.php chemin/vers/dump.sql --apply
# Reprendre les raisons d’entrée et les communes conservées en texte libre :
php scripts/recover-asm3-intake.php chemin/vers/dump.sql
php scripts/recover-asm3-intake.php chemin/vers/dump.sql --apply
```

Le premier rapport inventorie les tables et les domaines migrables. Le plan JSON convertit ensuite chaque fiche animale vers les champs Globinours et la classe en `create`, `match` ou `review`. Une identification identique ou le couple nom + naissance permettent un rapprochement sûr. Le code refuge n’est jamais utilisé seul entre deux sauvegardes historiques : ASM3 peut l’avoir réattribué après une remise à zéro et Globinours suffixe alors le code importé sans confondre deux animaux.

La reprise des entrées lit le champ ASM3 `REASONFORENTRY`, conserve son texte dans les circonstances et ne structure une commune que lorsqu’elle a été relue comme lieu réel de prise en charge. Une sauvegarde précède l’écriture et un CSV distingue les communes certaines des dossiers ambigus. Une seconde moulinette peut compléter les membres d’une portée lorsque la mère, les frères et sœurs, les dates et les codes refuge rendent le rapprochement solide : ces valeurs restent marquées `inferred_family`, accompagnées de leur justification, et ne sont jamais confondues avec une saisie documentée.

Les animaux nés sous la responsabilité du refuge restent volontairement sans commune de récupération : leur entrée structurée `born_in_care` / `birth` les distingue des origines réellement inconnues dans les statistiques. Une naissance au refuge n’est donc jamais transformée artificiellement en récupération sur la commune où se trouvent les locaux.

Les statistiques historiques réunissent une date d’entrée portée par la fiche et un éventuel mouvement d’entrée, avec dédoublonnage par animal. Lorsqu’un décès sous prise en charge possède une année certaine mais aucune date d’entrée, l’animal contribue au nombre de prises en charge de cette année sans être présenté comme une entrée datée. Les événements sans année restent dans « Toutes les années » et ne sont jamais répartis artificiellement.

```bash
php scripts/reconstruct-asm3-rescue-locations.php /chemin/dump_asm3.sql
php scripts/reconstruct-asm3-rescue-locations.php /chemin/dump_asm3.sql --apply
```

La première commande produit uniquement un rapport de simulation. L’application refuse tout conflit, crée une sauvegarde, synchronise le premier mouvement d’entrée et inscrit la justification dans l’historique. Les adresses de vétérinaires, adoptants ou tiers ne sont pas utilisées comme communes d’origine sans preuve explicite.

Les classeurs historiques 2022-2023 peuvent ensuite compléter les communes grâce au code, au nom et à l’espèce. Un identifiant réutilisé ne suffit jamais à lui seul et une même fiche retrouvée dans plusieurs communes reste dans le rapport des conflits.

```bash
php scripts/recover-2022-2023-xlsx.php /chemin/listing.xlsx
php scripts/recover-2022-2023-xlsx.php /chemin/listing.xlsx --apply
```

La même commande reconstitue, de façon explicitement estimative, la stérilisation des chats dont la première adoption connue intervient après six mois. Elle ne fabrique pas de date médicale : la date d’adoption sert uniquement de date comptable, le raisonnement et la source tarifaire restant inscrits sur la dépense et dans l’historique.

Lorsqu’un animal est attesté dans un registre mais absent de la base, il doit être recréé comme fiche historique distincte plutôt que fusionné avec le porteur actuel d’un ancien code réutilisé. Les informations certaines sont conservées ; dates, parentés ou actes non prouvés restent vides.

Les tarifs des partenaires doivent être saisis ou importés par chaque installation depuis ses propres sources. Aucune grille tarifaire réelle n’est livrée dans le dépôt.

Sans `--apply`, les commandes restent en simulation. En mode réel, elles exigent une confirmation textuelle, créent une sauvegarde, utilisent des transactions et mémorisent les correspondances ASM3 afin qu’une reprise ne duplique rien. Les rapprochements et cas ambigus ne sont jamais fusionnés automatiquement.

L’ensemble est également disponible sans terminal dans **Paramètres → Migration ASM3**. L’administrateur dépose un fichier `.sql` ou `.pgsql`, consulte les volumes et ambiguïtés, puis confirme l’import complet. Les animaux, contacts, rôles, adoptions, placements en FA, retours, vaccinations, historiques médicaux, poids et portées sont pris en charge. Les correspondances sûres sont reliées à la sauvegarde ancienne afin que leurs anciens événements rejoignent la bonne fiche actuelle. Si un dump ne contient que l’index des médias et pas leurs données binaires, l’assistant l’indique explicitement au lieu de créer des fichiers vides.

Lorsque les fichiers physiques ASM3 sont fournis séparément, l’importeur de photos recroise les tables `media` et `dbfs` avec les correspondances animales déjà mémorisées. Il commence par une simulation, vérifie chaque image, crée une sauvegarde complète, optimise les fichiers et les importe dans une transaction. Les photos sont publiques et la marque `WebsitePhoto` d’ASM3 désigne la photo principale ; les médias Globinours déjà présents sont conservés. Les liens techniques enregistrés rendent une relance idempotente.

Deux stratégies sont proposées dans l’interface : **Fusionner** conserve les données Globinours et ignore les rapprochements ambigus ; **Remplacer les données métier** vide les animaux, l’annuaire et leur historique opérationnel avant l’import. Ce second mode conserve les utilisateurs, rôles, paramètres de l’association et dossiers de subvention. Il exige la phrase `REMPLACER PAR ASM3`. Une sauvegarde est créée avant l’opération et nettoyage plus import sont réunis dans une transaction unique : une erreur annule l’ensemble.

La sauvegarde préalable ferme explicitement les curseurs SQLite de l’analyse avant la création de l’instantané, afin d’éviter tout verrou interne pendant `VACUUM INTO`. Les limites PHP réellement actives sont affichées sur la page de dépôt et les erreurs de téléversement sont traduites précisément en français.

Les animaux historiques importés par ASM3 restent accessibles dans **Animaux → Archives**. Cette vue reprend la recherche, les filtres et les tris du listing courant, notamment pour isoler les animaux décédés. Une fiche archivée peut être consultée avec son historique, son médical et ses documents, puis restaurée si nécessaire ; elle demeure exclue du suivi courant et des statistiques opérationnelles.

### Récupération d'archives fragmentaires

Un outillage complémentaire permet de reconstruire un historique à partir de sources hétérogènes lorsque la base d'origine est incomplète : exports I-CAD, contrats d'adoption numérisés et registre mémoriel des décès. Les scripts d'analyse produisent des CSV de rapprochement et séparent systématiquement les correspondances sûres, les anomalies et les dossiers à vérifier. L'import final fonctionne d'abord en simulation, crée une sauvegarde ZIP en mode réel, puis écrit animaux, contacts, entrées, sorties, adoptions, décès et fratries dans une transaction unique avec contrôle des clés étrangères.

Les décès dont la date exacte n'a pas pu être retrouvée restent enregistrés avec une précision `inconnue`, leur âge connu et les informations mémorielles disponibles. Ils sont visibles dans le dossier de l'animal sans être artificiellement attribués à une année dans les statistiques. Chaque élément importé conserve enfin un lien technique vers sa source afin de permettre un audit ou une reprise sans doublon.

La synthèse anonymisée des formulaires communaux est disponible dans [docs/ANALYSE_SUBVENTIONS.md](docs/ANALYSE_SUBVENTIONS.md).

### Bilans et demandes de subvention

L’espace **Administratif → Subventions et bilans** regroupe, année par année :

- les indicateurs calculés depuis les mouvements, adoptions, décès, portées, vaccinations et traitements, avec comparaison automatique à N−1 ;
- les répartitions par sexe, âge à l’entrée, origine, cause de décès et durée de séjour avant adoption ;
- les effectifs associatifs, le rapport d’activité et les projets ;
- une synthèse du réalisé, du prévisionnel, de la trésorerie et des contributions volontaires ;
- le suivi des demandes par commune ou organisme ;
- une checklist de dix pièces, avec formulaire officiel rattaché à son organisme et documents communs réutilisables ;
- les justificatifs PDF/ODT conservés hors du dossier public, contrôlés selon leur validité et inclus dans les sauvegardes ;
- une synthèse HTML optimisée pour l’impression ou l’enregistrement en PDF depuis le navigateur.

Les pièces sont classées comme valides, proches de l’expiration, expirées ou manquantes. Le dashboard signale uniquement aux rôles autorisés les échéances dépassées ou sous 30 jours, les dossiers incomplets et les documents à renouveler.

Cet outil prépare le noyau commun des dossiers, sans prétendre remplacer les formulaires officiels propres à chaque organisme.

## 📊 Statistiques internes

Le dashboard est la page d’accueil de Globinours et indique ce qui demande une action aujourd’hui. La page **Statistiques** le complète en analysant l’activité dans le temps. Une année peut être comparée à N−1 et étudiée par animaux distincts pris en charge, mouvements, adoptions, décès, naissances, activité médicale, sexe, âge à l’entrée, couleur, race, espèce, origine et durée de séjour. Le choix **Toutes les années** consolide l’historique complet et remplace le comparatif N−1 par une courbe ainsi qu’un tableau annuel. Les dossiers historiques sans année d’entrée connue figurent dans le total général, mais jamais dans une année arbitraire. Une photographie séparée décrit les animaux actuellement pris en charge afin de ne pas la confondre avec les données historiques.

Le dashboard signale également les fiches actives auxquelles il manque une date de naissance, un sexe, une couleur, une race, une origine, une identification, la confirmation I-CAD, l’état de stérilisation ou la disponibilité à l’adoption. Chaque compteur ouvre le listing déjà filtré. Les animaux explicitement non stérilisés sont présentés séparément comme information de suivi.

Les dépenses vétérinaires peuvent être analysées par commune d’origine, cabinet et catégorie d’acte. Globinours affiche le coût total, le nombre d’animaux du périmètre, ceux ayant réellement généré une dépense, la moyenne sur l’ensemble des animaux, la moyenne sur les seuls animaux avec frais et leur médiane. Cette lecture produit des chiffres directement exploitables pour argumenter une demande de subvention communale sans laisser un cas médical exceptionnel fausser toute l’analyse.

Dans le bilan par structure, chaque cabinet, crématorium ou fourrière identifié est cliquable. Sa fiche reprend exactement la période — et, le cas échéant, la commune — sélectionnée dans les statistiques, puis détaille le total payé ou facturé et chaque dépense par animal. Le refuge peut ainsi chiffrer objectivement son activité apportée à un partenaire pour une année donnée.

Pour une année, le périmètre financier comprend les animaux pris en charge pendant cette année ou ayant généré une dépense pendant celle-ci. Le bilan global utilise toutes les fiches non supprimées. La commune est déduite du lieu de récupération, jamais du cabinet vétérinaire ni de la famille d’accueil.

Les formulaires officiels des communes ne sont pas générés par Globinours : ils évoluent trop souvent pour garantir un résultat fiable. Le logiciel réunit plutôt les chiffres, le bilan et les justificatifs nécessaires à leur saisie.

## 🌐 Mini-site public

Le mini-site s’active dans **Paramètres → Site public**. Deux modes sont disponibles sans réécriture Apache ou Nginx : le mode intégré conserve Globinours à la racine et publie sous `/site` ; le mode domaine public affiche le site directement sous `/`, avec une entrée par espèce, `/dons` et `/contact`, tandis que `/gestion` conduit à la connexion ou au dashboard. `/site` reste un alias compatible. Son contenu reprend le logo et l’identité associative déjà configurés. Le pied de page publie l’adresse complète, le RNA et le SIRET lorsqu’ils sont renseignés. La page Contact positionne cette adresse sur une carte Leaflet dont la bibliothèque est embarquée localement ; sa fenêtre ouverte affiche le nom de l’association puis son adresse. Seules les tuiles cartographiques OpenStreetMap sont chargées à distance. Le téléphone et l’e-mail sont inversés dans le HTML puis remis dans le bon sens par CSS, sans lien `tel:` ou `mailto:` exposé aux robots simples. Trois thèmes très légers — chaleureux, naturel et minimal — reposent sur quelques variables CSS communes.

Une fiche publique n’existe que si l’animal est simultanément marqué **disponible à l’adoption** et **publié sur le mini-site**. Les requêtes publiques sélectionnent une liste limitée de colonnes : identité générale, âge, race, robe, compatibilités, stérilisation, présentation dédiée et photos marquées publiques. Notes, médical, identification, lieux internes, familles d’accueil et documents ne sont jamais chargés par ces routes. Le site désactivé renvoie une page 404 non indexable.

## 🔐 Rôles et permissions

Les accès sont attribués aux rôles — administrateur, responsable, bénévole et lecture seule — depuis **Paramètres → Rôles et permissions**. Chaque module distingue la consultation de la modification. La navigation, les formulaires, les actions et les fenêtres d’édition s’adaptent au rôle. Le serveur contrôle également chaque route afin qu’une URL saisie directement ne contourne pas la règle ; une page 403 intégrée explique clairement le refus.

Après la connexion, l’utilisateur est envoyé vers la première page autorisée à son rôle. Une ancienne URL mémorisée n’est reprise que si ce rôle peut réellement l’ouvrir.

Les administrateurs conservent obligatoirement tous les droits. La gestion des utilisateurs et permissions, les paramètres, les sauvegardes, les restaurations et le journal d’audit restent exclusivement administratifs. Chaque modification de la matrice est journalisée.

Les catégories de paramètres utilisent un ordre commun dans la roue crantée et dans la navigation interne : **Configuration**, **Référentiels métier**, **Accès** et **Maintenance**. Une rubrique ajoutée au référentiel de navigation apparaît donc automatiquement au même endroit dans les deux menus.

Le module médical est dépendant de la consultation des animaux. Sans droit médical, les onglets, statuts FIV/FeLV, traitements, vaccinations, décès, événements médicaux et documents contenant ces informations ne sont pas rendus dans la fiche.

## 🌍 Interface multilingue

L’interface applicative est disponible en français et en anglais. La langue globale se choisit dans les paramètres généraux ; le français reste le repli si une traduction manque. Les textes des écrans, formulaires, validations, cartes et impressions générées vivent dans `resources/lang/fr.php` et `resources/lang/en.php`. Les valeurs métier persistées — codes de statuts, imports ASM3, historiques et colonnes d’export — restent volontairement stables et indépendantes de la langue affichée.

Le contrôle `php scripts/check_translations.php` vérifie les clés utilisées, la parité complète des deux catalogues et la cohérence de leurs variables (`:name`, `:count`, etc.).

Les confirmations destructives sont elles aussi localisées et contrôlées côté serveur. Par exemple, la remise à zéro attend `VIDER LA BASE` en français ou `CLEAR DATABASE` en anglais ; le chargement de démonstration et la migration ASM3 suivent la même règle. La phrase attendue provient toujours du catalogue actif, jamais d’une constante cachée dans le contrôleur.

## 📣 Présentation publique du projet

Le site promotionnel autonome documente désormais précisément les publics visés, les différences avec une organisation par tableurs ou une solution généraliste, le parcours sécurisé de migration ASM3 et les trois modes de déploiement. La démonstration publique, les captures définitives et la vidéo finale sont volontairement réservées à la version 1.0. Le scénario, les sous-titres et la liste de vues à produire sont déjà préparés ; toutes les images devront provenir du jeu de données fictif intégré.

## ⚠️ Préparer le dépôt Git

Ne jamais publier les données réelles du refuge. Au minimum :

```gitignore
.env
data/refuge.sqlite*
data/association/**
public/media/**
!public/media/.gitkeep
storage/backups/**
storage/debug/**
storage/restore-*/
```

Les modèles ODT et les éléments graphiques propres à Globinours placés dans `resources/` peuvent être versionnés s’ils ne contiennent aucune donnée personnelle. Le logo téléversé par une association reste une donnée d’installation dans `data/association/`.

## 📄 Licence

Le code source de Globinours est distribué sous licence **GNU AGPLv3 ou ultérieure**. Elle autorise l’utilisation, l’étude, la modification et la redistribution, tout en demandant qu’une version modifiée proposée à travers un réseau rende également son code source correspondant accessible à ses utilisateurs. Consultez [LICENSE.md](LICENSE.md).

Les données d’une installation, les photographies, les documents privés, l’identité d’une association et les modèles fournis par des tiers ne deviennent jamais libres du seul fait qu’ils sont utilisés avec Globinours. Le nom et l’identité graphique Globinours ne doivent pas être employés pour faire passer une version modifiée pour une offre officielle.

---

<p align="center"><strong>Globinours</strong><br>Un outil léger, construit autour des animaux et des personnes qui prennent soin d’eux.</p>

### Candidates de publication 1.0

| Candidate | Date | État | Jalons principaux |
|---|---|---|---|
| `1.0.0-rc.1` | 2 septembre 2026 | Remplacée | Nettoyage du projet, première découpe de la fiche et du contrôleur animal, sauvegardes compatibles avec les volumes synchronisés. |
| `1.0.0-rc.2` | 2 septembre 2026 | Remplacée | Recherche universelle, second découpage du contrôleur animal et 23e test automatisé. |
| `1.0.0-rc.3` | 3 septembre 2026 | **Candidate gelée** | Squelette visuel et routes séparés, installation vierge corrigée, démonstration Twix complète, sources PHP harmonisées, 25 contrôles validés et gel fonctionnel. |

**Version candidate actuelle : `1.0.0-rc.3`.** Aucun nouveau développement fonctionnel n’entre désormais dans la branche 1.0 : seuls les défauts bloquants constatés pendant les dernières validations terrain peuvent être corrigés avant l’attribution de la version `1.0.0`.

Le résultat du contrôle de stabilisation est consultable dans [docs/AUDIT-1.0.md](docs/AUDIT-1.0.md).
