481 lines
24 KiB
Markdown
481 lines
24 KiB
Markdown
# Bugs et anomalies
|
||
|
||
## UI-001 — Transvasement inaccessible
|
||
|
||
- Priorité : P1
|
||
- Module : Matériel & Produits d'entretien
|
||
- URL : `/cleaning/transvasement`
|
||
- Compte : `chatgpt` / `super_admin`
|
||
- Résultat : HTTP 500, écran générique.
|
||
- Attendu : formulaire utilisable ou message métier explicite si le stock est
|
||
vide.
|
||
- Impact : dilution et transvasement impossibles.
|
||
|
||
## UI-002 — Configuration des prévisions inaccessible
|
||
|
||
- Priorité : P1
|
||
- Module : Matériel & Produits d'entretien
|
||
- URL : `/cleaning/forecast-config`
|
||
- Compte : `chatgpt` / `super_admin`
|
||
- Résultat : HTTP 500.
|
||
- Attendu : coefficients par défaut affichés et modifiables.
|
||
- Impact : coefficients de permanence impossibles à configurer.
|
||
|
||
## UI-003 — Création de salle bloquée
|
||
|
||
- Priorité : P1
|
||
- Module : Établissement
|
||
- URL : `/equipments/rooms/new`
|
||
- Résultat : le select « Bâtiment » est vide malgré des bâtiments visibles
|
||
dans `/equipments/buildings/`.
|
||
- Attendu : bâtiments proposés, puis zones filtrées par bâtiment.
|
||
- Impact : impossibilité de poursuivre les scénarios équipements/interventions.
|
||
|
||
## UI-004 — Confusion Site/Bâtiment
|
||
|
||
- Priorité : P2
|
||
- URL : `/equipments/buildings/`
|
||
- Résultat : le formulaire principal crée un `Site` (Collège), tandis que le
|
||
véritable bâtiment se crée via `/equipments/buildings/new`.
|
||
- Recommandation : séparer les deux actions et afficher la hiérarchie
|
||
établissement → bâtiment → zone → salle.
|
||
|
||
## UI-005 — Commit Docker non identifié
|
||
|
||
- Priorité : P2
|
||
- URL : `/health/`, setup
|
||
- Résultat : version `0.1.0-dev.2`, commit `unknown`.
|
||
- Recommandation : fournir `GIT_VERSION=$(git rev-parse HEAD)` au build.
|
||
|
||
## UI-006 — Instabilité sous navigation séquentielle
|
||
|
||
- Priorité : P1 à confirmer
|
||
- Résultat : temps de réponse parfois supérieur à 8–30 secondes, puis
|
||
indisponibilité temporaire.
|
||
- Recommandation : surveiller CPU/RAM, Gunicorn, connexions MariaDB et
|
||
documenter les temps de réponse sans lancer de test de charge.
|
||
|
||
## UI-007 — Disponibilités et horaires semblent partager le même écran
|
||
|
||
- Priorité : P2
|
||
- URL : `/planning/availability`
|
||
- Résultat : titre « Horaires et suivi annuel » et structure identique à
|
||
`/planning/time`.
|
||
- Attendu : redirection explicite ou écran distinct avec un libellé cohérent.
|
||
- Impact : l'utilisateur peut croire qu'il existe deux écrans différents.
|
||
|
||
## UI-008 — Requête 401 visible dans la console au chargement du login
|
||
|
||
- Priorité : P3 à confirmer
|
||
- Résultat : Playwright signale une ressource 401 sur `/auth/login`.
|
||
- Impact : bruit console et appel potentiellement lancé avant la session.
|
||
|
||
## UI-009 — Soumission produit très lente/non confirmée
|
||
|
||
- Priorité : P1 à confirmer (environnementale ou applicative)
|
||
- URL : `/cleaning/products/new`
|
||
- Compte : `chatgpt` / `super_admin`
|
||
- Étapes : remplir un produit `TEST_UI_DETERGENT_SOL` puis soumettre une
|
||
seule fois.
|
||
- Résultat : l'action Playwright est restée bloquée plus de 30 secondes ; la
|
||
requête n'a pas été répétée.
|
||
- Impact : impossible de confirmer la création d'un produit dans cette passe.
|
||
- Qualification : vérifier les logs et la charge VM avant de conclure à un
|
||
bug applicatif.
|
||
|
||
## UI-010 — Soumission prévention très lente/non confirmée
|
||
|
||
- Priorité : P1 à confirmer (environnementale ou applicative)
|
||
- URL : `/prevention/`
|
||
- Compte : `chatgpt` / `super_admin`
|
||
- Étapes : remplir le formulaire d'agent prévention avec des données
|
||
`TEST_UI_*`, puis soumettre une seule fois.
|
||
- Résultat : clic bloqué au-delà du délai ; aucune répétition.
|
||
- Impact : impossible de confirmer la création d'un personnel de prévention
|
||
dans cette passe.
|
||
|
||
## UI-011 — Lien Documents renvoie 404
|
||
|
||
- Priorité : P2
|
||
- URL : `/documents/`
|
||
- Compte : `chatgpt` / `super_admin`
|
||
- Résultat : HTTP 404.
|
||
- Attendu : liste documentaire ou redirection vers le module documentaire
|
||
réellement utilisé.
|
||
- Impact : lien cassé pour un utilisateur qui cherche les documents.
|
||
|
||
## UI-012 — Menu non filtré selon les permissions
|
||
|
||
- Priorité : P1
|
||
- Comptes : `TEST_UI_USER_MULTI` et `TEST_UI_USER_NONE`.
|
||
- Résultat : les deux dashboards contiennent les mêmes liens équipements,
|
||
interventions et nettoyage, y compris pour `TEST_UI_USER_NONE` sans rôle.
|
||
- Backend : `TEST_UI_USER_NONE` reçoit bien 403 sur ces URLs ; le backend est
|
||
donc plus strict que le menu.
|
||
- Résultat multi-rôles : `TEST_UI_USER_MULTI` reçoit 200 sur patrimoine et
|
||
interventions, puis 403 patrimoine après un refus individuel, tandis que
|
||
les interventions restent accessibles.
|
||
- Impact : UX trompeuse et risque d'erreurs ; un utilisateur voit des liens
|
||
qu'il ne peut pas ouvrir.
|
||
|
||
## UI-013 — Pagination absente ou non supportée sur plusieurs listes
|
||
|
||
- Priorité : P2
|
||
- `/lots/?page=2` et `/equipments/?page=2` répondent 200.
|
||
- `/interventions/?page=2` et `/companies/?page=2` répondent 404.
|
||
- Attendu : pagination cohérente, ou absence explicite du paramètre avec une
|
||
interface qui ne l'affiche pas.
|
||
- Impact : incohérence de navigation lorsque le volume de données augmente.
|
||
|
||
## UI-014 — Entreprises sans recherche ni filtre visible
|
||
|
||
- Priorité : P2
|
||
- URL : `/companies/`
|
||
- Résultat : aucune zone de recherche ou de tri dans la liste.
|
||
- Attendu : recherche par nom/contact lorsque le nombre d'entreprises croît.
|
||
|
||
## UI-015 — Formulaire entreprise vide provoque une erreur 500
|
||
|
||
- Priorité : P1
|
||
- URL : `/companies/new`
|
||
- Étapes : soumettre le formulaire vide avec un CSRF valide.
|
||
- Résultat : HTTP 500 au lieu d'une validation utilisateur.
|
||
- Attendu : HTTP 400 ou retour formulaire avec champ obligatoire signalé.
|
||
|
||
## UI-016 — Formulaire intervention vide provoque une erreur 500
|
||
|
||
- Priorité : P1
|
||
- URL : `/interventions/new`
|
||
- Étapes : soumettre le formulaire vide avec un CSRF valide.
|
||
- Résultat : HTTP 500.
|
||
- Attendu : validation des champs obligatoires et message compréhensible.
|
||
|
||
## UI-017 — Liste interventions casse avec une intervention sans salle
|
||
|
||
- Priorité : P1
|
||
- URL : `/interventions/`
|
||
- Donnée : `TEST_UI_INTERVENTION_ELECTRICITE` (ID 1), créée sans salle ni
|
||
équipement pour tester le cas autorisé par le formulaire.
|
||
- Résultat : le détail `/interventions/1` répond 200, mais la liste renvoie
|
||
HTTP 500.
|
||
- Attendu : afficher l'intervention avec « Salle non renseignée » ou demander
|
||
une salle avant validation.
|
||
- Impact : une intervention valide au niveau formulaire rend la liste
|
||
principale inutilisable.
|
||
|
||
## UI-018 — Titre d'édition ambigu
|
||
|
||
- Priorité : P2
|
||
- URL : `/interventions/1/edit`
|
||
- Résultat : le titre HTML reste « Nouvelle intervention » en édition.
|
||
- Attendu : « Modifier l'intervention » avec identifiant/titre existant.
|
||
|
||
## UI-019 — Tableau de bord en erreur avec une intervention sans équipement
|
||
|
||
- Priorité : P1
|
||
- URL : `/`
|
||
- Utilisateur : `chatgpt` (super-administrateur)
|
||
- Précondition : l'intervention de test ID 1 existe sans équipement associé.
|
||
- Étapes : ouvrir une session puis demander `/`.
|
||
- Résultat : HTTP 500. Le journal indique
|
||
`dashboard/index.html:495` et l'expression `interv.equipment.name` alors que
|
||
`interv.equipment` vaut `None`.
|
||
- Attendu : le tableau de bord doit afficher une valeur de remplacement
|
||
(« Aucun équipement ») ou exclure proprement la relation absente.
|
||
- Impact : erreur critique pour la page d'entrée et perte d'accès au tableau
|
||
de bord dès qu'une intervention sans équipement est enregistrée.
|
||
|
||
## UI-020 — Lien Journaux visible mais accès refusé
|
||
|
||
- Priorité : P2
|
||
- URL : `/logs/`
|
||
- Utilisateur : `chatgpt` (rôle personnalisé `chatgpt`)
|
||
- Étapes : ouvrir une page autorisée contenant la navigation, puis suivre le
|
||
lien « Journaux » ; ouvrir également `/logs/` directement.
|
||
- Résultat : le lien `/logs/` est présent dans le HTML de navigation, mais le
|
||
serveur répond HTTP 403. Le compte possède les permissions d'audit visibles
|
||
dans sa matrice, sans permission effective acceptée par cette route.
|
||
- Attendu : masquer le lien si l'accès est refusé, ou attribuer/vérifier la
|
||
permission réellement requise par la route.
|
||
- Impact : incohérence UI/backend et perte de temps pour l'utilisateur.
|
||
|
||
## UI-021 — Certains formulaires planning dépendent de l'injection JavaScript du CSRF
|
||
|
||
- Priorité : P2
|
||
- URLs : `/planning/availability/closure/new`, `/planning/tasks/new`
|
||
- Résultat : le HTML initial ne contient pas de champ caché `csrf_token` ; le
|
||
jeton est ajouté par le JavaScript global. Une soumission sans JavaScript
|
||
reçoit bien 400, mais le formulaire ne peut alors pas être utilisé.
|
||
- Attendu : rendre le champ CSRF dans le formulaire serveur, tout en gardant
|
||
l'injection JS comme secours pour les requêtes dynamiques.
|
||
- Impact : dépendance inutile à JavaScript et accessibilité dégradée.
|
||
|
||
## UI-022 — État du stock en erreur après une réception valide
|
||
|
||
- Priorité : P1
|
||
- URL : `/cleaning/stock`
|
||
- Précondition : produit, référence, conditionnement, emplacement et deux lots
|
||
`TEST_UI_*` réceptionnés avec succès.
|
||
- Étapes : ouvrir l'état du stock après les réceptions.
|
||
- Résultat : HTTP 500, alors que le journal des mouvements reste accessible et
|
||
affiche les réceptions, la sortie FEFO, le transfert et la correction
|
||
d'inventaire.
|
||
- Attendu : afficher les soldes par lot et emplacement, même lorsque les
|
||
mouvements précédents ont modifié les quantités.
|
||
- Impact : l'écran central de consultation du stock est inutilisable dès
|
||
qu'un stock réel existe.
|
||
|
||
## UI-023 — Aucun contrôle UI pour autoriser un produit sur les fiches de demande
|
||
|
||
- Priorité : P2
|
||
- URLs : `/cleaning/products/new`, `/cleaning/products/1/edit`,
|
||
`/cleaning/requests/new`
|
||
- Résultat : le modèle distingue `request_enabled`, mais les formulaires du
|
||
produit ne proposent aucun champ pour l'activer. Le formulaire de profil
|
||
affiche donc zéro produit sélectionnable, et la fiche imprimée ne contient
|
||
aucune ligne.
|
||
- Attendu : case « Autoriser sur les fiches de demande » dans le produit, avec
|
||
un état visible dans le profil.
|
||
- Impact : la fonctionnalité de fiches papier ne peut pas être configurée
|
||
depuis l'interface.
|
||
|
||
## UI-024 — Valeur numérique invalide sur l'édition d'un produit → 500
|
||
|
||
- Priorité : P1
|
||
- URL : `/cleaning/products/1/edit`
|
||
- Étapes : remplacer « Stock minimum » par `abc` et soumettre le produit de
|
||
test.
|
||
- Résultat : HTTP 500 au lieu d'un message de validation.
|
||
- Attendu : conserver les valeurs saisies et signaler que les quantités
|
||
doivent être numériques, comme le fait déjà la création.
|
||
- Impact : une faute de saisie rend l'écran d'édition inutilisable.
|
||
|
||
## UI-025 — Doublon de référence commerciale accepté sans avertissement
|
||
|
||
- Priorité : P2
|
||
- URL : `/cleaning/references/new`
|
||
- Étapes : créer une seconde référence `TEST_UI_REF_DETERGENT_SOL` pour le
|
||
même produit générique.
|
||
- Résultat : la soumission est acceptée (302) et deux occurrences apparaissent
|
||
dans la liste, sans avertissement ni indication d'historique.
|
||
- Attendu : avertir l'utilisateur ou demander une référence fabricant/
|
||
fournisseur distincte avant de créer un doublon involontaire.
|
||
- Impact : catalogue commercial ambigu et risque d'erreur lors des réceptions.
|
||
|
||
## UI-026 — Labels de formulaires non associés aux contrôles
|
||
|
||
- Priorité : P2
|
||
- Périmètre : formulaires produits, références, conditionnements, réceptions,
|
||
sorties, transferts et prévention.
|
||
- Résultat : les libellés sont visuellement présents, mais n'ont pas
|
||
d'attribut `for` et les contrôles n'ont pas d'identifiant associé. Le clic
|
||
sur le libellé ne place donc pas le focus et les lecteurs d'écran ne peuvent
|
||
pas relier automatiquement le nom au champ.
|
||
- Attendu : associer chaque `<label for="…">` à un `id` unique, ou envelopper
|
||
explicitement le contrôle dans le label.
|
||
- Impact : accessibilité clavier et compréhension des champs dégradées pour
|
||
les utilisateurs débutants ou avec assistance vocale.
|
||
|
||
## UI-027 — Habilitation prévention accepte des dates inversées
|
||
|
||
- Priorité : P2
|
||
- URL : `/prevention/` (formulaire `/prevention/authorization`)
|
||
- Étapes : pour `TEST_UI_AGENT ENTRETIEN`, saisir une date d'émission
|
||
31/12/2026 et une expiration 01/01/2026.
|
||
- Résultat : POST accepté avec redirection 302, sans message d'erreur ni
|
||
validation de l'ordre chronologique.
|
||
- Attendu : refuser une expiration antérieure à l'émission et expliquer la
|
||
correction attendue.
|
||
- Impact : historique d'habilitations incohérent.
|
||
|
||
## UI-028 — Les habilitations ne sont pas visibles dans le récapitulatif prévention
|
||
|
||
- Priorité : P2
|
||
- URL : `/prevention/`
|
||
- Résultat : le formulaire d'ajout d'habilitation est présent, mais aucune
|
||
liste des habilitations enregistrées n'est affichée ; l'entrée de test ne
|
||
peut donc pas être relue ou contrôlée dans l'interface.
|
||
- Attendu : tableau agent, habilitation, date d'émission, expiration et
|
||
émetteur, avec signalement des habilitations expirées.
|
||
- Impact : absence de suivi opérationnel malgré la possibilité de saisie.
|
||
|
||
## UI-029 — Listes stock et produits sans recherche ni filtre
|
||
|
||
- Priorité : P2
|
||
- URLs : `/cleaning/products`, `/cleaning/references`,
|
||
`/cleaning/movements`, `/cleaning/requests`
|
||
- Résultat : les listes ne présentent ni champ de recherche, ni filtre, ni
|
||
pagination visible. Après ajout de lots et mouvements, retrouver un produit
|
||
ou une opération nécessite de parcourir toute la page.
|
||
- Attendu : recherche par produit/référence/lot et filtres par période,
|
||
emplacement et type de mouvement, avec pagination.
|
||
- Impact : ergonomie insuffisante dès que le catalogue ou l'historique grandit.
|
||
|
||
## UI-030 — Document téléversé absent du détail de l'intervention
|
||
|
||
- Priorité : P1
|
||
- URLs : `/interventions/1`, `/documents/upload/intervention/1`
|
||
- Étapes : téléverser le fichier artificiel `test_document.pdf` depuis le
|
||
détail de l'intervention de test, puis revenir au détail.
|
||
- Résultat : le POST est accepté (302) et le téléchargement
|
||
`/documents/intervention/download/1` répond 200, mais aucun nom ou lien de
|
||
document n'est affiché sur `/interventions/1`.
|
||
- Attendu : afficher le document, sa description, sa date et les actions
|
||
téléchargement/suppression dans le détail.
|
||
- Impact : l'utilisateur ne sait pas si son fichier a été enregistré et ne
|
||
peut pas le gérer depuis l'intervention.
|
||
|
||
## Corrections locales — passe P1
|
||
|
||
Les éléments ci-dessous sont **CORRIGÉS DANS LE CODE — À REVALIDER SUR VM DE TEST**.
|
||
La VM et sa base `TEST_UI_*` ne sont pas accessibles depuis cet environnement.
|
||
|
||
| Bug | Cause racine | Correction locale | Tests locaux |
|
||
|---|---|---|---|
|
||
| UI-001 | `ReusableContainer` manquait dans les imports de la route | Import explicite du modèle et chargement défensif de la page | `test_cleaning_module.py`, `test_ui_p1_regressions.py` |
|
||
| UI-002 | Le nom de contexte `config` masquait la configuration Flask dans `base.html`, en plus de l'import manquant | Import de `CleaningForecastConfig` et contexte renommé `forecast_config` | `test_ui_p1_regressions.py::test_cleaning_pages_load_without_reference_data` |
|
||
| UI-003 | La route ne fournissait pas `buildings` au template et n'assurait pas la cohérence zone/bâtiment | Contexte complet, validation serveur et conservation des saisies | `test_ui_p1_regressions.py::test_room_form_lists_buildings_and_rejects_cross_building_zone`, `test_equipment_forms.py` |
|
||
| UI-015 | Le nom entreprise était envoyé directement en base sans validation | Validation obligatoire et retour formulaire HTTP 400 | `test_ui_p1_regressions.py::test_empty_intervention_and_company_are_validation_errors` |
|
||
| UI-016 | Le titre et les dates d'intervention étaient parsés sans validation | Validation du titre et des dates/heures avec message français | `test_ui_p1_regressions.py::test_empty_intervention_and_company_are_validation_errors` |
|
||
| UI-017 | Le template appelait `interv.equipment.name` lorsque l'équipement était absent | Affichage salle/localisation générale de remplacement | `test_ui_p1_regressions.py::test_optional_location_is_safe_in_interventions` |
|
||
| UI-019 | Le dashboard appelait `interv.equipment.name` lorsque l'équipement était absent | Garde équipement/salle/aucune localisation | `test_ui_p1_regressions.py::test_optional_equipment_is_safe_on_dashboard` |
|
||
| UI-022 | La vue stock n'injectait pas `current_date`, utilisé par le template | Passage explicite de la date courante | `test_ui_p1_regressions.py::test_cleaning_pages_load_without_reference_data`, tests stock existants |
|
||
| UI-024 | `Decimal()` non protégé dans l'édition produit | Validation numérique et rollback sans 500 | `test_ui_p1_regressions.py::test_invalid_product_quantity_is_validation_error` |
|
||
| UI-030 | La fiche module utilisait des endpoints de documents inexistants et une relation dynamique directement dans Jinja | Endpoints réels, liste de documents matérialisée dans la route et template | `test_ui_p1_regressions.py::test_intervention_detail_template_exposes_document_actions` |
|
||
| UI-012 | Les groupes de navigation et liens métier étaient statiques | Filtrage des groupes, liens et raccourci logs par `has_permission()` | Vérification de compilation/rendu des templates et suite ciblée |
|
||
|
||
Les résultats ci-dessus sont des tests automatisés locaux uniquement ; ils ne
|
||
valident pas la base distante ni le rendu sur la VM d'audit.
|
||
|
||
## Revalidation sur la VM de test — 22 août 2026
|
||
|
||
Passe exécutée séquentiellement sur `http://82.64.101.239/` avec `chatgpt`.
|
||
La base existante et les données `TEST_UI_*` ont été conservées ; aucun
|
||
watchdog, intégration externe ou utilisateur `alban` n'a été modifié.
|
||
|
||
| Bug | Résultat VM | Scénario et données |
|
||
|---|---|---|
|
||
| UI-003 | **VALIDÉ SUR VM** | `/equipments/rooms/new` propose les bâtiments existants ; création de `TEST_UI_REVALIDATION_SALLE` ; bâtiment 2 + zone 1 est refusé en HTTP 400. |
|
||
| UI-017 | **TOUJOURS REPRODUCTIBLE** | `/interventions/` reste en HTTP 500 avec l'intervention ID 1 sans salle/équipement. |
|
||
| UI-019 | **VALIDÉ SUR VM** | `/` renvoie 200 et affiche « Aucun équipement », sans `None`, `null` ni `undefined` visibles. |
|
||
| UI-001 | **VALIDÉ SUR VM** | `/cleaning/transvasement` 200 ; transvasement test de 0,1 L enregistré et quantité impossible refusée proprement. |
|
||
| UI-002 | **VALIDÉ SUR VM** | `/cleaning/forecast-config` 200 ; coefficient non numérique renvoyé en 400 avec message, sans 500. |
|
||
| UI-022 | **VALIDÉ SUR VM** | `/cleaning/stock` 200 après lots, réceptions, sortie, transfert et correction ; produits, lots et emplacements visibles. |
|
||
| UI-015 | **VALIDÉ SUR VM** | POST vide `/companies/new` en 400 avec formulaire ; `TEST_UI_REVALIDATION_ENTREPRISE` créé (ID 2). |
|
||
| UI-016 | **VALIDÉ SUR VM** | POST vide `/interventions/new` en 400 ; `TEST_UI_REVALIDATION_INTERVENTION` créé (ID 2). |
|
||
| UI-024 | **VALIDÉ SUR VM** | `stock_minimum=abc` sur le produit ID 1 renvoie 400 et conserve le formulaire. |
|
||
| UI-030 | **VALIDÉ SUR VM** | PDF artificiel `TEST_UI_REVALIDATION_DOCUMENT.pdf` visible dans le détail de l'intervention 1 et téléchargeable (document ID 2). |
|
||
| UI-012 | **CORRIGÉ PARTIELLEMENT — PROBLÈME RÉSIDUEL** | Le bouton global `/logs/` reste visible alors que l'URL renvoie 403. Les comptes `TEST_UI_USER_MULTI` et `TEST_UI_USER_NONE` n'ont pas pu être reconnectés : leurs mots de passe ne sont pas documentés. |
|
||
|
||
### UI-031 — nouveau blocage observé
|
||
|
||
Les groupes `TEST_UI_EQ_CHAISES` (30 individuels) et
|
||
`TEST_UI_EQ_CHAISE_UNITAIRE` créés dans `TEST_UI_CLASSE_101` apparaissent dans
|
||
`/equipments/` et dans la salle, mais `/equipments/1` et `/equipments/2`
|
||
renvoient HTTP 500. `/equipments/<id>/hierarchy` renvoie une liste de zones
|
||
vide. Les déplacements et cycles de vie restent donc bloqués. Anomalie
|
||
documentée uniquement, sans correction pendant cette passe.
|
||
|
||
## Passe corrective ciblée — 22 août 2026
|
||
|
||
Les trois blocages restants ont été corrigés dans le dépôt local. La VM
|
||
auditée n'est pas accessible depuis cette passe : chaque statut ci-dessous
|
||
reste **CORRIGÉ DANS LE CODE — À REVALIDER SUR VM**.
|
||
|
||
### UI-017 — liste des interventions
|
||
|
||
- Cause : les templates de liste et du planning préventif accédaient
|
||
directement à `interv.equipment.name` pour des relations optionnelles.
|
||
- Correction : affichage conditionnel de l'équipement, puis de la salle, puis
|
||
du libellé humain `Localisation non renseignée`.
|
||
- Fichiers : les deux templates `interventions/index.html` et les deux
|
||
templates `interventions/planning.html`.
|
||
- Tests : quatre combinaisons salle/équipement couvrent liste, détail et
|
||
dashboard.
|
||
- Statut : **CORRIGÉ DANS LE CODE — À REVALIDER SUR VM**.
|
||
|
||
### UI-031 — détail et hiérarchie des équipements groupés
|
||
|
||
- Cause du détail 500 : le template global affichait
|
||
`equipment.preventive_count`, propriété absente du modèle `Equipment`.
|
||
- Correction : ajout de cette propriété calculée au modèle, sans migration.
|
||
- Cause de la hiérarchie vide : l'endpoint ne sélectionnait que les
|
||
descendants ; une famille quantitative sans enfant produisait zéro ligne,
|
||
même si sa salle était renseignée.
|
||
- Correction : si aucun descendant n'est trouvé, l'équipement racine est
|
||
ajouté avec son bâtiment, sa zone, sa salle et sa quantité effective.
|
||
- Fichiers : `app_new/core/models/equipment.py` et
|
||
`app_new/equipments/main.py`.
|
||
- Tests : famille quantitative de quantité 30, détail rendu et endpoint
|
||
hierarchy vérifié avec zone/salle/quantité.
|
||
- Statut : **CORRIGÉ DANS LE CODE — À REVALIDER SUR VM**.
|
||
|
||
### Résidu UI-012 — lien Journaux
|
||
|
||
- Cause : la navigation vérifiait `audit.view`, alors que la garde globale de
|
||
`logs.index` exige `watchdog_dnd.view`.
|
||
- Correction : le bouton `/logs/` utilise désormais exactement
|
||
`has_permission('watchdog_dnd.view')`.
|
||
- Fichier : `app_new/templates/base.html`.
|
||
- Tests : concordance vérifiée avec `required_permission('logs.index', 'GET')`.
|
||
- Statut : **CORRIGÉ DANS LE CODE — À REVALIDER SUR VM**.
|
||
|
||
## Revalidation VM après déploiement — 22 août 2026
|
||
|
||
Correctifs observés : `8c54f46`, `864f65d`, `f2783a0`, `ce6d8ae`.
|
||
|
||
### UI-017 — liste des interventions
|
||
|
||
**Statut : VALIDÉ SUR VM.** `/interventions/` répond HTTP 200 avec
|
||
l'intervention sans salle ni équipement et affiche « Localisation non
|
||
renseignée ». Les détails testés, le planning (redirigé vers `/planning/`) et
|
||
le dashboard répondent également 200. Aucun texte `None`, `null` ou
|
||
`undefined` n'est visible.
|
||
|
||
### UI-031 — détail et hiérarchie des équipements groupés
|
||
|
||
**Statut : TOUJOURS REPRODUCTIBLE (correction partielle).** Les détails
|
||
`/equipments/1` et `/equipments/2` renvoient encore HTTP 500 pour
|
||
`TEST_UI_EQ_CHAISES` (quantité 30) et `TEST_UI_EQ_CHAISE_UNITAIRE` (quantité
|
||
1). En revanche, les endpoints `/equipments/1/hierarchy` et
|
||
`/equipments/2/hierarchy` répondent HTTP 200 et contiennent la hiérarchie
|
||
`TEST_UI_ZONE_PEDAGO → TEST_UI_CLASSE_101`, avec les quantités 30 et 1. Les
|
||
déplacements, la casse et le cycle de vie n'ont pas été exécutés, car le
|
||
détail reste bloquant.
|
||
|
||
### UI-012 — lien Journaux
|
||
|
||
**Statut : VALIDÉ SUR VM pour le compte sans permission ; contrôle positif à
|
||
compléter.** Avec `chatgpt`, l'accès direct `/logs/` reste HTTP 403 et le
|
||
dashboard ne contient plus aucun lien `logs`. Les identifiants des anciens
|
||
comptes à permissions réduites ne sont pas documentés ; aucun compte n'a été
|
||
modifié et `alban` n'a pas été touché. Le contrôle positif avec
|
||
`watchdog_dnd.view` devra être réalisé lors d'une prochaine passe.
|
||
|
||
## Reproduction et correction locale — UI-031 — 22 août 2026
|
||
|
||
Sur la copie locale de la base VM, `/equipments/1` reproduisait le 500. Le
|
||
traceback exact était `jinja2.exceptions.TemplateRuntimeError: No filter
|
||
named 'nl2br' found`, dans `app_new/templates/equipments/detail.html`.
|
||
|
||
Le filtre est désormais enregistré dans la factory Flask avec échappement du
|
||
contenu et conversion des retours à la ligne. Après reconstruction Docker,
|
||
les détails réels des équipements 1, 2 et 3 répondent 200. Le test ciblé de
|
||
non-régression passe (`1 passed`).
|
||
|
||
Statut : **VALIDÉ LOCALEMENT SUR COPIE VM**.
|
||
|
||
## Scénarios équipements locaux
|
||
|
||
- Groupe quantitatif ID 3 : 30 chaises en salle 2 ; déplacements de 1 puis 5
|
||
unités vers salle 3, groupe cible ID 4 avec 6 unités et mouvements tracés.
|
||
- Quantité 999 : refus métier, sans mouvement supplémentaire ni stock
|
||
négatif.
|
||
- Réparation : unité ID 5 individualisée, intervention ID 3 créée, puis
|
||
remise en service et événements de cycle de vie présents.
|
||
- Rebut : unité ID 6 proposée puis confirmée, statut final `jete`, localisation
|
||
supprimée et historique conservé.
|
||
- Équipement fixe : `TEST_UI_EQ_LUMINAIRE_LOCAL` ID 7, déplacement refusé.
|
||
|
||
Ces scénarios sont **VALIDÉS LOCALEMENT SUR COPIE VM** ; ils restent à
|
||
rejouer sur la VM distante si une validation distante est nécessaire.
|