ArchScan - Constats et rapport de qualité
ArchScan analyse votre base de code et produit un rapport en pleine parité avec un score de qualité unique pondéré par catégorie.
Sections du rapport
Section intitulée « Sections du rapport »- Score de synthèse - un score unique pondéré par catégorie + statut, comparable d’une version à l’autre.
- Constats - avec extrait de code et emplacement exact du fichier.
- Détail SOLID - les violations sont ventilées selon les cinq principes.
- Paquets - dépendances et versions.
- Projets - métriques par projet.
- Carte des dépendances - une vue de graphe interactive.
- Export - HTML/PDF partageable ; vous choisissez la langue du rapport par espace de travail.
Comment le score est-il calculé ?
Section intitulée « Comment le score est-il calculé ? »Les catégories architecture, SOLID, dépendances et métriques sont réduites à un score unique selon leurs pondérations. L’analyse s’exécute dans votre propre CI.
Tableau de bord analytique
Section intitulée « Tableau de bord analytique »La page d’accueil d’ArchScan est un tableau de bord à l’échelle de l’espace de travail, chargé en asynchrone :
- Projets audités, score moyen, constats ouverts, audits du mois - tuiles d’en-tête.
- Tendance des analyses - exécutions et score moyen sur 12 semaines.
- État du parc - anneau de notes (A-E), barres de couverture et d’issue, jauge de rythme.
- Répartition par langage - projets, part analysée, score moyen, échecs.
- Ce qui a bougé - les projets dont le score a le plus monté ou baissé récemment.
Code Health
Section intitulée « Code Health »ArchScan → Code Health répond à une autre question que le score : où se trouve la dette. Il lit la dernière exécution d’un projet - ou, avec Tous les projets, la dernière de chaque projet analysé, fusionnées :
- Carte de risque des fichiers - une treemap : la taille d’une tuile est le risque concentré (constats pondérés par la pire méthode du fichier), sa couleur la pire sévérité. Les petits fichiers se replient dans une tuile « autres » - rien ne disparaît en silence.
- Distribution de complexité - méthodes par bandes de complexité cyclomatique (1-5 / 6-10 / 11-20 / 21+), plus la pire méthode nommée.
- Dette de conception par principe - constats groupés par le principe de leur règle (SOLID, DRY, KISS, YAGNI).
- Composants sur la séquence principale - chaque module placé par abstraction × instabilité ; les zones de douleur et d’inutilité sont marquées.
- Points chauds - les fichiers où constats et complexité se rejoignent.
Un projet dont le runner n’envoie pas de métriques est signalé non mesuré - jamais zéro.
Dependency Health
Section intitulée « Dependency Health »ArchScan → Dépendances inverse les listes de paquets par projet en réponses à l’échelle du parc :
- La table des paquets - par paquet, pas par projet : quel paquet retient le plus de projets, de combien de versions le pire épinglage est en retard, quel projet utilise quelle version. Un paquet épinglé à plusieurs versions est marqué divisé.
- Versions de plateforme - le SDK/runtime que chaque dépôt déclare (
csproj/global.json,pyproject.toml,go.mod,pom.xml,Gemfile,composer.json,package.json) - « qui est encore sur .NET 6 » en un regard. Les sept langages de collector le rapportent. - Lignes par projet - totaux, répartition de fraîcheur et requêtes non résolues (un runner hors ligne ne peut pas interroger le registre - c’est signalé inconnu, pas à jour).
SmartScan
Section intitulée « SmartScan »ArchScan → SmartScan suit chaque point d’entrée web, job Quartz, service d’arrière-plan et consommateur MassTransit d’un projet .NET à travers les services et les handlers jusqu’à l’ORM (Entity Framework, Dapper), et signale les risques vus sur cette chaîne. C’est un module d’avertissement : il ne baisse pas le score et ne fait pas échouer le pipeline. Une chaîne sans risque n’envoie rien.
- Enregistrement introuvable - une requête (
FirstOrDefault,Find, …) peut ne rien renvoyer et le résultat est utilisé sans vérification. L’impact indique si la requête se termine par une 500 ou si un catch général plus haut la transforme en mauvais message. - Données à moitié écrites - une requête fait plusieurs commits sans transaction autour.
- Longueur au-delà de la colonne, valeur obligatoire manquante, valeur en double - un champ de la requête atteint une colonne limitée,
NOT NULLou unique sans règle correspondante en chemin. - Valeur de la requête que le code ne sait pas lire (.NET, Java, Kotlin, Python, Go, Ruby, PHP) - une valeur envoyée par la requête est lue avec
int.Parse,Guid.Parse,Convert.ToInt32et autres sans contrôle préalable : une valeur mal formée finit en 500 au lieu de 400. Un enregistrement désigné par la requête et lu avecFirst/Singleapparaît de même sous Enregistrement introuvable : s’il n’existe pas, la requête finit en 500 au lieu de « introuvable ». - Suppression bloquée par des enregistrements liés (.NET, Java, Kotlin, Python, Go, Ruby, PHP) - un enregistrement est réellement supprimé (pas une suppression logique) alors que d’autres peuvent encore pointer vers lui avec
Restrict,NoActionouClientSetNull; la base refuse la suppression avec une erreur de clé étrangère. Les flux qui vérifient, suppriment ou rattachent ailleurs ces enregistrements d’abord ne sont pas signalés. - Valeur hors de ce que la colonne contient (.NET ; le cas décimal aussi Java, Kotlin, Python, Go, Ruby, PHP ; le cas enum aussi Ruby, PHP) - un nombre plus grand que ce que contient sa colonne
decimal(p, s), une date que la requête peut omettre et qui arrive dans une colonnedatetimeSQL Server en 0001-01-01, ou une valeur non définie qui atteint une colonne enum PostgreSQL.
Choisissez un projet, ouvrez une catégorie : les risques sont groupés par couche et service (ou par type de requête). Un risque ouvert montre la chaîne étape par étape avec fichier et ligne, le code, une correction et un prompt à copier dans un assistant IA. Un risque peut être clos (faux positif, risque accepté, ne sera pas corrigé) et reste clos tant que le même risque est trouvé.
Pour un consommateur, le message est rejoué (ou, derrière un catch général, perdu) ; pour un job, l’exécution échoue. Un job n’a pas de requête : seules les écritures à moitié faites sont vérifiées.
Dans un frontend TypeScript (React, Next.js), la chaîne commence là où l’utilisateur agit ou là où le framework effectue le rendu - un gestionnaire d’événement JSX, un useEffect, un rendu serveur (getServerSideProps, une page asynchrone), un gestionnaire de route Next.js - et passe par les hooks, les thunks Redux et les services jusqu’à la requête (fetch, axios), y compris le saut d’une requête client vers la propre route API du projet. Les catégories : Requête non gérée (un échec de requête que rien n’intercepte : l’utilisateur n’est pas prévenu, ou un rendu serveur répond par une 500), Échec transmis comme un succès (un échec intercepté et renvoyé comme une valeur ordinaire, une réponse d’erreur de fetch lue comme des données, un rejet de thunk que personne ne regarde), Enregistrement introuvable (cette valeur vide est ensuite lue et l’écran lève une erreur) et Données à moitié écrites (deux requêtes d’écriture successives vers le backend du projet). Un client HTTP qui montre chaque échec à l’utilisateur (un toast dans un intercepteur) compte comme une gestion.
Les backends Ruby on Rails et Kotlin Spring sont parcourus comme .NET : actions de contrôleur (et points d’accès Grape), jobs et consumers jusqu’à ActiveRecord ou Spring Data / JPA, avec les mêmes catégories ; les limites de colonnes viennent de db/schema.rb ou des annotations @Column. Les applications Android (Kotlin) et iOS (Swift) sont parcourues comme un frontend : d’un appui, du cycle de vie d’un écran ou d’un view model jusqu’à la requête (Retrofit, OkHttp, Ktor ; URLSession, Alamofire, Moya). Là, un échec de requête non géré qui s’échappe d’une coroutine, ou un try!, fait planter l’application ; un échec transformé en nil ou en valeur par défaut est signalé comme un échec transmis comme un succès.
Les backends Java (Spring Data, JPA, JdbcTemplate, MyBatis), Python (Django et DRF, Flask, FastAPI, Celery ; Django ORM, SQLAlchemy), Go (net/http, gin, echo, chi, fiber, gRPC ; database/sql, sqlx, GORM, pgx) et PHP (Laravel, Symfony ; Eloquent, Doctrine) sont parcourus de la même façon, avec les mêmes catégories. En Go, un enregistrement absent est une erreur, pas un null : une erreur « introuvable » ignorée, qui fait utiliser une ligne vide comme si elle avait été trouvée et répondre la requête par un succès, est signalée avec l’impact silencieux. Go signale aussi une écriture dont l’erreur est ignorée (un db.Create(...) nu, _ =, ou une erreur seulement journalisée) alors que la requête répond quand même par un succès : le client croit les données enregistrées alors qu’elles ne le sont peut-être pas.
SmartScan s’active par projet et est désactivé par défaut : Projet → Paramètres → Analyse → Exécuter SmartScan. Il tourne ensuite sur les analyses approfondies de ce projet dès la prochaine exécution du pipeline, sans rien changer au pipeline. Il nécessite le module SmartScan, qu’un administrateur peut désactiver dans Administration → Paramètres → Modules.