Isi-APP Docs fonctionnelles
Toutes les docs
Markdown brut
Hub 'Santé de l'app' — Documentation fonctionnelle
Actif sante functional Revu le 2026-07-08 sante/sante-app.md

Hub "Santé de l'app" — Documentation fonctionnelle

Tableau de bord d'audit technique d'ISI-APP, réservé aux super-développeurs ISI. Centralise cinq indicateurs de santé du codebase et des données, accessibles sans impacter les tenants clients.


Vue d'ensemble

Le Hub Santé de l'app est une page d'administration (/admin/app-health) qui permet aux super-développeurs ISI d'auditer l'état interne d'ISI-APP : cohérence des données, qualité du code UI, fraîcheur des dépendances. Chaque audit est lancé manuellement, s'exécute en arrière-plan, et le résultat est persisté en base pour une lecture instantanée à tout moment.


Accès

  • URL : /admin/app-health
  • Restriction : isSuperDeveloper() — super-développeurs ISI uniquement. Toute tentative d'accès sans ce droit retourne un 403.
  • Aucun module client ni droit tenant requis.

Les 3 onglets

Onglet Rôle
Vue d'ensemble Grille de 5 cartes résumant le statut et la valeur principale de chaque type d'audit. Permet de lancer ou relancer un scan. Cliquer sur une carte (en dehors du bouton d'action) ouvre directement le détail correspondant dans l'onglet Intégrité des données ou Audit Onyx.
Intégrité des données Détail des résultats des 4 indicateurs d'intégrité (carte des relations, orphelins, normalisation, fraîcheur). Navigation par sous-onglet.
Audit Onyx Résultat de l'audit de conformité UI : statistiques d'usage des composants Onyx et liste des anti-patterns Bootstrap/global détectés dans les vues Blade.

Lancer un scan

  1. Aller sur l'onglet Vue d'ensemble.
  2. Sur la carte souhaitée, cliquer sur Lancer (premier scan) ou Relancer (résultat déjà disponible).
  3. Le temps que la requête parte au serveur, le bouton se désactive et affiche "Envoi en cours…" (retour visuel immédiat). Une fois le scan créé, le bouton passe à "Analyse en cours…" et la page se rafraîchit automatiquement toutes les 3 secondes via polling Livewire tant qu'un scan est actif.
  4. Une fois terminé, la carte affiche la valeur principale et la date de génération.

Si un scan du même type est déjà en cours, un second clic est ignoré silencieusement (protection anti-doublon).


Les 5 indicateurs

Carte des relations

Construit une carte de toutes les relations entre tables depuis trois sources complémentaires : les clés étrangères déclarées en base (information_schema), les relations Eloquent parsées dans app/Models/, et les jointures explicites détectées par grep dans app/. La valeur principale affichée est le nombre total de relations dédupliquées.

Détection des orphelins

S'appuie sur la carte des relations (dernière disponible) pour détecter les enregistrements enfants sans parent valide. Un scan « Carte des relations » réussi doit exister au préalable — sans lui, le scan des orphelins échoue explicitement avec un message invitant à lancer d'abord la cartographie, plutôt que de renvoyer un faux résultat « 0 orphelin » qui donnerait une confiance trompeuse.

Quatre niveaux de sévérité sont distingués, chacun détecté par une requête SQL dédiée et mutuellement exclusive (une ligne ne peut matcher qu'une seule des quatre) :

Sévérité Signification
FK null La colonne FK elle-même n'est pas renseignée — absence de relation, pas une relation brisée
Orphelin vrai FK renseignée mais parent totalement absent de la table, dans aucun tenant
Parent soft-deleted Parent présent mais archivé (dtdel non nul)
Fuite cross-tenant Parent présent et actif, mais idc différent de l'enfant

La valeur principale affichée est le nombre total d'orphelins (toutes sévérités confondues), calculé de façon exacte (aucun plafonnement) via un COUNT SQL par catégorie. Toutes les relations de la carte sont analysées à chaque scan (aucune limite par défaut).

Une même relation physique détectée par plusieurs sources de la carte des relations (ex. une clé étrangère à la fois déclarée en base et devinée par l'analyse du code Eloquent) est dédupliquée en amont : sans cette déduplication, ses orphelins auraient été comptés plusieurs fois dans le total affiché.

Le détail de tous les enregistrements orphelins (aucun plafond par relation) est affiché dans un tableau filtrable et triable côté serveur — deux filtres sont disponibles :

  • Sévérité : FK null, parent absent, fuite cross-tenant, ou parent archivé
  • Table : liste des tables enfants concernées par le dernier scan

Seule la dernière génération d'échantillons est conservée (un nouveau scan remplace intégralement la précédente) — l'historique des scans eux-mêmes reste consultable, mais pas le détail ligne par ligne des scans antérieurs.

Conformité normalisation

Vérifie que les données stockées en base respectent les règles de normalisation appliquées par les triggers SQL (migration 2026_06_05). Les règles couvrent : trim, trim_collapse, email, phone, siret, postal. Un échantillon de 500 lignes est analysé par colonne concernée. La valeur principale affichée est le taux de conformité global en pourcentage. Le détail par colonne (« Violations par colonne ») est trié par taux de conformité croissant : les colonnes les plus problématiques (0 % en premier) apparaissent en tête.

Un bouton « Voir » sur chaque colonne comportant des violations ouvre une fenêtre listant jusqu'à 3 exemples concrets — la valeur brute en base et sa version normalisée attendue — pour comprendre en un coup d'œil ce qui ne respecte pas la règle, sans avoir à interroger la base manuellement.

Fraîcheur des dépendances

Appelle composer outdated et npm outdated pour comparer les versions installées aux dernières disponibles. Classe chaque package en a_jour, retard_mineur (patch/minor) ou retard_majeur (major). La valeur principale affichée est le nombre de packages obsolètes. La note globale est : rouge (au moins un retard majeur), orange (retard mineur uniquement), vert (tout à jour) — un sous-texte précise systématiquement sa composition (ex. « 2 paquet(s) en retard majeur »).

Audit Onyx UI

Scanne toutes les vues Blade de resources/views/ pour détecter :

  • Les composants x-onyx.* utilisés (inventaire de l'adoption Onyx)
  • Les anti-patterns à migrer : éléments HTML natifs (<input>, <select>, <textarea>), classes Bootstrap (btn btn-*, badge bg-*, alert alert-*, card, etc.), anciens composants x-global.*

La valeur principale affichée est le nombre total d'occurrences d'anti-patterns. L'onglet Audit Onyx détaille par règle, fichier et ligne.


Mécanique asynchrone

Les scans ne s'exécutent jamais de façon synchrone. Le flux est :

  1. Déclenchement : AppHealthHub::startScan() crée un enregistrement AppHealthScan en base avec le statut pending, puis dispatche AppHealthScanJob sur la queue default.
  2. Exécution : le worker prend le job, passe le scan en running, exécute le service correspondant, puis enregistre le résultat JSON dans jsresult et passe le statut à done (ou failed avec message d'erreur).
  3. Lecture : AppHealthHub::render() lit uniquement les derniers scans done depuis la base — il n'exécute aucun calcul. Le polling Livewire (3 s) rafraîchit la vue jusqu'à disparition des scans actifs.

Ce design garantit qu'un scan long (plusieurs minutes) n'impacte pas le temps de réponse HTTP et que le résultat reste consultable indéfiniment après la fin du job.


Contournement cross-tenant délibéré

La détection des fuites cross-tenant dans DataIntegrityService nécessite de lire les colonnes idc de tables qui appartiennent à des tenants différents, sans scoper la requête. Ce contournement est intentionnel et documenté dans le code. Il est réservé aux super-développeurs ISI, qui ont précisément besoin d'une vision cross-tenant pour identifier les anomalies. Aucune écriture n'est effectuée.


Fonctionnalité différée

Le sous-lot suppression d'orphelins (§6.8 de la spec) est volontairement non implémenté. Le hub est en lecture seule : il signale les anomalies mais ne les corrige pas automatiquement. La suppression d'orphelins fera l'objet d'un développement séparé avec des gardes-fous adaptés.