Review auf Neural Slop
Neural Slop ist kein Stil, sondern Behauptungen, die nicht belegt sind, und Code, der keinen Grund hat zu existieren. Jeder Fund unten wird durch Fakten überprüft: durch eine Codezeile, eine Befehlsausgabe oder das Fehlen eines Konsumenten. Geschmacksurteile und das, was ein Linter fängt, fallen nicht darunter.
Prinzipien.
- Löschen ist besser als Hinzufügen. Eine tote Option wird entfernt, nicht dokumentiert; ein Marketingsatz wird durch einen Faktenbeleg ersetzt oder entfernt.
- Eine Behauptung wird am Code geprüft, nicht aus dem Gedächtnis. Bevor du eine README-Zeile als falsch oder richtig bezeichnest, öffne die Datei, über die sie spricht.
- Ein Fund ohne Beweis ist kein Fund. Wenn du kein
file:lineoder eine Befehlsausgabe zeigen kannst, schreib es nicht. - Änderungen erfolgen nur auf Wunsch. Standardmäßig ist das Review-Ergebnis eine Liste.
1. Ablauf
- Umfang festlegen: Diff (
git diff main...HEAD), bestimmte Dateien oder das gesamte Repository vor der Veröffentlichung. - Die Suche aus Abschnitt 3 durchführen – sie liefert Kandidaten, keine Funde.
- Jeden Kandidaten durch Lesen des Codes überprüfen und Fehlalarme verwerfen.
- Die Checkliste aus Abschnitt 2 für das abarbeiten, was die Suche nicht fängt: README vs. Code, UI-Zustände, Abstraktionen.
- Wenn möglich, die Anwendung starten und die Seiten betrachten – Vorlagenseiten und ungestaltete Komponenten fallen sofort auf.
- Bericht im Format aus Abschnitt 4 erstellen.
2. Checkliste
2.1. Überbleibsel von Generatoren und Vorlagen
- Startseiten und Blöcke von Generatoren: „Get started by editing“, Links zur Framework- und Tool-Dokumentation,
utm_source=…-project, „Give us a star“, Blöcke zu Cloud-Diensten des Tools. - Vorlagendateien:
example.spec.ts, Tests, die nur den Titel der Vorlage prüfen; SVG und Bilder aus der Vorlage inpublic/; README des Generators. - Leere Platzhalter:
.gitkeepin Ordnern, die bereits Dateien enthalten; leereindex.ts; Layer-Ordner ohne Code.
2.2. Totes und Unfertiges
- Config-Werte oder
switch-Zweige, die „not implemented“ / „pending“ werfen. - Aufzählungen mit einem einzigen Wert, die wie ein Erweiterungspunkt aussehen (
type: "graphql" | "msw", wobeimswnicht implementiert ist). - Auskommentierter Code,
TODOohne Grund und Verweis, ungenutzte Exporte, Abhängigkeiten inpackage.json, die nirgends importiert werden. - Skripte in
package.json, die nicht laufen (verweisen auf gelöschte Dateien oder nicht existierende Targets).
2.3. Dokumentation vs. Code
Jede Behauptung in README, ADR, Kommentaren und Commit-Beschreibungen wird überprüft:
- Namen und Pfade: genannte Dateien, Befehle, Umgebungsvariablen existieren (
next.config.tsim Text undnext.config.jsim Repository – Fund). - Verhalten: „Anfragen gehen direkt“, „Tokens sind für JS nicht zugänglich“, „vor Open Redirect geschützt“ – finde den Code, der das implementiert, und prüfe Randfälle.
- Versionen und Zahlen: Bibliotheksversionen, Token-Lebensdauer, Abdeckung.
- Zukunft im Präsens: was geplant ist, wird als erledigt beschrieben.
- Links und Anker in Markdown führen dorthin, wohin sie sollen (Anker brechen beim Ändern von Überschriften).
2.4. Ton
- Wertende Wörter statt Fakten: premium, state-of-the-art, cutting-edge, blazing/lightning-fast, seamless, robust, powerful, modern, production-ready, enterprise-grade, „mehr als nur“, „exklusiv“, „modern“, „leistungsstark“.
- Emojis in Überschriften der Dokumentation, in UI, in Logs und Commit-Nachrichten.
- „Designed with ❤️“, „Carefully crafted“, Badges um der Badges willen.
- Kommentare, die nur zusammenfassen („// Holt den Benutzer“ über
getUser()), Kommentare mit Geschichte („// Gefixt“, „// Aktualisiert auf X“), Kommentare in GROSSBUCHSTABEN, „IMPORTANT“-Marker ohne Erklärung. - Überschriften und Kommentare im Stil „🚀 Production Roadmap“ und „(Premium Aesthetic)“.
Ersatz: Fakten – was tut es, warum so, welche Einschränkung.
2.5. Überflüssige Abstraktionen
- Interface oder Factory mit einer einzigen Implementierung und ohne Mock in den Tests.
- Schicht, Zone, Monorepo-Paket, State-Manager, Storybook ohne Konsument oder ohne dokumentierten Grund (ADR, README-Abschnitt).
- Wrapper, die nur umbenennen (
useAuthApi = () => useStrictContext(Ctx)ohne Logik – ok; Wrapper über Wrapper – nein). - „Für die Zukunft“: Parameter, die niemand übergibt, Config-Optionen mit nur einem Wert.
2.6. Fehler und Asynchronität
- Fehlertyp wird aus der Nachricht bestimmt (
message === "unauthorized",includes("invalid password")) – ohne Kommentar und Tests. - Nur das erste Element des Fehlerarrays wird geprüft (
errors[0]). throw { status, ... }– Objekt stattError.- Leerer
catch,catchder leere Daten zurückgibt,.catch(() => {}). - Gemeinsamer in-flight Promise, dessen Ergebnis Wartende nicht lesen (Token-Refresh „warten, dann wiederholen“ ohne Prüfung des Erfolgs).
error.messagedes Servers wird unverändert dem Benutzer gezeigt.- Fehlende Zustände für Laden, Fehler, leere Liste.
2.7. Sicherheit und Privatsphäre
- Personenbezogene Daten in Logs: E-Mail, Telefon, Name; Tokens; Request-Bodies.
- Secrets im Repository oder in der History (
git log -p),.envim Index, Secrets mit PräfixNEXT_PUBLIC_. - Redirects per Parameter (
callbackUrl,next,returnTo) ohne Prüfung oder nur mitstartsWith("/")/!startsWith("//")– erlaubt/\evil.comund Steuerzeichen. - Tokens in
localStorage/sessionStorage; Token in der URL, der nach dem Lesen nicht aus der Adresszeile entfernt wird. dangerouslySetInnerHTMLohne Sanitizer.
2.8. UI
- Klassen, die es im Theme nicht gibt: kopierte Tokens aus shadcn/ui (
bg-card,text-muted-foreground,bg-primary) in einem Projekt ohne diese Tokens – Komponente wird stumm ohne Styles dargestellt. - Rohe HEX- und beliebige Werte in Komponenten, wenn Tokens vorhanden sind.
- Zustand „Feld ausgefüllt“, der in
onChangegesetzt wird: bricht bei Autovervollständigung undreset(). key={index}bei änderbaren Listen; Buttons ohnetypein Formularen; Icon-Buttons ohnearia-label.- SVG aus dem Layout mit Filtern (Schatten, Glow), die durch
viewBoxbeschnitten sind – sichtbares Rechteck um das Logo.
2.9. Tests
- Tests, die Mocks testen, nicht das Verhalten; Snapshots großer Bäume.
- e2e gegen gemeinsames oder Produktions-Backend, die Daten verändern.
- Tests, die nur deshalb bestehen, weil jsdom kein CSS anwendet (Element ist durch Klasse „versteckt“, Test findet es trotzdem), und breite Selektoren (
/password/i, der auch auf „Show password“ matched).
2.10. Git
- Zusammenhanglose Änderungen in einem Commit; Commit „fix stuff“.
- Generierte Dateien und Build-Artefakte im Index (außer bewusst eingecheckter generierter API-Client).
- Commit-Nachricht beschreibt nicht das, was im Diff steht.
3. Kandidatensuche
Die Befehle liefern Kandidaten. Jeder Treffer wird durch Lesen des Codes überprüft.
# Generator-Vorlagen und Marketing
rg -n -i "utm_source|get started by editing|give us a star|nx cloud|welcome to|carefully crafted|designed with" \
--glob '!**/node_modules/**' --glob '!*.lock' --glob '!pnpm-lock.yaml'
rg -n -i "premium|state-of-the-art|cutting-edge|blazing|lightning|seamless|robust|enterprise-grade|production-ready| премиальн | современн | мощн" \
--glob '!**/node_modules/**'
# Emojis in Code, UI und Dokumentation
rg -n --pcre2 '[\x{1F300}-\x{1FAFF}\x{2600}-\x{27BF}]' --glob '!**/node_modules/**' --glob '!*.lock'
# Unfertiges
rg -n -i "not implemented|pending implementation|todo|fixme|hack" --glob '!**/node_modules/**'
# Fragile Fehler
rg -n "errors\?\.\[0\]|errors\[0\]|message ===|message\.includes|\.includes\([\'"][a-z ]+[\'\"\)]" src app
rg -n "throw \{" src app
rg -n "catch \{\s*\}|catch \(\w*\) \{\s*\}|\.catch\(\(\) => \{\s*\}\)" src app
# Logs mit personenbezogenen Daten
rg -n "(logger|console)\.\w+\(.*(email|phone|password|token)" src app
# Redirects und Tokens
rg -n "callbackUrl|returnTo|redirectTo|searchParams.get\([\'\"]next" src app
rg -n "localStorage|sessionStorage" src app
# shadcn-Klassen ohne Tokens: finde Klassen und gleiche mit @theme / tailwind-config ab
rg -n -o "\b(bg|text|border)-(card|muted|popover|accent|primary|secondary|destructive)(-foreground)?\b" src app | sort -u
# Ungenutzte Abhängigkeiten und Exporte (falls knip installiert)
pnpm dlx knip
# Secrets in der History
git log -p --all | rg -n -i "(api[_-]?key|secret|password|token)\s*[:=]\s*[\'\"][A-Za-z0-9_\-]{16,}"
git ls-files | rg -n "(^|/)\.env($|\.)" | rg -v "\.env\.example$"
4. Berichtsformat
Funde geordnet nach Wichtigkeit: Sicherheit und Privatsphäre → falsche Behauptungen in der Dokumentation → Bugs in der Fehlerbehandlung → Totes und Unfertiges → Vorlagen → Ton.
<file>:<line> — <Kategorie>
Was: <ein Satz: was nicht stimmt, mit Fakt>
Warum wichtig: <Folge für Nutzer, Reviewer oder Wartung>
Korrektur: <konkret; meistens „löschen“ oder „durch Fakt ersetzen: …“>
Am Ende: was geprüft wurde und keine Funde ergeben hat, und was nicht geprüft wurde (z.B. Anwendung nicht gestartet). Wenn es keine Funde gibt – genauso sagen, ohne erzwungene Anmerkungen.