Faire évoluer la GMAO par checkpoints indépendants, reprenables et testables, depuis la consolidation de la création d'équipements jusqu'aux compteurs, au graphe technique et à la page « À documenter ».
- [x] Centre de configuration permanent, organisé en Essentiel, Maintenance, Patrimoine, Entreprises, Compteurs, Cartographie technique et Intégrations ;
- [x] états calculés « Configuré », « Incomplet », « À configurer », « Facultatif », « Attention » avec liens d'action ;
- [ ] périmètres Site, Building, Zone, Room, HousingUnit, Equipment et plusieurs compteurs par équipement ;
- [ ] périodicité de relevé, Ma journée, delta et consommation normalisée ; seuil absolu/relatif avec message « Surconsommation inhabituelle — fuite possible » ;
- [ ] calendrier scolaire contextuel pour collège, `school_calendar_aware=false` par défaut pour HousingUnit ;
- [ ] photocopieurs N&B/couleur, quotas globaux de contrat, agrégation, projection et historique de périmètre.
`0.2.0-dev.3` signifie une bêta utilisable au quotidien sur patrimoine, équipements, interventions, préventif, entreprises, planning, Ma journée, setup et Centre de configuration. Les fonctions avancées non configurées doivent rester non bloquantes.
Uniquement Alembic, non destructives, testées sur installation existante et neuve. Chaque checkpoint décide ses tables après audit des modèles existants.
## Risques / dépendances
- workflows historiques multiples pour Equipment ;
- données de test locales non équivalentes à une validation UI ;
- absence éventuelle de compte fonctionnel de validation ;
Un checkpoint est DONE quand son code, sa migration éventuelle, ses tests ciblés, le pytest complet, sa documentation, son statut et ses commits sont cohérents et poussés sur les deux dépôts configurés : Forgejo (`origin/main`) et GitHub principal (`audit/main`). `audit` désigne le remote du GitHub principal du projet ; il n'existe pas de troisième dépôt d'audit.
C2 introduit une règle `MeterReadingSchedule`, des occurrences bornées et idempotentes `MeterReadingOccurrence`, ainsi que les définitions et occurrences de tournées. Les fréquences hebdomadaire, mensuelle, semestrielle, annuelle et annuelle à date fixe sont conservées comme valeurs extensibles, sans enum SQL fermée. La date cible/contractuelle est conservée séparément de la date opérationnelle.
L'anticipation vers le dernier jour travaillé précédent réutilise `PlanningService.get_working_hours()` lorsque le périmètre est scolaire et qu'une configuration horaire explicite existe. Les compteurs de logements utilisent par défaut un périmètre hors calendrier scolaire. En l'absence d'horaires explicites, aucune fermeture n'est inventée et la date cible est conservée.
Les occurrences en retard restent ouvertes jusqu'à leur traitement. Le traitement avec valeur appelle `record_meter_reading()` ; le traitement sans relevé conserve un motif, un commentaire, l'utilisateur et l'horodatage sans créer de `MeterReading`. Le remplacement d'un compteur annule explicitement ses occurrences ouvertes lors de la génération suivante et ne crée plus d'occurrence future.
Les occurrences sont agrégées par `DayPlanner` dans « Ma journée » avec responsable, durée estimée et échéance, sans création de fausse intervention ni créneau horaire simulé. Une tournée regroupe les règles membres par position et expose une occurrence datée avec progression et reprise.