You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
zoom-html : domaines métier d'un projet rangé par type #58
Vue export zoom-html (#50, PR #57), vérifiée sur captures réelles. Sur un projet Symfony rangé par type (src/Controller/, src/Service/, src/Command/...), le niveau 1 prend les dossiers de type pour des domaines : Command, Form, Enum, EventSubscriber, DataFixtures apparaissent comme domaines, 290 classes tombent dans « (no domain) » et 89 petits domaines sont regroupés. Le découpage métier réel est un niveau plus bas : src/Service/<Domaine>/, src/Controller/<Domaine>/.
User story
En tant que développeur qui découvre un projet rangé par type, je veux voir ses domaines métier au niveau 1, afin de comprendre son découpage sans connaître sa convention de dossiers.
Acceptance criteria
Détection de l'organisation : par type (premier niveau = noms de couches connus) ou par domaine ; documentée
Projet rangé par type : domaine = sous-dossier sous la couche (src/Service/Billing/X.php -> domaine Billing, couche Service) ; les classes au premier niveau d'une couche vont dans un domaine « commun » explicite
Les dossiers purement techniques (DataFixtures, Command, Enum, Form) ne sont jamais présentés comme des domaines métier
Test sur une fixture neutre rangée par type, et capture du niveau 1 avant/après
Prise en charge (branche fix/zoom-domains-by-type).
Périmètre de fichiers visé :
graphify/zoom_html.py (détection de l'organisation, règle de domaine, libellés)
tests/test_zoom_html.py (fixture neutre rangée par type)
README.md si la ligne de commande change de sens
Approche envisagée : liste fermée des dossiers « de type » (noms générés par les commandes make:* de Symfony et Laravel, plus les dossiers de couche) ; organisation par type si la majorité des classes vit sous un tel dossier ; domaine = premier dossier non technique sous les dossiers de type ; sinon domaine commun explicite. Captures avant/après du projet A, niveaux 1 et 2, clair et sombre.
L'organisation est détectée (by-type ou by-domain) et annoncée en tête du niveau 1.
Les dossiers de type (Controller, Command, Form, Enum, DataFixtures, EventSubscriber...) ne sont jamais présentés comme domaines ; les classes sans dossier de domaine vont dans le groupe explicite « Common », expliqué dans la légende.
Ordre des colonnes du niveau 2 confirmé : Route (masquée tant qu'elle est vide), Controller, Service, Repository, Entity / Model, View, Other.
Comment
graphify/zoom_html.py : liste fermée _TYPE_DIRS, detect_layout, classify_domain(path, root, layout), groupe « Common », phrase d'organisation et entrée de légende ; docstring du module mis à jour.
tests/test_zoom_html.py : 16 cas de chemins (Symfony par type, par domaine, Laravel), détection de l'organisation, fixture neutre rangée par type (Item, Order, Sitemap) qui vérifie qu'aucun dossier technique ne devient domaine.
Pourquoi ce choix
Liste fermée des noms que les générateurs de Symfony (maker) et Laravel (make:*) donnent aux dossiers, plutôt qu'une heuristique sur la taille ou le contenu des dossiers : prévisible, documentable, et fidèle à la règle « refuser plutôt que deviner ».
Organisation décidée à l'échelle du projet (majorité des classes sous un dossier de type) et non fichier par fichier : dans un projet rangé par domaine, un domaine qui porterait un nom de type au deuxième niveau (src/Account/Security/) reste dans son domaine.
Sur le projet A, le découpage métier existe bien un niveau plus bas : 94 domaines (ProbeNetwork, Admin, Retention, Osint, Host, Account, Economy...), mais un tiers des classes (1 068 sur 3 362) n'a aucun dossier de domaine : entités, dépôts, énumérations et messages sont posés à plat.
ClientXCMS (Laravel 12) est aussi rangé par type : 24 domaines (Admin, Billing, Core, Store, Provisioning, Helpdesk...) au lieu de Http, DTO, Console, Events, Contracts, Providers.
Captures avant/après faites sur le projet A (niveaux 1 et 2, clair et sombre), non publiées ici car le projet est privé.
Quality
Tests : tests/test_zoom_html.py 29/29 ; sans le correctif, erreur d'import sur main, et 2 échecs si la détection est forcée à by-domain.
Suite complète après le dernier changement : 7648 passed, 14 skipped, 0 failed.
Ruff : 0. Pyright sur les fichiers touchés : 0 erreur.
Accessibilité : axe-core 4.10.3 (WCAG 2.0/2.1 A et AA), 0 violation sur 3 niveaux x 2 thèmes x 3 projets réels ; parcours clavier et 320 px vérifiés ; aucun texte sous 12 px (glyphe de l'icône passé de 11 à 12 px).
Activity
github-actions commentedon Oct 11, 2026
Thanks for opening this issue, @alexwrite. A maintainer will take a look soon.
If you would like to discuss it in real time, come say hi on our Discord server. For longer-form questions and ideas there is also GitHub Discussions.
To help us triage, please make sure the report includes what you expected, what actually happened, and the steps (and a small sample) to reproduce it.
alexwrite commentedon Oct 11, 2026
Prise en charge (branche
fix/zoom-domains-by-type).Périmètre de fichiers visé :
graphify/zoom_html.py(détection de l'organisation, règle de domaine, libellés)tests/test_zoom_html.py(fixture neutre rangée par type)README.mdsi la ligne de commande change de sensApproche envisagée : liste fermée des dossiers « de type » (noms générés par les commandes
make:*de Symfony et Laravel, plus les dossiers de couche) ; organisation par type si la majorité des classes vit sous un tel dossier ; domaine = premier dossier non technique sous les dossiers de type ; sinon domaine commun explicite. Captures avant/après du projet A, niveaux 1 et 2, clair et sombre.alexwrite commentedon Oct 11, 2026
Fait
zoom-htmlmontre les domaines métier d'un projet rangé par type : PR fix(zoom-html): show business domains in projects organised by type #61.by-typeouby-domain) et annoncée en tête du niveau 1.Controller,Command,Form,Enum,DataFixtures,EventSubscriber...) ne sont jamais présentés comme domaines ; les classes sans dossier de domaine vont dans le groupe explicite « Common », expliqué dans la légende.Comment
graphify/zoom_html.py: liste fermée_TYPE_DIRS,detect_layout,classify_domain(path, root, layout), groupe « Common », phrase d'organisation et entrée de légende ; docstring du module mis à jour.tests/test_zoom_html.py: 16 cas de chemins (Symfony par type, par domaine, Laravel), détection de l'organisation, fixture neutre rangée par type (Item,Order,Sitemap) qui vérifie qu'aucun dossier technique ne devient domaine.Pourquoi ce choix
make:*) donnent aux dossiers, plutôt qu'une heuristique sur la taille ou le contenu des dossiers : prévisible, documentable, et fidèle à la règle « refuser plutôt que deviner ».src/Account/Security/) reste dans son domaine.Apprentissages
Http,DTO,Console,Events,Contracts,Providers.Faiblesses restantes
Logging,Sentry,Mailer...) apparaissent comme domaines ; domaines déclarés à la main : Contrôles d'architecture déclaratifs avec score et SARIF, sur le modèle de Plumber #51.Quality
tests/test_zoom_html.py29/29 ; sans le correctif, erreur d'import surmain, et 2 échecs si la détection est forcée àby-domain.Merge: zoom-html shows business domains of type-organized projects (#58)