Eine undokumentierte Codebasis übernehmen: Ein 30-Tage-Plan für sicheren Start

#übernommene Codebasis
Sandor Farkas - Founder & Lead Developer at Wolf-Tech

Sandor Farkas

Gründer & Lead Developer

Experte für Softwareentwicklung und Legacy-Code-Optimierung

Du hast gerade Zugang zu einem Produktivsystem bekommen. Es gibt keine README, die diesen Namen verdient. Der letzte Entwickler ist vor sechs Monaten gegangen. Im Ticketsystem stehen offene Bugs von 2019. Deine Führungskraft will wissen, wann du das erste Feature ausliefern kannst.

Das ist keine ungewöhnliche Situation. Entwickler übernehmen ständig Codebasen - durch Jobwechsel, Übernahmen, Teamumbauten oder schlicht, weil die Person, die das System geschrieben hat, weitergezogen ist. Ungewöhnlich ist, dabei strukturiert vorzugehen. Die meisten improvisieren, tauchen in Code ein, den sie nicht verstehen, und hoffen, dass nichts kaputtgeht.

Dieser Leitfaden ist ein 30-Tage-Plan, um eine undokumentierte Codebasis systematisch zu übernehmen. Das Ziel ist nicht, alles zu verstehen - das dauert Monate. Das Ziel ist, sicher produktiv zu werden: genug zu verstehen, um Änderungen auszuliefern, ohne unerwartete Fehler auszulösen.

Warum undokumentierte Codebasen gefährlich sind

Eine übernommene Codebasis ist nicht deshalb gefährlich, weil sie schlecht geschrieben wäre, sondern weil sie verstecktes Verhalten hat. Jedes System, das länger als ein Jahr in Produktion läuft, hat Workarounds, implizite Verträge und Logik angesammelt, die wegen eines konkreten Vorfalls existiert, von dem du nie gehört hast.

Die Datenbankspalte, die nullable aussieht, aber wegen eines Bugs im Reporting nie null sein darf. Der API-Endpoint, der auch bei Validierungsfehlern eine 200 zurückgibt, weil eine Drittanbieter-Integration mit 4xx nicht umgehen kann. Der Cronjob, der um 3 Uhr nachts läuft und den halben Cache neu schreibt, und zwar so, dass es bricht, wenn gleichzeitig etwas anderes den Cache anfasst.

Nichts davon steht in Codekommentaren. Manches steht nicht einmal in Commit-Messages. Es lebt in den Köpfen von Menschen, die vielleicht nicht mehr erreichbar sind.

Änderungen ohne Landkarte auszuliefern bedeutet, in diese Minen zu treten. Der folgende 30-Tage-Plan ist darauf ausgelegt, sie freizulegen, bevor deine Änderungen es tun.

Tage 1 bis 7: Beobachten, bevor du etwas anfasst

In der ersten Woche solltest du praktisch keinen Code ändern. Deine Aufgabe ist Beobachtung.

Richte lokales Tooling ein. Bring die Anwendung lokal zum Laufen. Lies die Deployment-Skripte sorgfältig - sie enthalten oft mehr architektonische Wahrheit als die Codebasis selbst. Notiere jede Umgebungsvariable, jede externe Service-Abhängigkeit, jeden Drittanbieter-API-Key, der auftaucht.

Lies die Infrastruktur, nicht nur den Code. Sieh dir das Datenbankschema direkt an. Schau in die Serverkonfiguration. Gibt es einen Load Balancer, lies seine Regeln. Gibt es geplante Jobs, liste sie vollständig auf. Die Infrastruktur sagt dir, was das System tatsächlich tut, statt dessen, was der Code behauptet.

Verfolge die wichtigsten User-Flows. Identifiziere die drei bis fünf wichtigsten Dinge, die die Anwendung leistet - die Abläufe, deren Ausfall den größten Schaden anrichten würde. Zeichne jeden davon vom HTTP-Request bis zum Datenbankschreibvorgang nach. Geh noch nicht in die Tiefe; du zeichnest eine Karte, du liest nicht das Gelände.

Sprich mit allen, die verfügbar sind. Selbst wenn der ursprüngliche Entwickler weg ist, gibt es meist Menschen, die sich erinnern: Support-Mitarbeiter, die wissen, welche Fehler am häufigsten auftreten, ein Product Manager, der weiß, warum ein Feature so gebaut wurde, ein Ops-Engineer, der wegen dieses Systems nachts um 2 Uhr angepiept wurde. Diese Gespräche sind mehr wert als Stunden Codelektüre.

Tage 8 bis 14: Kartiere den tragenden Code

Nicht jeder Code ist gleich wichtig. In den meisten Produktivsystemen deckt ein relativ kleiner Teil der Codebasis die kritischen Pfade ab: Zahlungsabwicklung, Authentifizierung, zentrale Datenschreibvorgänge. Der Rest ist unterstützende Infrastruktur, administratives Werkzeug oder Funktionen, die nur wenige Nutzer je anfassen.

Deine Aufgabe in Woche zwei ist, den tragenden Code zu identifizieren - die Teile, die im Fehlerfall das Geschäft mitreißen.

Fang beim Geldfluss an. Bei einem SaaS-Produkt ist das alles rund um Abonnements, Abrechnung und User-Provisioning. Bei einem E-Commerce-System ist es der Checkout. Bei einer B2B-API sind es die Endpoints, die zahlende Kunden am häufigsten aufrufen. Verfolge diese Pfade vollständig und kommentiere, während du liest.

Lies die Testsuite - oder nimm ihr Fehlen zur Kenntnis. Tests sind Dokumentation. Ein gut geschriebener Test sagt dir, was ein Stück Code tun soll, welche Eingaben es verarbeitet und an welche Grenzfälle der Autor gedacht hat. Gibt es keine Tests, ist auch dieses Fehlen eine wichtige Information: Änderungen an diesem Code haben kein Sicherheitsnetz.

Kartiere die Datenbankabhängigkeiten. Verstehe für jede Tabelle, welche Teile der Anwendung schreiben, welche lesen und ob es Constraints oder Trigger gibt, die Geschäftsregeln auf Datenbankebene durchsetzen. Diese Regeln auf Datenbankebene sind oft die letzte Verteidigungslinie und das Erste, was ein neuer Entwickler versehentlich bricht. Unsere Arbeit an Legacy-Code-Optimierung findet regelmäßig Geschäftslogik in Datenbanktriggern, von der niemand im aktuellen Team weiß.

Identifiziere die Integrationspunkte. Jeder externe Dienst - Payment-Gateway, E-Mail-Provider, Analytics-Plattform, Drittanbieter-API - ist ein potenzieller Ausfallpunkt. Liste sie alle auf. Finde heraus, was passiert, wenn einer nicht verfügbar ist. Fällt die Anwendung sauber zurück, oder legt ein Timeout des Zahlungsdienstleisters den gesamten Request-Zyklus lahm?

Tage 15 bis 21: Bau ein Sicherheitsnetz

Mitte der dritten Woche solltest du eine brauchbare Karte des Systems haben. Jetzt kannst du das Sicherheitsnetz bauen, das Änderungen sicher macht.

Schreibe Characterisation Tests. Characterisation Tests prüfen nicht, was der Code tun sollte, sondern was er aktuell tut. Führe den Code mit einer bekannten Eingabe aus, halte die Ausgabe fest und schreibe einen Test, der diese Ausgabe zusichert. Änderst du den Code später und die Ausgabe ändert sich, schlägt der Test fehl. Das ist keine Garantie für Korrektheit, aber eine Garantie für Konsistenz, und die ist in einer übernommenen Codebasis oft nützlicher.

Die Technik ist in PHP unkompliziert:

public function testOrderTotalCalculation(): void
{
    $order = $this->buildTestOrder(['items' => $this->fixtures['standard_cart']]);
    $total = $this->calculator->calculate($order);
    // Zuerst die tatsächliche Ausgabe festhalten, dann zusichern
    $this->assertEquals('247.83', $total->formatted());
}

Führe das gegen produktionsnahe Datenformen aus und halte fest, was das System tatsächlich zurückgibt. Damit hast du eine Regressionssuite für das Verhalten, das heute existiert.

Ergänze Logging in den dunklen Ecken. Genau die Codepfade, bei denen du am nervösesten bist - die, bei denen du nicht sicher weißt, was sie auslöst - sollten genug loggen, um debuggbar zu sein. Setze strukturierte Logeinträge am Eintritt und Austritt kritischer Funktionen. Du optimierst noch nicht; du machst das System beobachtbar.

Richte Error-Tracking ein, falls es fehlt. Sendet die Anwendung Fehler noch nicht an einen zentralen Dienst, richte das jetzt ein. Zu verstehen, was in Produktion fehlschlägt und wie oft, ist unverzichtbarer Kontext für jede Änderung, die du vorhast.

Tage 22 bis 30: Liefere etwas Kleines, sicher

Die letzte Woche geht darum, zu beweisen, dass du das System ändern kannst, ohne es zu brechen.

Wähle eine wirklich kleine Aufgabe. Deine erste Änderung in einer übernommenen Codebasis sollte so klein sein, dass der Schadensradius begrenzt bleibt, falls etwas schiefgeht. Ein Bugfix in einem unkritischen Ablauf, eine UI-Änderung ohne Geschäftslogik, ein neuer API-Endpoint, der keine bestehenden Daten verändert. Widerstehe dem Druck, etwas Beeindruckendes zu liefern.

Schreibe den Test zuerst. Schreibe für deine Änderung einen Test, der das neue Verhalten prüft, bevor du sie implementierst. Ist die Testinfrastruktur zu kaputt, um in diesem Bereich Tests zu schreiben, repariere zuerst die Testinfrastruktur. Diesen Schritt aus Zeitgründen zu überspringen kostet zwei Wochen später meist mehr Zeit.

Reviewe deine eigene Änderung, als hättest du sie geerbt. Frag dich vor dem Commit: Würde eine Entwicklerin, die diese Änderung ohne meine Erklärung übernimmt, verstehen, warum es sie gibt? Wüsste sie, dass sie sie nicht zurückdrehen darf? Falls nein, schreib einen Kommentar dazu.

Deploye zuerst auf eine Staging-Umgebung. Gibt es keine Staging-Umgebung, gehört ihr Aufbau in die Arbeit deiner ersten Woche. Eine Änderung an einem undokumentierten System direkt in Produktion zu deployen ist ein Risiko, das sich mit minimalem Aufwand vermeiden lässt.

Dokumentiere, was du gelernt hast. Jede Entdeckung der vergangenen 30 Tage - jedes versteckte Verhalten, jede überraschende Abhängigkeit, jeder Workaround ohne Erklärung - gehört in ein Dokument. Es muss nicht poliert sein. Eine Stichpunktliste mit Dingen, für deren Entdeckung du eine Woche gebraucht hast, ist mehr wert als gar keine Dokumentation.

Was tun, wenn du etwas Alarmierendes findest

Du wirst etwas Alarmierendes finden. Sicherheitslücken, fest einkodierte Zugangsdaten, unverschlüsselte sensible Daten, eine Abfrage, die die Datenbank in die Knie zwingen würde, sobald eine bestimmte Tabelle eine gewisse Größe überschreitet. Das ist normal.

Die Entscheidung, was du sofort behebst und was du dokumentierst und später angehst, hängt vom Schweregrad ab. Ein fest einkodierter API-Key in einem öffentlichen Repository muss heute rotiert werden. Ein Performance-Problem, das erst beim Zehnfachen des heutigen Traffics auftritt, kann auf ein priorisiertes Backlog.

Was du nie tun solltest: alarmierende Dinge still und ohne Ankündigung reparieren. Der ursprüngliche Entwickler kannte das Problem vielleicht und hat es aus damals nachvollziehbaren Gründen nicht behoben. Deine Stakeholder müssen von wesentlichen Risiken wissen, um informierte Entscheidungen treffen zu können. Wenn du externe Augen auf deine Funde werfen lassen willst, ist Code-Quality-Consulting ein Weg zu einer unabhängigen Einschätzung, die bei Entscheidern Gewicht hat.

Das Ergebnis nach 30 Tagen

Nach 30 Tagen wirst du die Codebasis nicht vollständig verstehen. Das ist in Ordnung. Ein komplexes Produktivsystem vollständig zu verstehen dauert Monate, und auf dieses Verständnis zu warten, bevor du irgendetwas auslieferst, ist keine gangbare Option.

Was du haben solltest: eine Karte des tragenden Codes, damit du weißt, wo du besonders vorsichtig sein musst; eine Suite von Characterisation Tests, die Regressionen in den kritischen Pfaden abfängt; genug Logging und Error-Tracking, um Probleme schnell zu debuggen; eine Aufzeichnung der überraschenden Funde, damit sie niemanden sonst überraschen; und eine ausgelieferte Änderung, die beweist, dass du dich im System bewegen kannst, ohne es zu brechen.

Dieses Fundament reicht, um darauf aufzubauen. Wenn du ein System in schlechtem Zustand übernimmst und Unterstützung bei der Priorisierung brauchst, melde dich unter hello@wolf-tech.io oder besuche wolf-tech.io. Wir arbeiten regelmäßig mit Teams in genau dieser Lage.