2026-08-23 15:41:43 +02:00
|
|
|
|
# Phase 2.1b — implémentation préventif et entreprises
|
|
|
|
|
|
|
|
|
|
|
|
## Baseline
|
|
|
|
|
|
|
2026-08-23 15:42:15 +02:00
|
|
|
|
- Version avant : `0.1.0-dev.10` ; version après : `0.1.0-dev.11`.
|
2026-08-23 15:41:43 +02:00
|
|
|
|
- Commit de départ : `e65e653`.
|
|
|
|
|
|
- Le dépôt était propre ; les services Docker local (Flask, MariaDB,
|
|
|
|
|
|
Adminer) étaient démarrés et `/health/` répondait.
|
|
|
|
|
|
- Les tests de référence restaient `152 passed, 1 failed, 1 error` ; l'échec
|
|
|
|
|
|
et l'erreur historiques concernent le lookback/contexte GMAO et son
|
|
|
|
|
|
teardown, hors périmètre.
|
|
|
|
|
|
|
|
|
|
|
|
## Ce qui est implémenté
|
|
|
|
|
|
|
|
|
|
|
|
### Durée et périmètre
|
|
|
|
|
|
|
|
|
|
|
|
`LotTask` expose maintenant :
|
|
|
|
|
|
|
|
|
|
|
|
- `duration_mode` : `unit`, `fixed` ou `zone` ;
|
|
|
|
|
|
- `scope_mode` : `dynamic` ou `manual` ;
|
|
|
|
|
|
- `executor_type` : `internal`, `external_company`, `department`, `mixed`,
|
|
|
|
|
|
`undefined`.
|
|
|
|
|
|
|
|
|
|
|
|
En mode `unit`, la durée d'une cible est `duree_minutes × quantity`. Une
|
|
|
|
|
|
quantité de groupe (par exemple 30 chaises) est donc respectée. En mode
|
|
|
|
|
|
`fixed`, la quantité ne multiplie pas le forfait. Le périmètre dynamique suit
|
|
|
|
|
|
les équipements actifs du lot ; le périmètre manuel utilise la sélection
|
|
|
|
|
|
explicitement enregistrée. Les tâches sans durée ont `estimated_duration=0`
|
|
|
|
|
|
et le statut technique `needs_duration`; elles ne sont pas proposées par
|
|
|
|
|
|
`DayPlanner` comme tâches planifiées.
|
|
|
|
|
|
|
|
|
|
|
|
Les valeurs historiques ne sont pas réintroduites comme vérité : le catalogue
|
|
|
|
|
|
reste idempotent et ne remplace jamais une personnalisation existante. Les
|
|
|
|
|
|
propositions de durée du document de référence restent à valider métier avant
|
|
|
|
|
|
d'être injectées en masse.
|
|
|
|
|
|
|
|
|
|
|
|
### Espaces verts
|
|
|
|
|
|
|
|
|
|
|
|
Les zones disposent de quatre durées facultatives propres à la zone : tonte,
|
|
|
|
|
|
bordures, haies et ramassage/évacuation. Elles sont éditables dans le
|
|
|
|
|
|
formulaire normal d'une zone et ne créent aucune durée générique dans un lot.
|
|
|
|
|
|
Le raccord automatique d'une règle de lot à ces quatre champs reste à faire
|
|
|
|
|
|
dans une passe ultérieure après validation du vocabulaire des tâches espaces
|
|
|
|
|
|
verts.
|
|
|
|
|
|
|
|
|
|
|
|
### Entreprises et passages
|
|
|
|
|
|
|
|
|
|
|
|
Les champs existants `company_id`, `contract_id`, `periodicite` et
|
|
|
|
|
|
`jours_entre_interventions` sont exposés dans la fiche de tâche, ainsi que le
|
2026-08-23 16:02:47 +02:00
|
|
|
|
type d'exécutant. La migration `i4d5e6f7a8b9` ajoute les modes `appointment`,
|
|
|
|
|
|
`date_only` et `open_window`, les heures/fenêtres, la date réelle, l'arrivée,
|
|
|
|
|
|
l'accompagnement et le technicien. La page **Passages & contrôles** permet
|
|
|
|
|
|
les actions Réalisée, Non venue et Entreprise arrivée. Un rendez-vous avec
|
|
|
|
|
|
heures est transmis à `DayPlanner` comme contrainte fixe ; les autres modes
|
|
|
|
|
|
restent informatifs et ne bloquent pas une plage horaire.
|
|
|
|
|
|
|
|
|
|
|
|
Le fichier `preventive_duration_proposals.py` embarque les **132** valeurs
|
|
|
|
|
|
numériques effectivement présentes dans la proposition documentaire. Elles
|
|
|
|
|
|
sont appliquées uniquement aux nouvelles lignes de catalogue dont la durée est
|
|
|
|
|
|
vide ; les personnalisations existantes ne sont jamais écrasées. L'écart avec
|
|
|
|
|
|
les 147 valeurs minimales annoncées doit être clarifié métier avant d'ajouter
|
|
|
|
|
|
des valeurs.
|
2026-08-23 15:41:43 +02:00
|
|
|
|
|
|
|
|
|
|
## Migration
|
|
|
|
|
|
|
2026-08-23 16:02:47 +02:00
|
|
|
|
`h3c4d5e6f7a8_phase21b_preventive_scope.py` et
|
|
|
|
|
|
`i4d5e6f7a8b9_phase21b_contract_visits.py` ajoutent sans perte :
|
2026-08-23 15:41:43 +02:00
|
|
|
|
|
|
|
|
|
|
- les trois colonnes de qualification à `lot_tasks` ;
|
|
|
|
|
|
- la table d'association `lot_task_equipments` ;
|
|
|
|
|
|
- les quatre durées d'espaces verts à `zones`.
|
2026-08-23 16:02:47 +02:00
|
|
|
|
- les données de passage entreprise à `contract_visits`.
|
2026-08-23 15:41:43 +02:00
|
|
|
|
|
|
|
|
|
|
La migration est additive et possède un downgrade. Elle n'attribue aucun
|
|
|
|
|
|
horaire, lot ou exécutant à `alban`.
|
|
|
|
|
|
|
|
|
|
|
|
## Tests ajoutés
|
|
|
|
|
|
|
2026-08-23 16:02:47 +02:00
|
|
|
|
`tests/unit/test_preventive_scope.py` et
|
|
|
|
|
|
`tests/unit/test_external_maintenance_visit.py` couvrent le calcul par
|
|
|
|
|
|
quantité, les modes de passage, le forfait par cible et l'absence explicite de durée. La compilation Python et le
|
2026-08-23 15:41:43 +02:00
|
|
|
|
chargement des modèles passent. La suite intégration locale est actuellement
|
|
|
|
|
|
bloquée par l'erreur historique de teardown (`equipment_lifecycle_events`
|
|
|
|
|
|
absente de la base de test), déjà présente avant cette passe.
|
|
|
|
|
|
|
|
|
|
|
|
## État de validation
|
|
|
|
|
|
|
2026-08-23 16:02:47 +02:00
|
|
|
|
Cette passe est **partiellement validée** : durée unitaire, périmètre, durées
|
|
|
|
|
|
de zone et workflow de passage de base sont persistants et exposés dans l'UI.
|
|
|
|
|
|
La sélection en masse avancée, le raccord automatique espaces verts → lot et
|
|
|
|
|
|
le scénario intégral sans intervention technique restent à renforcer. Phase
|
|
|
|
|
|
2.2 non commencée.
|