11 KiB
Décisions architecturales 0.2.0-dev.3
Les décisions sont ajoutées au fil des checkpoints. Les modèles existants sont privilégiés avant toute nouvelle table.
D-005 — Centre de configuration permanent et setup progressif
CONTEXTE : le setup initial ne doit pas devenir une page jetable ; une GMAO utile doit accepter une configuration partielle et expliciter les actions restantes.
OPTIONS ÉTUDIÉES : checklist statique de fin d'installation ; tableau calculé et permanent avec liens d'action.
CHOIX : créer/faire évoluer un Centre de configuration permanent, organisé par domaines (Essentiel, Maintenance, Patrimoine, Entreprises, Compteurs, Cartographie technique, Intégrations), avec états calculés et intégrations facultatives non bloquantes.
JUSTIFICATION : rendre la configuration progressive observable et exploitable sans SQL ni connaissance de l'architecture.
CONSÉQUENCES : chaque contrôle doit avoir une règle de calcul et une destination UI ; Pronote, ENT, Outlook, Yeastar, IA, compteurs, logements et cartographie restent facultatifs.
DATE/COMMIT : 2026-08-23 / préparation checkpoint B.
D-006 — RoomType structurel, RoomProfile séparé à étudier
CONTEXTE : RoomType classe actuellement les locaux et est utilisé par Pronote et les écrans de patrimoine, mais ne porte aucun catalogue d'équipements, de quantités ou d'ouvrages.
OPTIONS ÉTUDIÉES : enrichir RoomType ; créer un RoomProfile distinct relié à RoomType ; stocker des JSON dans RoomType.
CHOIX : RoomProfile séparé, avec RoomProfileItem et RoomSurface normalisés. RoomType reste structurel et n'est pas modifié.
JUSTIFICATION : éviter de casser les usages de classification/enseignement et permettre plusieurs profils de proposition pour un même type structurel.
CONSÉQUENCES : migrations k6f7a8b9c0d1 et l7a8b9c0d1e2 ajoutées ; association de profil nullable ; aucune création automatique d'équipement sans validation utilisateur.
DATE/COMMIT : 2026-08-23 / implémentation checkpoint B en cours.
D-007 — Origine d’une proposition de profil
CONTEXTE : une réapplication d’un RoomProfile doit ajouter uniquement le delta sans rechercher les équipements par nom.
OPTIONS ÉTUDIÉES : comparaison fragile nom/catégorie ; table de liaison ; identifiant nullable sur Equipment.
CHOIX : ajouter Equipment.room_profile_item_id, nullable, indexé et relié à RoomProfileItem. Les équipements historiques sans origine restent valides.
JUSTIFICATION : l’identifiant de proposition est stable, compatible avec les noms en doublon et permet une idempotence explicite sans mutation silencieuse.
CONSÉQUENCES : migration non destructive m8b9c0d1e2f3; le service commun renseigne l’origine lors de l’application d’un profil.
DATE/COMMIT : 2026-08-23 / checkpoint B.
D-008 — Centre de configuration sans faux état d’erreur
CONTEXTE : le lot d’un équipement est facultatif et les modèles de contrats exposent des colonnes ORM dont certaines propriétés métier ne sont pas directement filtrables.
CHOIX : afficher un équipement sans lot comme information facultative ; filtrer les contrats via Contract.__table__.c pour éviter les erreurs de rendu du Centre.
JUSTIFICATION : une configuration progressive ne doit pas bloquer l’inventaire ni produire une page de synthèse cassée.
CONSÉQUENCES : les liens du nouveau menu pointent vers Centre, profils, bulk et horaires ; les intégrations avancées restent facultatives.
DATE/COMMIT : 2026-08-23 / validation B.
D-000 — Checkpoints indépendants
CONTEXTE : le chantier couvre plusieurs domaines avec migrations et risques différents.
OPTIONS ÉTUDIÉES : un gros développement continu ; checkpoints commitables.
CHOIX : checkpoints A à E, chacun documenté, testé et versionné.
JUSTIFICATION : reprise fiable, absence de régression masquée, dépôt source de vérité.
CONSÉQUENCES : aucun checkpoint suivant ne démarre avant validation du précédent.
DATE/COMMIT : 2026-08-23 / initialisation.
D-001 — Service de création Equipment
CONTEXTE : les routes fiche avancée et wizard construisaient des objets différents et le wizard retrouvait ensuite des équipements par nom.
OPTIONS ÉTUDIÉES : conserver les routes indépendantes ; centraliser la construction dans un service.
CHOIX : core.services.equipment_creation.create_equipment, lot et catégorie facultatifs, retour de l'instance persistée.
JUSTIFICATION : évite les collisions de noms et garantit la même gestion de quantité, parent, localisation et génération préventive.
CONSÉQUENCES : les anciens parcours sont progressivement migrés ; les relations techniques restent hors parent_id.
DATE/COMMIT : 2026-08-23 / checkpoint A en cours.
D-011 — Échéances et tournées de relevés C2
CONTEXTE : un relevé est un travail opérationnel planifiable, mais ne doit pas être modélisé comme une intervention. Les fréquences simples ne suffisent pas pour les dates contractuelles et les logements.
CHOIX : créer MeterReadingSchedule pour la règle, MeterReadingOccurrence pour chaque échéance logique, MeterReadingRound/MeterReadingRoundMember pour la définition d'une tournée et MeterReadingRoundOccurrence pour sa réalisation datée. L'unicité (schedule_id, target_date) et l'unicité d'une occurrence de tournée par date rendent la génération idempotente.
La date cible reste distincte de la date opérationnelle. L'anticipation réutilise le moteur horaire/calendrier existant pour les règles scolaires ; les logements sont hors calendrier scolaire par défaut. Sans horaires explicites, le système conserve la date cible plutôt que d'inventer un jour travaillé.
TRAITEMENT : une occurrence avec relevé appelle le service C1 record_meter_reading. Une occurrence sans relevé conserve un motif distinguant notamment inaccessible, absent, refus et relevé non connu, sans créer de mesure artificielle. Une occurrence ouverte d'un compteur remplacé est annulée avec une raison système et reste historisée.
INTÉGRATION : les occurrences sont une source du DayPlanner, avec responsable, durée et retard calculé ; elles ne créent pas d'intervention et ne simulent pas de créneau si le planificateur ne sait pas en attribuer un. Les routes de configuration sont administrateur ; le traitement d'une occurrence est limité à l'utilisateur assigné ou à un administrateur.
LIMITES C2 : génération à horizon borné autour de « Ma journée » (365 jours de regard arrière et 31 jours d'avance) ; aucune analyse de consommation, conversion, alerte, coût, contrat ou quota n'est implémentée.
DATE/COMMIT : 2026-08-24 / checkpoint C2.
D-009 — Rattachement explicite des compteurs
CONTEXTE : les compteurs historiques étaient obligatoirement rattachés à Equipment, alors que l'exploitation nécessite aussi des compteurs de bâtiment, zone, local et logement.
OPTIONS ÉTUDIÉES : cible polymorphe scope_type/scope_id ; FK nullable distinctes ; création d'un faux équipement pour chaque compteur patrimoine.
CHOIX : conserver equipment_id nullable et ajouter building_id, zone_id, room_id et housing_unit_id, avec une contrainte SQL imposant exactement un rattachement principal. Room est supporté directement.
JUSTIFICATION : les FK garantissent l'intégrité référentielle MariaDB, rendent les requêtes explicites et évitent le faux équipement. Le polymorphisme aurait supprimé les FK natives et complexifié les jointures.
CONSÉQUENCES : l'index historique des compteurs Equipment reste valide ; les listes ne font plus de join(Equipment) obligatoire ; migration non destructive n9c0d1e2f3g4.
D-010 — Hiérarchie, relevés audités et remplacement
CHOIX : Meter.parent_id porte une hiérarchie indépendante d'Equipment.parent_id, avec plusieurs racines possibles et validation des cycles. MeterReading reste une mesure physique dans l'unité native. record_meter_reading est le service unique ; une baisse exige un reset explicite et justifié. Une correction met à jour la mesure tout en conservant ancienne valeur, nouvelle valeur, auteur, date et justification dans MeterReadingCorrection. Un remplacement crée une nouvelle identité reliée par replaces_meter_id et clôt l'ancien compteur.
PHOTOS : une photo facultative est stockée sur le relevé (photo_filename, photo_path) en réutilisant les extensions et la racine d'upload existantes ; aucune association artificielle à EquipmentDocument.
HORS C1 : échéances, consommations, coefficients gaz, alertes, coûts, contrats et quotas restent respectivement C2, C3 et C4.
DATE/COMMIT : 2026-08-23 / checkpoint C1.
D-003 — Catégorie et lot facultatifs
CONTEXTE : un inventaire peut être saisi avant que le référentiel de maintenance soit complet.
OPTIONS ÉTUDIÉES : bloquer toute création sans lot ; accepter un équipement incomplet et le compléter plus tard.
CHOIX : la création reste valide sans lot (et sans catégorie dans les parcours wizard) ; un lot fourni est validé et peut déclencher la génération préventive.
JUSTIFICATION : respecter le principe de configuration progressive sans fabriquer de maintenance implicite.
CONSÉQUENCES : l'interface doit pouvoir signaler ultérieurement « Lot non renseigné » ; les relations techniques restent indépendantes.
DATE/COMMIT : 2026-08-23 / checkpoint A.
D-004 — Versionnement du checkpoint A
CONTEXTE : le chantier interdit 0.1.0-dev.13 et demande des versions correspondant à des checkpoints réellement validés.
CHOIX : le checkpoint A validé passe de 0.1.0-dev.12 à 0.2.0-dev.1 ; B, C, D et E restent séparés.
JUSTIFICATION : la création Equipment est consolidée et testée sans nouvelle régression ; les erreurs restantes sont exactement la baseline historique.
CONSÉQUENCES : Docker doit être reconstruit avec la nouvelle version ; aucune migration n'est ajoutée au checkpoint A.
DATE/COMMIT : 2026-08-23 / version commit.
D-002 — Durée d'intervention inconnue
CONTEXTE : Intervention.effective_estimated_duration retournait silencieusement 60 minutes.
CHOIX : retourner 0 si aucune estimation ou moyenne historique n'existe ; DayPlanner affiche alors une tâche sans durée à renseigner.
JUSTIFICATION : ne pas présenter une estimation arbitraire comme une contrainte métier.
CONSÉQUENCES : les statistiques historiques restent inchangées ; les workflows doivent renseigner les interventions planifiables.
DATE/COMMIT : 2026-08-23 / checkpoint A en cours.