ArchScan - Befunde & Qualitätsbericht
ArchScan scannt Ihre Codebasis und erstellt einen vollständig gleichwertigen Bericht mit einem einzigen, kategoriegewichteten Qualitäts-Score.
Berichtsabschnitte
Abschnitt betitelt „Berichtsabschnitte“- Zusammenfassungs-Score - ein einzelner kategoriegewichteter Score + Status, über Versionen hinweg vergleichbar.
- Befunde - mit Code-Snippet und genauer Dateiposition.
- SOLID-Aufschlüsselung - Verstöße werden nach den fünf Prinzipien aufgeschlüsselt.
- Pakete - Abhängigkeiten und Versionen.
- Projekte - Metriken pro Projekt.
- Abhängigkeitskarte - eine interaktive Graphansicht.
- Export - teilbares HTML/PDF; Sie wählen die Berichtssprache pro Workspace.
Wie wird der Score berechnet?
Abschnitt betitelt „Wie wird der Score berechnet?“Die Kategorien Architektur, SOLID, Abhängigkeit und Metrik werden gemäß ihren Gewichtungen zu einem einzigen Score zusammengefasst. Der Scan läuft in Ihrem eigenen CI.
Analytics-Dashboard
Abschnitt betitelt „Analytics-Dashboard“Die ArchScan-Startseite ist ein workspace-weites, asynchron geladenes Dashboard:
- Geprüfte Projekte, Durchschnittsscore, offene Befunde, Audits diesen Monat - Kopfkarten.
- Scan-Trend - Läufe und Durchschnittsscore der letzten 12 Wochen.
- Gesamtbild - Notenring (A-E), Abdeckungs- und Ergebnisbalken, Arbeitstempo-Anzeige.
- Sprachaufschlüsselung - pro Sprache: Projekte, gescannter Anteil, Durchschnittsscore, Fehlschläge.
- Was sich bewegt hat - die Projekte mit der größten jüngsten Verbesserung oder Verschlechterung.
Code Health
Abschnitt betitelt „Code Health“ArchScan → Code Health beantwortet eine andere Frage als der Score: wo die Schuld sitzt. Es liest den letzten Lauf eines Projekts - oder, mit Alle Projekte, die letzten Läufe aller gescannten Projekte zusammengeführt:
- Datei-Risikokarte - eine Treemap: Kachelgröße = konzentriertes Risiko (Befunde gewichtet mit der schlimmsten Methode der Datei), Farbe = schlimmster Schweregrad darin. Kleine Dateien falten sich in eine “Sonstige”-Kachel - nichts fällt stillschweigend weg.
- Komplexitätsverteilung - Methoden nach zyklomatischer Komplexität gebändert (1-5 / 6-10 / 11-20 / 21+), plus die schlimmste Methode namentlich.
- Designschuld nach Prinzip - Befunde gruppiert nach dem Prinzip ihrer Regel (SOLID, DRY, KISS, YAGNI).
- Komponenten auf der Main Sequence - jedes Modul nach Abstraktheit × Instabilität; die Schmerzzone und die Nutzlosigkeitszone sind markiert.
- Hotspots - Dateien, in denen sich Befunde und Komplexität treffen.
Ein Projekt, dessen Runner keine Metriken sendet, wird als nicht gemessen gemeldet - nie als null.
Dependency Health
Abschnitt betitelt „Dependency Health“ArchScan → Abhängigkeiten kehrt die Paketlisten pro Projekt in bestandsweite Antworten um:
- Die Pakettabelle - nach Paket, nicht nach Projekt: welches Paket hält die meisten Projekte zurück, wie weit hinten liegt der schlimmste Pin, welches Projekt nutzt welche Version. Ein auf mehrere Versionen gepinntes Paket wird als gespalten markiert.
- Plattformversionen - das SDK/die Runtime, die jedes Repository deklariert (
csproj/global.json,pyproject.toml,go.mod,pom.xml,Gemfile,composer.json,package.json) - “wer ist noch auf .NET 6” auf einen Blick. Alle sieben Collector-Sprachen melden sie. - Projektzeilen - Summen, Aktualitätsmix und unaufgelöste Abfragen (ein Offline-Runner kann die Registry nicht fragen - das wird als unbekannt gemeldet, nicht als aktuell).
SmartScan
Abschnitt betitelt „SmartScan“ArchScan → SmartScan verfolgt jeden Web-Einstiegspunkt, Quartz-Job, Hintergrunddienst und MassTransit-Consumer eines .NET-Projekts über Services und Handler bis zum ORM (Entity Framework, Dapper) und meldet die Risiken auf dieser Kette. Es ist ein Warnmodul: Es senkt den Score nicht und lässt die Pipeline nicht fehlschlagen. Eine Kette ohne Risiko sendet nichts.
- Datensatz nicht gefunden - eine Abfrage (
FirstOrDefault,Find, …) kann nichts liefern, und das Ergebnis wird ohne Prüfung verwendet. Die Auswirkung zeigt, ob die Anfrage mit 500 endet oder ein allgemeiner Catch weiter oben eine falsche Meldung daraus macht. - Halb geschriebene Daten - eine Anfrage committet mehrmals ohne umschließende Transaktion.
- Länge über der Spalte, fehlender Pflichtwert, doppelter Wert - ein Anfragefeld erreicht eine begrenzte,
NOT NULL- oder eindeutige Spalte ohne passende Regel auf dem Weg. - Anfragewert, den der Code nicht lesen kann (.NET, Java, Kotlin, Python, Go, Ruby, PHP) - ein Wert aus der Anfrage wird ohne vorherige Prüfung mit
int.Parse,Guid.Parse,Convert.ToInt32o. ä. gelesen, sodass ein fehlerhafter Wert mit 500 statt 400 endet. Ein von der Anfrage benannter Datensatz, der mitFirst/Singlegelesen wird, erscheint ebenso unter Datensatz nicht gefunden: fehlt er, endet die Anfrage mit 500 statt “nicht gefunden”. - Durch verknüpfte Datensätze blockiertes Löschen (.NET, Java, Kotlin, Python, Go, Ruby, PHP) - ein Datensatz wird wirklich gelöscht (kein Soft Delete), während andere noch mit
Restrict,NoActionoderClientSetNullauf ihn verweisen können; die Datenbank lehnt das Löschen mit einem Fremdschlüsselfehler ab. Abläufe, die diese Datensätze vorher prüfen, löschen oder umhängen, werden nicht gemeldet. - Wert außerhalb dessen, was die Spalte fasst (.NET; der Decimal-Fall auch Java, Kotlin, Python, Go, Ruby, PHP; der Enum-Fall auch Ruby, PHP) - eine Zahl größer als ihre
decimal(p, s)-Spalte, ein Datum, das die Anfrage weglassen kann und als 0001-01-01 in einer SQL-Server-datetime-Spalte landet, oder ein undefinierter Wert für eine PostgreSQL-Enum-Spalte.
Projekt wählen, Kategorie öffnen: Die Risiken sind nach Schicht und Service (oder Anfragetyp) gruppiert. Ein geöffnetes Risiko zeigt die Kette Schritt für Schritt mit Datei und Zeile, den Code, eine Lösung und einen Prompt zum Kopieren in einen KI-Assistenten. Ein Risiko kann geschlossen werden (Fehlalarm, akzeptiertes Risiko, wird nicht behoben) und bleibt geschlossen, solange dasselbe Risiko gefunden wird.
Bei einem Consumer wird die Nachricht erneut zugestellt (hinter einem Catch-all verschluckt), bei einem Job schlägt der Lauf fehl. Ein Job hat keine Anfrage und wird nur auf halb geschriebene Daten geprüft.
In einem TypeScript-Frontend (React, Next.js) beginnt die Kette dort, wo der Benutzer handelt oder das Framework rendert - ein JSX-Event-Handler, ein useEffect, ein Server-Render (getServerSideProps, eine asynchrone Seite), ein Next.js-Route-Handler - und führt über Hooks, Redux-Thunks und Services bis zur Anfrage (fetch, axios), einschließlich des Sprungs von einer Client-Anfrage zur eigenen API-Route des Projekts. Die Kategorien dort: Unbehandelte Anfrage (ein Anfragefehler, den nichts abfängt: der Benutzer erfährt nichts, oder ein Server-Render antwortet mit 500), Fehler als Erfolg weitergegeben (ein abgefangener Fehler, der als gewöhnlicher Wert zurückkommt, eine Fehlerantwort von fetch, die als Daten gelesen wird, eine Thunk-Ablehnung, die niemand prüft), Datensatz nicht gefunden (dieser leere Wert wird danach gelesen und der Bildschirm wirft einen Fehler) und Halb geschriebene Daten (zwei schreibende Anfragen an das eigene Backend hintereinander). Ein HTTP-Client, der jeden Fehler dem Benutzer zeigt (ein Toast im Interceptor), gilt als Behandlung.
Ruby-on-Rails- und Kotlin-Spring-Backends werden wie .NET verfolgt: Controller-Aktionen (und Grape-Endpunkte), Jobs und Consumer bis zu ActiveRecord oder Spring Data / JPA, mit denselben Kategorien; Spaltengrenzen stammen aus db/schema.rb oder den @Column-Annotationen. Android- (Kotlin) und iOS-Apps (Swift) werden wie ein Frontend verfolgt: von einem Tippen, dem Lebenszyklus eines Bildschirms oder einem View-Model bis zur Anfrage (Retrofit, OkHttp, Ktor; URLSession, Alamofire, Moya). Dort bringt ein unbehandelter Anfragefehler, der aus einer Coroutine entkommt, oder ein try! die App zum Absturz; ein Fehler, der in nil oder einen Standardwert verwandelt wird, gilt als Fehler, der als Erfolg weitergegeben wird.
Backends in Java (Spring Data, JPA, JdbcTemplate, MyBatis), Python (Django und DRF, Flask, FastAPI, Celery; Django ORM, SQLAlchemy), Go (net/http, gin, echo, chi, fiber, gRPC; database/sql, sqlx, GORM, pgx) und PHP (Laravel, Symfony; Eloquent, Doctrine) werden genauso verfolgt, mit denselben Kategorien. In Go ist ein fehlender Datensatz ein Fehler, kein null: Wird ein Nicht-gefunden-Fehler ignoriert, sodass ein leerer Datensatz wie ein gefundener verwendet wird und die Anfrage Erfolg meldet, erscheint das mit der Auswirkung still. Go meldet außerdem einen Schreibvorgang, dessen Fehler verworfen wird (ein bloßes db.Create(...), _ = oder ein nur protokollierter Fehler), während die Anfrage trotzdem Erfolg meldet: Dem Client wird gesagt, die Daten seien gespeichert, obwohl sie es vielleicht nicht sind.
SmartScan wird pro Projekt eingeschaltet und ist standardmäßig aus: Projekt → Einstellungen → Scannen → SmartScan ausführen. Ab dem nächsten Pipeline-Lauf läuft es dann bei den Tiefenscans dieses Projekts, ohne Änderung an der Pipeline. Es setzt das SmartScan-Modul voraus, das Administratoren unter Verwaltung → Einstellungen → Module abschalten können.