Erweiterung exportierter Go-Backends mit sicherer eigener Middleware
Exportierte Go-Backends erweitern, ohne Änderungen zu verlieren: wohin benutzerdefinierte Logik gehört, wie Middleware und Endpunkte hinzugefügt werden und wie du Upgrades planst.

Was schiefgeht, wenn du exportierten Code anpasst
Exportierter Code ist nicht dasselbe wie ein handgeschriebenes Go-Repo. Bei Plattformen wie AppMaster wird das Backend aus einem visuellen Modell (Datenschema, Business-Prozesse, API-Setup) generiert. Beim Re-Export kann der Generator große Teile des Codes neu schreiben, um dem aktualisierten Modell zu entsprechen. Das hält das Projekt sauber, verändert aber die Art und Weise, wie du anpassen solltest.
Das häufigste Problem ist, generierte Dateien direkt zu bearbeiten. Es klappt einmal, beim nächsten Export werden deine Änderungen überschrieben oder es entstehen hässliche Merge-Konflikte. Noch schlimmer: kleine manuelle Änderungen können stillschweigend Annahmen des Generators brechen (Routing-Reihenfolge, Middleware-Ketten, Request-Validierung). Die App kompiliert vielleicht noch, aber das Verhalten ändert sich.
Sichere Anpassung bedeutet, dass deine Änderungen wiederholbar und leicht zu überprüfen sind. Wenn du das Backend erneut exportieren, deine Custom-Schicht anwenden und klar sehen kannst, was sich geändert hat, bist du auf dem richtigen Weg. Wenn sich jedes Upgrade wie Archäologie anfühlt, bist du es nicht.
Hier sind die Probleme, die typischerweise auftreten, wenn Anpassungen am falschen Ort stattfinden:
- Deine Änderungen verschwinden nach einem Re-Export oder du verbringst Stunden mit dem Lösen von Konflikten.
- Routen verschieben sich und deine Middleware läuft nicht mehr an der erwarteten Stelle.
- Logik wird zwischen No-Code-Modell und Go-Code dupliziert und driftet auseinander.
- Eine „Ein-Zeilen-Änderung" wird zu einem Fork, den niemand anfassen will.
Eine einfache Regel hilft zu entscheiden, wohin Änderungen gehören. Wenn die Änderung Teil des Geschäftsverhaltens ist, das Nicht-Entwickler anpassen sollten (Felder, Validierung, Workflows, Berechtigungen), gehört sie ins No-Code-Modell. Wenn sie Infrastrukturverhalten betrifft (benutzerdefinierte Auth-Integration, Request-Logging, spezielle Header, Rate-Limits), gehört sie in eine benutzerdefinierte Go-Schicht, die Re-Exports überlebt.
Beispiel: Audit-Logging für jede Anfrage ist meist Middleware (Custom-Code). Ein neues Pflichtfeld für eine Bestellung gehört dagegen normalerweise ins Datenmodell (No-Code). Halte diese Trennung klar, dann bleiben Upgrades vorhersehbar.
Die Codebasis kartieren: generierte Teile vs. deine Teile
Bevor du ein exportiertes Backend erweiterst, nimm dir 20 Minuten, um zu kartieren, was beim Re-Export neu generiert wird und was dir wirklich gehört. Diese Karte sorgt dafür, dass Upgrades langweilig bleiben.
Generierter Code verrät sich oft selbst: Header-Kommentare wie "Code generated" oder "DO NOT EDIT", konsistente Namensmuster und eine sehr gleichförmige Struktur mit wenigen menschlichen Kommentaren.
Eine praktische Klassifikation ist, alles in drei Buckets zu sortieren:
- Generiert (read-only): Dateien mit klaren Generator-Markern, wiederkehrenden Mustern oder Ordnern, die wie ein Framework-Skelett aussehen.
- Dein Besitz: Pakete, die du erstellt hast, Wrapper und Konfiguration, die du kontrollierst.
- Geteilte Nähte: Wiring-Punkte, die zur Registrierung gedacht sind (Routen, Middleware, Hooks), wo kleine Änderungen nötig sein können, aber minimal bleiben sollten.
Behandle den ersten Bucket als schreibgeschützt, auch wenn du ihn technisch ändern kannst. Wenn du ihn änderst, geh davon aus, dass der Generator ihn später überschreibt oder du für immer Merge-Aufwand tragen wirst.
Mach die Grenze für das Team deutlich, indem du eine kurze Notiz ins Repo schreibst (z. B. eine README im Root). Halte es knapp:
"Generator-owned files: anything with a DO NOT EDIT header and folders X/Y. Our code lives under internal/custom (or similar). Only touch wiring points A/B, and keep changes there small. Any wiring edit needs a comment explaining why it can't live in our own package."
Diese eine Notiz verhindert, dass Quickfixes zu dauerhaftem Upgrade-Schmerz werden.
Wo du benutzerlichen Code ablegen solltest, damit Upgrades einfach bleiben
Die sicherste Regel ist simpel: Behandle exportierten Code als schreibgeschützt und lege deine Änderungen in einem klar zugewiesenen Custom-Bereich ab. Wenn du später re-exportierst (zum Beispiel aus AppMaster), willst du, dass das Merge größtenteils "generated code ersetzen, custom code behalten" ist.
Erstelle ein separates Paket für deine Ergänzungen. Es kann im Repo liegen, sollte aber nicht mit generierten Paketen vermischt werden. Generierter Code betreibt den Kern der App; dein Paket fügt Middleware, Routen und Helfer hinzu.
Ein praktisches Layout:
internal/custom/für Middleware, Handler und kleine Helferinternal/custom/routes.goum benutzerdefinierte Routen an einer Stelle zu registriereninternal/custom/middleware/für Request-/Response-Logikinternal/custom/README.mdmit ein paar Regeln für künftige Änderungen
Vermeide es, die Server-Wiring an fünf verschiedenen Stellen zu bearbeiten. Ziel ist ein dünner "Hook Point", an dem du Middleware anhängst und zusätzliche Routen registrierst. Falls der generierte Server einen Router oder Handler-Stack freigibt, stecke dort dein Plugin. Falls nicht, füge eine einzelne Integrationsdatei in der Nähe des Entrypoints hinzu, die so etwas aufruft wie custom.Register(router).
Schreibe Custom-Code so, als würdest du ihn in einen nagelneuen Export morgen hineinlegen. Halte Abhängigkeiten minimal, vermeide das Kopieren generierter Typen, wenn möglich, und nutze kleine Adapter.
Schritt für Schritt: sichere Middleware hinzufügen
Das Ziel ist, Logik in dein eigenes Paket zu legen und generierten Code an nur einer Stelle zum Verdrahten zu berühren.
Erstens: halte Middleware eng gefasst: Request-Logging, eine einfache Auth-Prüfung, ein Rate-Limit oder eine Request-ID. Wenn sie drei Aufgaben übernimmt, wirst du später mehr Dateien ändern müssen.
Erstelle ein kleines Paket (z. B. internal/custom/middleware), das nicht dein ganzes App-Wissen benötigt. Halte die öffentliche Oberfläche klein: eine Konstruktorfunktion, die eine Standard-Go-Handler-Wrapping-Funktion zurückgibt.
package middleware
import "net/http"
func RequestID(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Add header, log, or attach to context here.
next.ServeHTTP(w, r)
})
}
Wähle nun einen Integrationspunkt: die Stelle, an der der Router oder HTTP-Server erstellt wird. Registriere deine Middleware dort einmal und vermeide es, Änderungen über einzelne Routen zu verstreuen.
Halte die Verifizierungs-Schleife eng:
- Füge einen fokussierten Test mit
httptesthinzu, der ein Ergebnis prüft (Statuscode oder Header). - Mache eine manuelle Anfrage und bestätige das Verhalten.
- Prüfe, dass die Middleware sich bei Fehlern vernünftig verhält.
- Füge einen kurzen Kommentar in der Nähe der Registrierungszeile ein, der erklärt, warum sie existiert.
Kleines Diff, ein Wiring-Punkt, einfache Re-Exports.
Schritt für Schritt: neuen Endpunkt hinzufügen, ohne alles zu forken
Behandle generierten Code als schreibgeschützt und füge deinen Endpunkt in einem kleinen Custom-Paket hinzu, das die App importiert. Das hält Upgrades überschaubar.
Schreibe zuerst den Vertrag auf: Was akzeptiert der Endpunkt (Query-Parameter, JSON-Body, Header)? Was gibt er zurück (JSON-Form)? Wähle Statuscodes im Voraus, damit du nicht bei "was auch immer gerade funktionierte" landest.
Erstelle einen Handler in deinem Custom-Paket. Halte ihn langweilig: Input lesen, validieren, existierende Services oder DB-Helfer aufrufen, Antwort schreiben.
Registriere die Route am selben Integrationspunkt, den du für Middleware verwendest, nicht in generierten Handler-Dateien. Suche dort, wo der Router beim Startup zusammengesetzt wird, und mounte deine Custom-Routen. Falls das generierte Projekt Hooks oder Custom-Registration unterstützt, nutze diese.
Eine kurze Checkliste hält das Verhalten konsistent:
- Inputs früh validieren (erforderliche Felder, Formate, min/max).
- Überall eine einheitliche Fehlerform zurückgeben (message, code, details).
- Context-Timeouts verwenden, wo Arbeit hängen bleiben kann (DB, Netzwerk).
- Unerwartete Fehler einmalig loggen und dann ein sauberes 500 zurückgeben.
- Einen kleinen Test hinzufügen, der die neue Route trifft und Status sowie JSON prüft.
Prüfe außerdem, dass der Router deinen Endpunkt genau einmal registriert. Doppelte Registrierung ist eine häufige Post-Merge-Falle.
Integrationsmuster, die Änderungen begrenzen
Behandle das generierte Backend wie eine Dependency. Bevorzuge Komposition: wire Funktionen um die generierte App herum, statt ihre Kernlogik zu bearbeiten.
Konfiguration und Komposition bevorzugen
Prüfe zuerst, ob sich das Verhalten über Konfiguration, Hooks oder Standard-Komposition hinzufügen lässt. Middleware ist ein gutes Beispiel: füge sie am Rand (Router/HTTP-Stack) hinzu, so dass sie entfernt oder neu sortiert werden kann, ohne die Business-Logik zu berühren.
Wenn du eine neue Verhaltensweise brauchst (Rate-Limiting, Audit-Logging, Request-IDs), halte sie in deinem eigenen Paket und registriere sie aus einer einzigen Integrationsdatei. In Reviews sollte einfach zu erklären sein: "ein neues Paket, ein Registrierungs-Punkt".
Adapter nutzen, damit generierte Typen nicht durchdringen
Generierte Modelle und DTOs ändern sich oft bei Re-Exports. Um Upgrade-Schmerzen zu reduzieren, übersetze an der Grenze:
- Konvertiere generierte Request-Typen in deine eigenen internen Strukturen.
- Führe Domänenlogik nur mit deinen Strukturen aus.
- Konvertiere Ergebnisse zurück in generierte Response-Typen.
So zeigt der Compiler nach einer Änderung nur noch eine Stelle, die du anpassen musst.
Wenn du wirklich generierten Code anfassen musst, isoliere es in einer einzigen Wiring-Datei. Vermeide Änderungen in vielen generierten Handlern.
// internal/integrations/http.go
func RegisterCustom(r *mux.Router) {
r.Use(RequestIDMiddleware)
r.Use(AuditLogMiddleware)
}
Eine praktische Regel: Wenn du die Änderung nicht in 2–3 Sätzen beschreiben kannst, ist sie wahrscheinlich zu verstrickt.
Wie du Diffs über die Zeit überschaubar hältst
Das Ziel ist, dass ein Re-Export nicht in eine Woche voller Konflikte ausartet. Halte Änderungen klein, leicht auffindbar und gut erklärbar.
Nutze Git von Beginn an und trenne generierte Updates von deiner Custom-Arbeit. Wenn du sie mischst, findest du später nicht mehr, was einen Fehler verursacht hat.
Eine lesbare Commit-Routine:
- Ein Ziel pro Commit ("Request ID Middleware hinzufügen", nicht "verschiedene Fixes").
- Formatierungsänderungen nicht mit Logikänderungen mischen.
- Nach jedem Re-Export zuerst den generierten Update-Commit, dann deine Custom-Anpassungen committen.
- Commit-Nachrichten, die das Paket oder die Datei erwähnen, die du geändert hast.
Führe ein einfaches CHANGELOG_CUSTOM.md (oder ähnlich), das jede Anpassung, warum sie existiert und wo sie liegt, auflistet. Das ist besonders nützlich bei AppMaster-Exports, weil die Plattform den Code vollständig regenerieren kann und du schnell sehen willst, was neu angewendet oder verifiziert werden muss.
Reduziere Diff-Rauschen mit konsistenten Format- und Lint-Regeln. Führe gofmt bei jedem Commit aus und dieselben Checks in CI. Wenn generierter Code einen bestimmten Stil nutzt, „verschönere“ ihn nicht von Hand, es sei denn, du bist bereit, diese Bereinigung nach jedem Re-Export zu wiederholen.
Wenn dein Team wiederholt dieselben manuellen Änderungen nach jedem Export macht, ziehe einen Patch-Workflow in Betracht: exportieren, Patches anwenden (oder ein Script), Tests ausführen, ausliefern.
Upgrades planen: Re-Export, Mergen und Validieren
Upgrades sind am einfachsten, wenn du das Backend so behandelst, dass es regeneriert werden kann, statt es ewig manuell zu pflegen. Das Ziel bleibt: Sauberen Code re-exportieren und dann dein Custom-Verhalten über dieselben Integrationspunkte wieder anwenden.
Wähle ein Upgrade-Rhythmus, der zu deiner Risikobereitschaft und der Häufigkeit von Änderungen passt:
- Pro Plattform-Release, wenn du schnelle Sicherheitsfixes oder neue Features brauchst
- Vierteljährlich, wenn die App stabil ist und Änderungen klein sind
- Nur bei Bedarf, wenn das Backend selten geändert wird und das Team klein ist
Wenn ein Upgrade ansteht, mache einen Dry-Run-Re-Export in einem separaten Branch. Baue und starte die neu exportierte Version allein zuerst, damit du weißt, was sich geändert hat, bevor deine Custom-Schicht ins Spiel kommt.
Dann reapplye Customizations über deine geplanten Nähte (Middleware-Registrierung, custom router group, dein Custom-Paket). Vermeide chirurgische Änderungen in generierten Dateien. Wenn sich etwas nicht durch einen Integrationspunkt ausdrücken lässt, ist das ein Signal, einmalig eine neue Naht hinzuzufügen und sie danach immer zu verwenden.
Validiere mit einer kurzen Regressions-Checkliste, die auf Verhalten fokussiert ist:
- Auth-Flow funktioniert (Login, Token-Refresh, Logout)
- 3–5 wichtige API-Endpunkte liefern dieselben Statuscodes und Shapes
- Ein unhappy path pro Endpunkt (schlechter Input, fehlende Auth)
- Hintergrundjobs oder geplante Tasks laufen weiterhin
- Health-/Readiness-Endpunkt liefert OK in deiner Deployment-Konfiguration
Wenn du Audit-Logging-Middleware hinzugefügt hast, vergewissere dich nach jedem Re-Export und Merge, dass Logs für eine Schreiboperation weiterhin user ID und Routenname enthalten.
Häufige Fehler, die Upgrades schmerzhaft machen
Der schnellste Weg, dein nächstes Re-Export zu ruinieren, ist, generierte Dateien „nur dieses eine Mal" zu editieren. Es fühlt sich harmlos an, wenn du einen kleinen Bug fixst oder einen Header-Check hinzufügst, aber Monate später weißt du nicht mehr, was sich geändert hat, warum oder ob der Generator jetzt denselben Output erzeugt.
Eine andere Falle ist, Custom-Code überall zu verstreuen: ein Helfer in Paket A, ein Auth-Check in Paket B, ein Middleware-Tweak nahe beim Routing und ein One-Off-Handler in einem zufälligen Ordner. Niemand besitzt das Ganze, und jeder Merge wird zur Schnitzeljagd. Halte Änderungen an wenigen offensichtlichen Orten.
Enge Kopplung an generierte Interna
Upgrades werden hart, wenn dein Custom-Code von generierten internen Structs, privaten Feldern oder Paket-Layout-Details abhängt. Schon eine kleine Refaktorierung im generierten Code kann deinen Build brechen.
Sichere Grenzen:
- Nutze DTOs, die du kontrollierst, für Custom-Endpunkte.
- Interagiere mit generierten Schichten über exportierte Interfaces oder Funktionen, nicht über interne Typen.
- Triff Middleware-Entscheidungen möglichst auf Basis von HTTP-Primitiven (Header, Methode, Pfad).
Tests dort nicht skippen, wo sie am meisten gebraucht werden
Middleware- und Routing-Bugs kosten Zeit, weil Fehler oft wie zufällige 401s oder „Endpoint not found" aussehen. Ein paar fokussierte Tests sparen Stunden.
Ein realistisches Beispiel: Du fügst Audit-Middleware hinzu, die den Request-Body zum Loggen liest, und plötzlich erhalten einige Endpunkte einen leeren Body. Ein kleiner Test, der einen POST durch den Router schickt und sowohl das Audit-Nebenprodukt als auch das Handler-Verhalten prüft, fängt diese Regression und gibt Sicherheit nach einem Re-Export.
Kurze Pre-Release-Checkliste
Bevor du benutzerdefinierte Änderungen auslieferst, mache einen kurzen Durchgang, der dich beim nächsten Re-Export schützt. Du solltest genau wissen, was neu angewendet werden muss, wo es liegt und wie man es verifiziert.
- Halte allen Custom-Code in einem klar benannten Paket oder Ordner (z. B.
internal/custom/). - Begrenze die Touchpoints mit generiertem Wiring auf ein oder zwei Dateien. Behandle sie wie Brücken: Routen einmal registrieren, Middleware einmal registrieren.
- Dokumentiere Middleware-Reihenfolge und den Grund dafür ("Auth vor Rate-Limiting" und warum).
- Sorge dafür, dass jeder Custom-Endpunkt mindestens einen Test hat, der seine Funktion belegt.
- Schreibe eine wiederholbare Upgrade-Routine: re-export, custom layer wieder anwenden, Tests ausführen, deployen.
Wenn du nur eine Sache tust: Schreibe die Upgrade-Notiz. Sie verwandelt „ich glaube, es ist in Ordnung" in „wir können beweisen, dass es noch funktioniert".
Beispiel: Audit-Logging und ein Health-Endpunkt hinzufügen
Angenommen, du hast ein Go-Backend exportiert (zum Beispiel aus AppMaster) und willst zwei Ergänzungen: eine Request-ID plus Audit-Logging für Admin-Aktionen und einen einfachen /health-Endpunkt fürs Monitoring. Ziel ist, die Änderungen leicht nach einem Re-Export wieder anwenden zu können.
Für Audit-Logging lege den Code an einem klaren Ort ab, z. B. internal/custom/middleware/. Erstelle Middleware, die (1) X-Request-Id liest oder eine generiert, (2) sie im Request-Context speichert und (3) eine kurze Audit-Zeile für Admin-Routen loggt (Methode, Pfad, User-ID falls verfügbar, Ergebnis). Halte dich an eine Zeile pro Request und vermeide das Dumpen großer Payloads.
Wired die Middleware am Rand, nahe dort, wo Routen registriert werden. Wenn der generierte Router eine einzige Setup-Datei hat, füge dort einen kleinen Hook ein, der deine Middleware importiert und nur auf die Admin-Gruppe anwendet.
Für /health füge einen winzigen Handler in internal/custom/handlers/health.go hinzu. Gib 200 OK mit einem kurzen Body wie ok zurück. Füge keine Auth hinzu, außer deine Monitore benötigen sie — dokumentiere es in dem Fall.
Strukturiere Commits so:
- Commit 1:
internal/custom/middleware/audit.gound Tests hinzufügen - Commit 2: Middleware in Admin-Routen einbinden (kleinstmöglicher Diff)
- Commit 3:
internal/custom/handlers/health.gohinzufügen und/healthregistrieren
Nach einem Upgrade oder Re-Export verifiziere die Basics: Admin-Routen erfordern weiterhin Auth, Request-IDs erscheinen in Admin-Logs und /health antwortet schnell; die Middleware fügt bei leichtem Load keine spürbare Latenz hinzu.
Nächste Schritte: Einen anpassbaren Workflow etablieren
Behandle jeden Export wie einen wiederholbaren Build. Dein Custom-Code sollte sich anfühlen wie eine Add-on-Schicht, nicht wie ein Rewrite.
Entscheide beim nächsten Mal klar, was in Code und was ins No-Code-Modell gehört. Geschäftsregeln, Datenformen und standardmäßige CRUD-Logik gehören normalerweise ins Modell. One-Off-Integrationen und unternehmensspezifische Middleware gehören in den Custom-Go-Code.
Wenn du AppMaster (appmaster.io) verwendest, gestalte deine Custom-Arbeit als saubere Erweiterungsschicht um das generierte Go-Backend: halte Middleware, Routen und Helfer in einigen wenigen Ordnern, die du über Re-Exports hinweg tragen kannst, und lasse generator-eigene Dateien unangetastet.
Eine praktische Abschlussprüfung: Kann ein Kollege re-exportieren, deine Schritte anwenden und dasselbe Ergebnis in unter einer Stunde erzielen? Wenn ja, ist dein Workflow wartbar.
FAQ
Ändere keine generator-verwalteten Dateien. Lege deine Änderungen in einem klar zugewiesenen Paket ab (zum Beispiel internal/custom/) und verbinde sie über einen kleinen Integrationspunkt in der Nähe des Server-Startups. So ersetzt ein Re-Export größtenteils den generierten Code, während deine benutzerdefinierte Schicht erhalten bleibt.
Geh davon aus, dass alles mit Kommentaren wie „Code generated“ oder „DO NOT EDIT“ überschrieben wird. Achte außerdem auf sehr uniforme Ordnerstrukturen, wiederkehrende Namensmuster und wenige menschliche Kommentare — das sind typische Anzeichen für generierten Code. Die sicherste Regel lautet: Behandle solche Teile als schreibgeschützt, auch wenn sie nach einer Änderung noch kompilieren.
Behalte eine einzelne „Hook“-Datei, die dein Custom-Paket importiert und alles registriert: Middleware, zusätzliche Routen und kleine Wiring-Schritte. Wenn du fünf Routing-Dateien oder mehrere generierte Handler anfasst, driftest du in einen Fork, der schwer zu upgraden ist.
Schreibe die Middleware in deinem eigenen Paket und halte sie eng fokussiert — Request IDs, Audit-Logging, Rate-Limits oder spezielle Header. Registriere sie einmal beim Erstellen des Routers oder des HTTP-Stacks, nicht pro Route innerhalb generierter Handler. Ein kurzer httptest, der einen erwarteten Header oder Statuscode prüft, reicht oft, um Regressionen nach einem Re-Export zu entdecken.
Definiere zuerst das Vertragswerk (Input, Output, Statuscodes), implementiere den Handler in deinem Custom-Paket und registriere die Route am selben Integrationspunkt wie die Middleware. Halte den Handler schlicht: Input validieren, vorhandene Services nutzen, eine konsistente Fehlerform zurückgeben und vermeiden, generierten Handler-Code zu kopieren. So bleibt die Änderung portabel für einen frischen Export.
Der Generator kann die Reihenfolge der Registrierung, Gruppierung oder Middleware-Ketten ändern. Schütze dich, indem du eine stabile Registrierungsnaht verwendest und die Middleware-Reihenfolge direkt neben der Registrierungszeile dokumentierst. Wenn die Reihenfolge wichtig ist (z. B. Auth vor Audit), kodifiziere sie bewusst und überprüfe das Verhalten mit einem kleinen Test.
Wenn du eine Regel an zwei Stellen implementierst, driften die Implementierungen auseinander und führen zu unerwartetem Verhalten. Lege Geschäftsregeln, die Nicht-Entwickler anpassen sollen (Felder, Validierung, Workflows, Berechtigungen), ins No-Code-Modell. Infrastrukturthemen (Logging, Auth-Integration, Rate-Limits, Header) gehören in deine benutzerdefinierte Go-Schicht. Die Trennung sollte für jeden, der das Repo liest, offensichtlich sein.
Isoliere diesen Wandel an der Grenze: konvertiere generierte Anfrage-Typen in eigene interne Strukturen, führe die Domänenlogik nur mit diesen Strukturen aus und konvertiere die Ergebnisse am Rand zurück. So zeigt dir der Compiler nach einem Export nur noch einen Ort, den du anpassen musst.
Trenne generierte Updates klar von deiner eigenen Arbeit in Git, damit du sehen kannst, was sich geändert hat und warum. Ein praktikabler Ablauf ist: zuerst den Re-Export committen, dann die minimale Wiring und die Anpassungen der Custom-Schicht committen. Ein kurzes Custom-CHANGELOG, das sagt, was du hinzugefügt hast und wo es liegt, macht das nächste Upgrade deutlich schneller.
Führe einen Dry-Run-Re-Export in einem separaten Branch durch, baue ihn und mache einen kurzen Regressions-Check, bevor du deine Custom-Schicht wieder einspielst. Reappliziere Anpassungen über dieselben Nähte jedes Mal, führe dann Tests für einige Schlüsselendpunkte und einen unhappy path pro Endpunkt aus. Wenn sich etwas nicht über eine bestehende Naht ausdrücken lässt, füge einmalig eine neue Naht hinzu und verwende sie künftig.


