Use Cases (Aktualisiert: 1.6.2026)

Sicheres Refactoring mit Claude Code automatisieren

Praktischer Workflow für Claude Code Refactoring: Vorher/Nachher, Tests, git diff, Review, Risiken und sofort nutzbare Prompts.

Sicheres Refactoring mit Claude Code automatisieren

Zuerst die Sicherheitsgrenze festlegen

Der sicherste Weg, Refactoring mit Claude Code zu automatisieren, ist nicht der Prompt “räum den Code auf”. Das klingt produktiv, führt aber oft zu einem großen Diff, den niemand sauber prüfen kann. Refactoring bedeutet, die interne Struktur zu verbessern, ohne das Verhalten zu ändern, auf das Benutzer, APIs, Tests und andere Systeme angewiesen sind. Wenn diese Grenze unklar ist, wird aus Automatisierung schnell unbeabsichtigte Feature-Arbeit.

Dieser Artikel behandelt Claude Code als praktischen Partner: erst untersuchen, dann einen kleinen Plan erstellen, genau eine Änderung umsetzen, Tests ausführen und den git diff erklären. Die offiziellen common workflows zeigen diese Arbeitsweise gut. Für Befehlsrechte und Projektkonfiguration ist außerdem die Dokumentation zu settings wichtig.

Wenn dein Team gerade Regeln für den Einsatz erstellt, lies auch die Artikel zu Claude Code Berechtigungen und Claude Code Kontextmanagement. Hier geht es um den Alltag: was man zuerst fragt, welche Änderungen für Einsteiger sicher sind, wie man testet und wie man das Ergebnis prüft.

Masa-Notiz aus der Praxis: In kleinen Tests war Claude Code stark bei Umbenennungen, dem Extrahieren reiner Funktionen, dem Klären von TypeScript-Typen und dem Ergänzen von Regressionstests. Schwieriger wurde es bei breiten Prompts wie “modernisiere diesen Service”. Der langweilige Workflow ist der wirtschaftliche: enger Scope, sichtbare Tests, kleiner Diff.

Sicherer Workflow: untersuchen, planen, einen Diff ändern, verifizieren

Nutze diese Reihenfolge, bis das Team Vertrauen aufgebaut hat.

SchrittWas Claude Code tutWas der Mensch prüft
1. UntersuchenDateien, Abhängigkeiten und Tests lesenScope ist nicht zu groß
2. PlanenPlan mit maximal drei Schritten vorschlagenKeine versteckte Verhaltensänderung
3. ÄndernNur ein Thema bearbeitenDiff ist reviewbar
4. VerifizierenTests, typecheck und lint ausführenFehler sind klar erklärt
5. Reviewgit diff und Risiken zusammenfassenBefore/after Verhalten bleibt gleich

Beginne mit einem Prompt ohne Dateiedits.

Untersuche dieses Repository auf sichere Refactoring-Kandidaten.
Bearbeite noch keine Dateien.

Bedingungen:
- Externes Verhalten nicht ändern
- Ein Diff umfasst höchstens drei Dateien
- Bereiche mit vorhandenen Tests bevorzugen
- Gib eine Tabelle aus: Kandidat, Grund, Prüfbefehl, Risiko

“Bearbeite noch keine Dateien” ist wichtig. Claude Code kann schnell von Analyse zu Umsetzung wechseln. Wenn Untersuchung und Implementierung getrennt sind, sinkt das Risiko deutlich.

Lege vor der Änderung einen Branch an und sichere die Ausgangslage.

git status --short
git checkout -b refactor/safe-extract-order-total
npm test
npm run typecheck
npm run lint

Passe die Befehle an dein package.json an. Wenn Tests schon vor dem Refactoring fehlschlagen, dokumentiere das. Sonst ist später unklar, ob Claude Code etwas kaputt gemacht hat oder ob der Fehler bereits existierte.

Use case 1: Umbenennen und eine kleine reine Funktion extrahieren

Der sicherste Einstieg ist bessere Benennung plus Extraktion einer reinen Funktion. Eine reine Funktion liefert für dieselbe Eingabe dasselbe Ergebnis und verändert keine Datenbank, sendet keine E-Mail, ruft keine API auf und ändert keinen globalen Zustand. Das ist ideal für Claude Code, weil Erfolg leicht testbar ist.

// before: src/domain/order.ts
export function calc(o: { items: { p: number; q: number }[]; d?: number }) {
  let t = 0;
  for (const i of o.items) {
    t += i.p * i.q;
  }
  if (o.d) {
    t = t - o.d;
  }
  return Math.max(t, 0);
}

Der Code ist kurz, aber p, q und d erklären die Fachlogik nicht. Bitte Claude Code, zuerst Tests zu ergänzen und danach Namen zu verbessern.

Refactore die Funktion calc in src/domain/order.ts sicher.

Anforderungen:
- Vor der Implementierungsänderung Unit-Tests ergänzen, die aktuelles Verhalten fixieren
- Der exportierte Name calc bleibt in diesem Diff gleich
- Variablen- und Typnamen verbessern
- Die Regel, dass der Gesamtbetrag nie negativ wird, bleibt erhalten
- Danach npm test -- order ausführen

Ein gutes Ergebnis bleibt klein.

// after: src/domain/order.ts
type OrderLine = {
  price: number;
  quantity: number;
};

type OrderInput = {
  items: OrderLine[];
  discount?: number;
};

export function calc(order: OrderInput): number {
  const subtotal = order.items.reduce(
    (sum, item) => sum + item.price * item.quantity,
    0
  );

  return Math.max(subtotal - (order.discount ?? 0), 0);
}

Kopierbare Tests:

// src/domain/order.test.ts
import { describe, expect, it } from "vitest";
import { calc } from "./order";

describe("calc", () => {
  it("multiplies price and quantity", () => {
    expect(calc({ items: [{ price: 1200, quantity: 2 }] })).toBe(2400);
  });

  it("applies discount without returning a negative total", () => {
    expect(calc({ items: [{ price: 500, quantity: 1 }], discount: 800 })).toBe(0);
  });
});

Prüfe nur die geänderten Dateien.

git diff -- src/domain/order.ts src/domain/order.test.ts
npm test -- order
npm run typecheck

Die Review-Frage lautet nicht “sieht der Code schlau aus?”, sondern “behalten dieselben Eingaben dieselbe fachliche Bedeutung?”. Prüfe Berechnung, exportierten Namen und Testbeschreibungen.

Use case 2: any entfernen, indem zuerst die Grenze typisiert wird

any zu reduzieren ist wertvoll, aber projektweit auf einmal ist es riskant. Beginne an Grenzen: API-Antworten, Formulare, Konfiguration, Webhooks oder importierte CSV-Zeilen. Dort kommen unbekannte Daten ins System.

// before: src/lib/user-api.ts
export async function fetchUser(id: string): Promise<any> {
  const response = await fetch(`/api/users/${id}`);
  return response.json();
}

export function getDisplayName(user: any): string {
  return user.profile.displayName || user.name;
}

Gib Claude Code ein enges Ziel und beschreibe fehlende Daten.

Reduziere any in src/lib/user-api.ts.

Anforderungen:
- Typ für die API-Antwort ergänzen
- Fetch-URL und Rückgabebedeutung bleiben gleich
- getDisplayName ist sicher, wenn profile fehlt
- Tests für aktuelles Anzeigeverhalten ergänzen
- npm test -- user-api und npm run typecheck ausführen

Ein akzeptabler erster Diff:

// after: src/lib/user-api.ts
export type UserResponse = {
  id: string;
  name: string;
  profile?: {
    displayName?: string;
  };
};

export async function fetchUser(id: string): Promise<UserResponse> {
  const response = await fetch(`/api/users/${id}`);
  return response.json() as Promise<UserResponse>;
}

export function getDisplayName(user: UserResponse): string {
  return user.profile?.displayName ?? user.name;
}

Dieser Cast validiert keine Laufzeitdaten. Wenn echte Eingabesicherheit nötig ist, folgt ein zweiter Diff mit zod oder einem vorhandenen Parser. Mische nicht “any entfernen” und “Validierungsbibliothek einführen” im ersten Einsteiger-Diff.

// src/lib/user-api.test.ts
import { describe, expect, it } from "vitest";
import { getDisplayName, type UserResponse } from "./user-api";

describe("getDisplayName", () => {
  it("uses profile displayName when present", () => {
    const user: UserResponse = {
      id: "u1",
      name: "Masa",
      profile: { displayName: "Masa I." },
    };

    expect(getDisplayName(user)).toBe("Masa I.");
  });

  it("falls back to name when profile is missing", () => {
    expect(getDisplayName({ id: "u2", name: "Guest" })).toBe("Guest");
  });
});

Suche im Review nach gefährlichen Abkürzungen: as any, geschluckte Fehler, leere Strings als Fallback oder verändertes Verhalten optionaler Felder. Ein stärker typisierter Diff kann trotzdem Verhalten brechen.

Use case 3: Große Funktionen erst mit Test-Harness aufteilen

Große Service-Funktionen sind verlockend, verstecken aber oft Fachlogik. Bestellungen, Abrechnung, Berechtigungen, Benachrichtigungen und Importe mischen Validierung, Berechnung, Persistenz und Seiteneffekte. Lass Claude Code zunächst nur ein reines Stück extrahieren.

// before: src/services/order-service.ts
export async function createOrder(input: CreateOrderInput) {
  if (input.items.length === 0) {
    throw new Error("items required");
  }

  const subtotal = input.items.reduce((sum, item) => sum + item.price * item.quantity, 0);
  const shippingFee = subtotal >= 10000 ? 0 : 800;
  const total = subtotal + shippingFee;

  const order = await db.order.create({
    data: { userId: input.userId, subtotal, shippingFee, total },
  });

  await mailer.sendOrderCreated(order.id);
  return order;
}

Der Prompt muss auch Nicht-Ziele festlegen.

Mache createOrder in src/services/order-service.ts kleiner.

In diesem Diff:
- Nur Versand- und Gesamtberechnung in eine reine Funktion extrahieren
- Name: calculateOrderTotals
- Unit-Tests für calculateOrderTotals ergänzen
- Reihenfolge von Datenbank-Schreibvorgang und E-Mail beibehalten

Nicht in diesem Diff:
- Datenbankschema ändern
- Fehlermeldungen ändern
- API-Antwortform ändern
- Unrelated Funktionen verschieben
- Ganze Datei formatieren

Danach:

// after: src/services/order-service.ts
export function calculateOrderTotals(items: OrderItem[]) {
  const subtotal = items.reduce(
    (sum, item) => sum + item.price * item.quantity,
    0
  );
  const shippingFee = subtotal >= 10000 ? 0 : 800;

  return {
    subtotal,
    shippingFee,
    total: subtotal + shippingFee,
  };
}

Review-Befehle:

git diff --stat
git diff -- src/services/order-service.ts
git diff -- src/services/order-service.test.ts
npm test -- order-service

Wenn Claude Code nebenbei formatiert:

Dieser Diff ist zu groß.
Nimm reine Formatierungsänderungen zurück und behalte nur die Extraktion von calculateOrderTotals plus Tests.
Ändere kein externes Verhalten, keine Fehlermeldungen, keine DB-Schreibvorgänge und keine E-Mail-Reihenfolge.

Mit git diff reviewen, nicht nach Gefühl

Die Erklärung von Claude Code ist hilfreich, aber der Diff ist die Wahrheit.

git diff --check
git diff --stat
git diff --name-only
git diff --word-diff -- src/domain/order.ts
BereichWas prüfen
VerhaltenEingaben, Ausgaben, Exceptions, HTTP-Status und Persistenzreihenfolge
GrößeÄnderung passt in eine menschliche Review
TestsBestehendes Verhalten ist abgesichert
TypenKein neues as any, keine unsicheren Casts, keine ignorierten Fehler
SeiteneffekteAPI, E-Mail, Billing, Löschen und Rechte behalten Reihenfolge
ZusammenfassungClaude Codes Erklärung passt zum echten Diff

Review-Prompt:

Reviewe diesen git diff.

Prüfe:
- Überschreitet die Änderung den Refactoring-Scope?
- Welches Verhalten ist nicht durch Tests geschützt?
- Gibt es unsichere Casts oder geschluckte Fehler?
- Welche Dateien muss ein Mensch besonders prüfen?

Antworte mit:
- Sieht sicher aus
- Braucht menschliche Bestätigung
- Muss korrigiert werden
und nenne Dateien und Gründe.

Pitfall: typische Fehler und Risiken

Erster failure: ein zu breiter Prompt.

Mach diese Service-Schicht sauberer.

Das kann Extraktion, Namen, Fehlerdesign, Dateiverschiebung und Formatierung vermischen. Besser:

Extrahiere nur die Versandkostenberechnung aus createOrder in eine reine Funktion.
Ändere keine Prozessreihenfolge, Fehlermeldungen oder Rückgabewerte.

Zweiter risk: einen schön aussehenden Diff ohne Tests akzeptieren. Lesbarkeit kann steigen, während Grenzfälle kippen: Rabatte, kostenloser Versand, Rechte, Retry-Verhalten oder Nullwerte. Dritter Fehler: Formatierung und strukturelles Refactoring mischen. Wenn Prettier hunderte Zeilen ändert, ist die echte Änderung versteckt. Vierter Risk: Befehlsrechte zu früh zu weit öffnen. Beginne mit Lesen, Tests, typecheck und lint; erweitere später.

Wiederverwendbare Checklist und CTA

## Refactoring checklist

- [ ] Die Änderung hat genau ein Ziel
- [ ] Baseline-Tests liefen vor dem Editieren
- [ ] Before/after Verhalten ist gleich
- [ ] Bestehende oder neue Tests schützen das Verhalten
- [ ] git diff --stat ist klein genug für Review
- [ ] git diff --check läuft durch
- [ ] Keine neuen any, unsicheren Casts oder geschluckten Fehler
- [ ] DB, E-Mail, Billing, Löschen und Rechte behalten ihre Reihenfolge

Finaler Prompt:

Führe genau einen sicheren Refactoring-Diff aus.

Ziel:
- src/services/order-service.ts
- src/services/order-service.test.ts

Erfolgskriterien:
- Externes Verhalten ändert sich nicht
- calculateOrderTotals wird extrahiert
- Bestehende und neue Tests bestehen
- Berichte git diff --stat und ausgeführte Befehle

Verboten:
- DB-Schemaänderungen
- API-Response-Änderungen
- Änderungen an Fehlermeldungen
- Bearbeitung unrelated Dateien

In meiner Prüfung brachten zwei Gewohnheiten den größten Qualitätsgewinn: zuerst ein Plan ohne Edit und am Ende immer eine git diff-Zusammenfassung. Kombiniere das mit der Claude Code Review-Checkliste und den CLAUDE.md Best Practices, damit das Team den Prozess wiederholen kann.

Wenn dein Team Claude Code sicher einführen will, kann das Claude Code Training Berechtigungen, Prompts, Review-Gewohnheiten und Workflow-Design abdecken. Refactoring-Automation lohnt sich, wenn sie Wartungsrisiko senkt, nicht wenn sie spektakuläre, unprüfbare Diffs erzeugt.

#Claude Code #refactoring #code quality #automation #TypeScript
Kostenlos

Kostenloses PDF: Claude-Code-Cheatsheet

E-Mail eintragen und eine Seite mit Befehlen, Review-Gewohnheiten und sicheren Workflows herunterladen.

Wir schützen Ihre Daten und senden keinen Spam.

Masa

Über den Autor

Masa

Engineer für praktische Claude-Code-Workflows und Team-Einführung.