Lovable: Warum aus KI generierte Apps einen Code Audit brauchen

    # Es sieht aus, als würde es funktionieren

    Zwei reale Fälle aus vibecodeten Apps — und warum ein Code Audit kein Misstrauen gegenüber Lovable ist, sondern der Schritt, der aus einem Prototyp ein Produkt macht.

    Ich baue selbst Frontends mit Lovable. Für einen klickbaren Prototyp, eine Landingpage oder einen ersten Durchstich ist das großartig: In Stunden steht etwas, das man anfassen, zeigen und testen kann. Das ist kein Marketingversprechen, das ist Alltag.

    Und genau hier beginnt das Missverständnis. „Sieht funktionierend aus" und „ist tragfähig gebaut" sind zwei verschiedene Aussagen. Der Unterschied liegt fast immer in der Architektur — und Architektur sieht man der laufenden Demo nicht an.

    Eine Demo läuft auf dem Happy Path: wenige Datensätze, ein freundlicher Nutzer, kein Lastfall, kein Angreifer. Was unter Last, mit echten Daten oder unter einer Sicherheitsbetrachtung passiert, klickt niemand durch. Deshalb bleiben die teuren Fehler unsichtbar — bis sie es nicht mehr sind.

    Zwei Fälle aus der Praxis.

    ---

    ## Fall 1: Die Jobbörse, die im Browser filtert

    Eine Jobbörse, sauber aussehend, Filter nach Stadt, Gehalt und Branche. Funktioniert tadellos in der Vorführung. Im Code zeigt sich: Die Filterung passiert im Client.

    ```ts

    // Alle Stellen laden, dann im Browser filtern

    const { data: jobs } = await supabase.from('jobs').select('*')

    const sichtbar = jobs.filter(

    (j) => j.stadt === stadt && j.gehalt >= minGehalt

    )

    ```

    Das ist der schnellste Weg zu einer funktionierenden Demo — und in Produktion gleich doppelt ein Problem.

    Sicherheit. Der Browser bekommt alle Datensätze, bevor gefiltert wird. Wer die Entwicklertools öffnet, sieht jede Stelle im Netzwerk-Response — auch Entwürfe, deaktivierte Inserate oder Einträge, die eigentlich gar nicht sichtbar sein sollten. Ein Filter im Client ist nie eine Sicherheitsgrenze. Er ist Kosmetik.

    Skalierung. Bei 30 Stellen merkt das niemand. Bei 30.000 lädt jeder Seitenaufruf den kompletten Datenbestand auf das Endgerät. Langsam, teuer, auf dem Smartphone unbenutzbar.

    Richtig gehört die Filterung dorthin, wo auch die Datenhoheit liegt:

    ```ts

    // In der Query filtern — der Server gibt nur zurück, was erlaubt und nötig ist

    const { data: jobs } = await supabase

    .from('jobs')

    .select('*')

    .eq('stadt', stadt)

    .gte('gehalt', minGehalt)

    ```

    Dazu Row Level Security, Pagination und Indizes. Nichts davon ist exotisch — aber nichts davon entsteht von allein, wenn das Ziel „läuft in der Demo" heißt.

    ---

    ## Fall 2: Das ERP, das angeblich Deep Learning macht

    Ein Fachexperte spezifiziert für ein ERP-Werkzeug eine Funktion, die per Deep Learning gelöst werden soll — sagen wir, eine Bedarfsprognose. Das Ergebnis sieht stimmig aus: Es kommen plausible Zahlen heraus, die Oberfläche spricht von „KI-gestützter Prognose". Beim Blick in den Code steht da aber kein Modell. Da stehen if-then-else-Regeln.

    ```ts

    // Verkauft als „KI-gestützte Bedarfsprognose"

    function prognose(historie, monat, wochentag) {

    if (monat === 12) return basis * 1.5 // Weihnachtsgeschäft

    if (wochentag === 6) return basis * 0.7 // Samstag

    return basis

    }

    ```

    Kein Training, kein Modell, kein Lernen aus Daten. Es funktioniert auf genau den Beispielen, mit denen es gebaut wurde — und wird überall sonst brüchig.

    Der Grund ist strukturell: Das Werkzeug bleibt bei seinem Stack. Lovable generiert hervorragend TypeScript, React und Supabase. Eine echte ML-Pipeline — Datenaufbereitung, Training, Modell, Inferenz — liegt außerhalb dessen, was es ausliefern kann. Statt zu sagen „das geht so nicht", produziert es das Nächstbeste, das im eigenen Stack ausdrückbar ist: hartkodierte Heuristik im Mantel der KI.

    > Ein LLM-Codegenerator sagt selten „kann ich nicht". Er liefert das plausibel aussehende Surrogat — und das ist der gefährlichere Fehler, weil ihn niemand bemerkt.

    Die Stakeholder treffen Entscheidungen in der Annahme, ein lernendes System zu haben. Tatsächlich haben sie ein paar Regeln, die niemand mehr anfasst.

    ---

    ## Das gemeinsame Muster

    Beide Fälle sehen aus wie die Lösung. Beide sind es nicht. Und in beiden ist die Lücke ohne Fachwissen unsichtbar:

    - Das Werkzeug optimiert auf das, was in der Demo überzeugt — nicht auf das, was unter Last, mit echten Daten oder unter Sicherheitsbetrachtung trägt.

    - Das Werkzeug optimiert auf das, was in seinem Stack ausdrückbar ist — und ersetzt echte Anforderungen still durch das nächstgelegene Surrogat.

    Das ist kein Argument gegen Lovable. Es ist eine Eigenschaft der Werkzeugklasse. Wer das weiß, nutzt sie richtig: für Geschwindigkeit am Anfang — und mit einem prüfenden Blick, bevor es ernst wird.

    ## Was ein Code Audit tatsächlich prüft

    Kein Misstrauen, sondern ein paar konkrete Fragen:

    - Wo wird gefiltert und autorisiert? Im Client oder auf dem Server? Greift Row Level Security wirklich, oder ist sie nur konfiguriert?

    - Was steht hinter den Versprechen? „KI", „Echtzeit", „Suche" — gibt es die Substanz dahinter, oder ist es ein Platzhalter, der in der Demo gut aussieht?

    - Was passiert bei 100x Daten? Skaliert die Architektur, oder bricht sie am ersten echten Lastfall?

    - Wo liegen die Daten, und wer sieht was? Verlässt etwas das Backend, das es nicht verlassen dürfte?

    Diese Fragen kosten ein paar Stunden. Sie nicht zu stellen, kostet eine Migration, einen Sicherheitsvorfall oder ein Produkt, das auf einer Lüge gebaut ist.

    ---

    Vibe Coding ist ein hervorragender Startpunkt. Es ist nur kein Endpunkt. Der Schritt vom „funktioniert in der Demo" zum „trägt in Produktion" ist genau der Schritt, den ein Audit sichtbar macht — bevor ihn die Realität für einen erledigt.

    Wir verwenden nur essenzielle Cookies, um diese Website zu betreiben. Mehr erfahren