Fallstudie · Produkt & Engineering
Alcorte Alemán
Eine 50 Jahre alte Metzgerei über WhatsApp betreiben
Alleiniger Architekt und Entwickler · Produktdefinition, Systemdesign, Implementierung, Einarbeitung des Betreibers
Phase 0 abgeschlossen, Phase A1 in Arbeit
Ein KI-gestütztes Bestellmanagementsystem, entworfen um eine einzige Randbedingung: Der Betreiber wird nie ein Dashboard öffnen.
Auf einen Blick
- Kunde
- Alcorte Alemán — Familienmetzgerei, Mexiko-Stadt, über 50 Jahre im Betrieb
- Rolle
- Alleiniger Architekt und Entwickler — Produktdefinition, Systemdesign, Implementierung, Einarbeitung des Betreibers
- Größenordnung
- über 120 Produkte im Katalog, über 1000 Kunden
- Problem
- Bestellannahme und Tagesgeschäft digitalisieren, ohne von einem lebenslangen Betreiber zu verlangen, seine Arbeitsweise zu ändern
- Ansatz
- WhatsApp als gesamte Oberfläche — für Kunden und für den Inhaber
- Stack
- WhatsApp Business API → Meta webhooks → Vercel (Next.js) → Anthropic Claude → Supabase (Postgres + RLS)
- Status
- Phase 0 abgeschlossen, Phase A1 in Arbeit. Durchgängige Pipeline produktiv im Einsatz; Werkzeugsatz für den Betreiber gegen echte Daten validiert
- Repository
- Privat, 2FA erzwungen. Produktivbetrieb auf Vercel
Das Problem
Software für kleine Unternehmen scheitert meist auf dieselbe Weise: Sie setzt voraus, dass der Inhaber eine neue Oberfläche erlernt. Der Inhaber führt diese Metzgerei seit über fünfzig Jahren. Er kennt seine Produkte, seine Margen, seine Stammkunden und seine Lieferanten besser, als es ein System je könnte. Was ihm fehlt, ist eine Stunde am Tag, um ein Verwaltungsmenü zu erlernen — und rund eine Stunde täglich ist die ehrliche Obergrenze dessen, was er überhaupt für die Interaktion mit einem System aufbringen kann.
Das Geschäft nimmt täglich eine überschaubare Zahl an Bestellungen an, überwiegend von Privatkunden, gelegentlich von Restaurants. Bestellungen kommen per Telefon und per WhatsApp. Nichts wird protokolliert. Die Preise stehen im Kopf des Inhabers und auf handschriftlichen Zetteln. Lieferzeiten werden nach Gefühl geschätzt. Das funktioniert — bis es nicht mehr skaliert oder bis die eine Person, die das Wissen trägt, ausfällt.
Die naheliegende Lösung ist ein Web-Dashboard mit Bestellliste und Produktkatalog. Die naheliegende Lösung wäre binnen einer Woche liegen geblieben.
Der Perspektivwechsel
Ich habe die Anforderung umgedreht. Statt “ein Verwaltungsmenü bauen und dem Inhaber dessen Bedienung beibringen” lautete der Auftrag:
Wenn der Inhaber jemals einen Browser öffnen muss, um sein Geschäft zu führen, ist das Projekt gescheitert.
WhatsApp ist kein Kanal, der dem Produkt angeflanscht wurde. Es ist die Produktoberfläche — für Kunden, die bestellen, und für den Inhaber, der das System konfiguriert. Einen Preis ändern, ein Stück Fleisch als ausverkauft melden und die Tageszusammenfassung abrufen geschieht alles in derselben Chat-App, die er ohnehin den ganzen Tag geöffnet hat.
Diese eine Randbedingung bestimmte jede der folgenden Architekturentscheidungen.
Entwurfsprinzipien
Sie standen fest, bevor eine Zeile Code geschrieben war, und jede spätere Entscheidung wurde an ihnen geprüft.
Konfiguration WhatsApp-first
Jede Systemeinstellung muss vom Betreiber per Chatnachricht änderbar sein. Grundlage dafür ist eine vendor_settings-Tabelle statt Umgebungsvariablen oder fest verdrahteter Konfiguration — wenn ein Wert sich ändern kann, muss er sich vom Telefon aus ändern lassen.
Operative Sprache, niemals Strategiejargon
Das System spricht mit dem Inhaber so, wie es ein guter Mitarbeiter täte: konkret und im Rahmen des Tagesgeschäfts. Niemals “Conversion Rate”, “ROI” oder “NPS”. “Siebzehn Bestellungen heute, drei noch auszuliefern” ist ein Satz, auf den er handeln kann. “Erfüllungsquote 82 %” ist es nicht.
Niemals Geschäftsfakten erfinden
Der Bot darf keinen Preis, kein Liefergebiet und kein Detail der Geschäftshistorie nennen, das er nicht aus der Datenbank belegen kann. Das ist als harte Vorgabe im System-Prompt verankert, nicht als weiche Empfehlung — ein plausibel klingender falscher Preis ist schlechter als keine Antwort, denn er wird zu einem Versprechen, das das Geschäft einlösen muss.
Automatisierung erst nach manuellem Betrieb
Nichts läuft unbeaufsichtigt, bevor die Daten es rechtfertigen. Der Automatikmodus wird erst freigeschaltet, wenn sich ausreichend belastbare Signale angesammelt haben; jeder automatisierbare Schritt geht zuerst als Schaltfläche in Betrieb, die jemand drückt.
Zubereitung mit der Ankunft synchronisieren
Zu früh zubereitetes Fleisch verliert an Qualität; zu spät zubereitetes hält den Fahrer auf. Die Zeitberechnungen sind realistisch statt optimistisch und werden mit proaktiver Kommunikation verbunden, wenn sie sich verschieben.
Passives Lernen aus Eskalationen
Jedes Mal, wenn das System ein Gespräch an einen Menschen übergibt, wird dieser Austausch zu abrufbarem Wissen (RAG) statt zu einem verworfenen Fehlschlag. Das System verbessert sich als Nebenprodukt seiner Nutzung, ohne dass jemand einen Annotationsprozess pflegen müsste.
Die Buchhaltungsarchitektur früh anlegen, spät umsetzen
Die mexikanische Steuerrechnung (CFDI) ist ein theoretisch gelöstes, praktisch mühsames Problem, und die Entscheidung zwischen Eigenausstellung und externem Steuerberater liegt nicht bei mir. Das Schema sieht sie daher vor; die Funktion wartet.
Architektur
get_vendor_id()-Helper auf vendor_id zu, sodass das Schema von Tag eins an mandantenfähig ist. Für diese Fallstudie nachgebaut.Warum dieser Zuschnitt
Der Webhook-Handler ist zustandslos und läuft auf Vercel, sodass ein Ein-Personen-Team keinen Server am Leben halten muss. Der Zustand liegt in Supabase mit Row-Level Security auf Basis von vendor_id — die Architektur ist von Tag eins an mandantenfähig, obwohl sie nur ein Geschäft bedient, denn Mandantenfähigkeit nachzurüsten ist eine Neuentwicklung, sie vorwegzunehmen eine WHERE-Klausel.
Die agentische Schicht
Statt eines starren Intent-Klassifikators läuft die Nachrichtenverarbeitung als vollständige agentische Schleife: Das Modell erhält die Nachricht samt UserContext und entscheidet, welche Werkzeuge es aufruft. Das ist entscheidend, denn echte Nachrichten eines Metzgers sind keine wohlgeformten Befehle. “El sirloin súbelo a 320” und “ya no hay arrachera” sind beides Konfigurationsänderungen in gesprochener Form.
Identität und Berechtigungen
Das System unterscheidet Kunden von Betreibern, indem es die eingehende Rufnummer gegen eine operators-Tabelle abgleicht und daraus einen UserContext erzeugt, der die gesamte Anfrage begleitet. Sechs Werkzeuge stehen bereit, getrennt nach Berechtigungsstufe:
get_product
search_products
list_products_summary
update_product_price
set_product_availability
get_today_summary
Die Rechteprüfung folgt dem Prinzip der gestaffelten Verteidigung: Der dem Modell angebotene Werkzeugsatz wird nach Kontext gefiltert, und jedes privilegierte Werkzeug prüft den Aufrufer vor der Ausführung erneut. Sich allein auf den Prompt zu verlassen, damit ein Kunde keine Preise ändert, ist kein Sicherheitsmodell — es ist eine Hoffnung. Eine Nachricht von einer unbekannten Nummer erreicht keinen Schreibpfad, selbst wenn das Modell dazu überredet wird.
Jede Preisänderung schreibt nach price_history mit changed_via: "whatsapp_tool", sodass eine per Chat ausgelöste Änderung ebenso nachvollziehbar ist wie eine über jede andere Oberfläche.
Die Eskalationskette
Die operative Realität ist, dass der Bot nicht alles bewältigen wird, und der Fehlerfall eines KI-Assistenten ohne Ausweg ist ein frustrierter Kunde.
- Inhaber
- →
- Schichtleitung
- →
- Weitere Mitarbeitende
- →
- dev_backup · nicht entfernbar
Die Eskalation verläuft Inhaber → Schichtleitung → weitere Mitarbeitende → ich als nicht entfernbares dev_backup. Die Kette ist vom Betreiber konfigurierbar, mit einer Ausnahme: Das letzte Glied lässt sich nicht entfernen.
Ein System, das sich in einen Zustand konfigurieren lässt, in dem niemand mehr zuhört, ist ein System, das irgendwann genau so konfiguriert sein wird.
Was ausgeliefert wurde
Phase 0 — Grundlagen (abgeschlossen)
vendor_settings-Tabelle mit zehn Standardwerten, ausgeliefert als Migration001_vendor_settings.sql, die dem bestehenden RLS-Muster folgt, statt ein zweites einzuführen.- Anbindung der Meta WhatsApp Business API mit einem dauerhaften System-User-Token, beschränkt auf
whatsapp_business_messagingundwhatsapp_business_management. - Durchgängige Pipeline im Produktivbetrieb bestätigt: WhatsApp → Meta → Vercel → Claude → WhatsApp.
Phase A1 — Werkzeugsatz für den Betreiber (in Arbeit)
- Sechs agentische Werkzeuge mit vollständiger Schleife, Identitätsauflösung über
UserContextund der oben beschriebenen Rechteprüfung. - Drei Validierungstests, alle bestanden gegen echte Infrastruktur statt gegen Mocks:
- Betreibererkennung über Rufnummernabgleich
- Live-Abfrage eines Produktpreises gegen Supabase
- Preisänderung mit bestätigtem Audit-Trail in
price_history
Artefakt zur Einarbeitung des Betreibers
Fünfzig Jahre undokumentiertes Geschäftswissen in eine Datenbank zu bekommen, ist ein Interviewproblem, kein Engineeringproblem. Ich habe für den Inhaber fünf strukturierte PDF-Interviewdokumente mit einem dreifarbigen Codiersystem erstellt:
- Grün — von mir vorausgefüllte Antwortentwürfe, die er bestätigt oder korrigiert
- Gelb — geschäftsspezifische Daten, die nur er kennt, bewusst leer gelassen
- Grau — interne Preisdaten, bewusst aus der Wissensbasis des Bots ausgeschlossen
Das Vorausfüllen der grünen Felder machte aus einer Aufgabe vor leerem Blatt eine Prüfaufgabe. Die grauen Felder ausdrücklich zu kennzeichnen bedeutete, dass die Grenze zwischen “das darf der Bot sagen” und “das ist intern” einmal auf Papier entschieden wurde, statt bei jeder Prompt-Überarbeitung neu verhandelt zu werden.
Technische Probleme, die eine Beschreibung verdienen
Ein einziges unsichtbares Zeichen legte die Authentifizierung lahm
Die API-Anbindung scheiterte an Authentifizierungsfehlern, obwohl die Zugangsdaten bei Sichtprüfung korrekt waren. Ursache war ein nicht druckbares Unicode-Zeichen (Klasse U+2028), das per Kopieren und Einfügen in die Umgebungsvariable geraten war. Es überstand jede Sichtprüfung, weil es per Definition unsichtbar ist. Behebung: Zugangsdaten bereinigen, bevor sie an einen SDK-Konstruktor übergeben werden — .replace(/[^\x21-\x7E]/g, '') — und die Hygiene von Umgebungsvariablen als vorrangiges Thema behandeln statt als nachgelagerte Konfigurationsfrage. Die allgemeine Lehre: Wenn Zugangsdaten “offensichtlich korrekt” sind und trotzdem scheitern, hört auf, sie zu lesen, und fangt an, ihre Bytes zu prüfen.
Temporäre Tokens sind eine Falle, die man sich selbst stellt
Der zweite blockierende Fehler war ein abgelaufenes WhatsApp-API-Token — das übliche Ergebnis, wenn man einer Einstiegsanleitung folgt. Ein dauerhaftes System-User-Token mit ausdrücklich zugewiesenen Assets und Berechtigungen muss bewusst eingerichtet werden, und der Preis dafür, es zu unterlassen, ist ein System, das in der Entwicklung funktioniert und Wochen später im Produktivbetrieb stillschweigend ausfällt, im ungünstigsten Moment.
Für die Array-Filterung in Postgres gibt es hier genau eine richtige Form
Produktaliase werden als text[] gespeichert (ein Fleischstück hat viele Namen, und Kunden verwenden sie alle). Die Filterung erfordert aliases.cs.{value} innerhalb eines einzigen .or()-Aufrufs — zwei verkettete .or()-Aufrufe ergeben eine Abfrage, die richtig aussieht und falsche Ergebnisse liefert. Verwandte Schemaentscheidungen, die die Werkzeuge geprägt haben: base_unit ist ein unit_type-Enum, weiches Löschen nutzt deleted_at, und Verfügbarkeitsänderungen müssen sowohl availability_updated_at als auch availability_updated_by schreiben, um die Nachvollziehbarkeit zu wahren.
Leitplanken gehören in den System-Prompt, nicht in die Wissensbasis
Zwei Vorgaben wurden bewusst von “Inhalt” zu “harter Regel” hochgestuft: niemals medizinische oder ernährungsbezogene Gesundheitsberatung; und Entscheidungen über Kredit bzw. fiado sind eine strukturierte Geschäftsregel, gebunden an customers.credit_limit_cents, und nichts, was der Bot aus Freitext wiedergibt. Eine Metzgerei, die informell anschreiben lässt, unterhält damit eine reale, tragende Geschäftsbeziehung. Fehler kosten Geld und Vertrauen, deshalb ist die Regel in Code und Schema verankert statt in Sprache, die sich das Modell merken soll.
Wie die Arbeit organisiert war
Das Projekt läuft über drei bewusst getrennte Kanäle, denn sie zu vermischen verschlechtert alle drei:
- Architekturkanal — Strategie, Phasendefinition und offene Entwurfsentscheidungen. Langsam, schriftlich, Entscheidungen dokumentiert.
- Debug-Kanal — Fehlerdiagnose, Auswertung von Screenshots, Korrekturen auf Codeebene. Schnell, kurzlebig.
- Lokale Ausführung — Claude Code auf dem Repository.
Planungssitzungen gehen der Umsetzung voraus, und Phasen werden formal definiert, bevor die Implementierung beginnt. Die Arbeit schreitet in prüfbaren, freigabepflichtigen Schritten mit Screenshot-Kontrollpunkten voran, nicht in ungeprüften Codepaketen.
Roadmap
- A2.1
- Kundenseitiger Bot
- A2.2
- Auswertung und Beobachtbarkeit — Funnel-Analyse, Gesprächsprotokollierung
- A3
- Kosten, Margen, Statistiken
- Operación
- Laufender Tagesbetrieb mit der konfigurierbaren Eskalationskette
- Decisión
- Strategischer Kontrollpunkt nach 3–6 Monaten echter Daten, aufbereitet in operativer Sprache
- Logística
- Anbindung externer Lieferdienste (Uber Direct, iVoy, Rappi Cargo) hinter einer Provider-Abstraktion, zunächst manuell über Schaltflächen im Dashboard
- B
- Sprach-KI — Vapi.ai als erste Wahl, ElevenLabs in Prüfung. Der Inhaber hat zugestimmt, seine Stimme zum Klonen aufzunehmen
- C
- Vollständiger E-Commerce
- D
- Buchhaltung — abhängig von der Entscheidung des Steuerberaters zur CFDI-Eigenausstellung
Die Phase Decisión ist diejenige, an der sich der Entwurfsgedanke am deutlichsten zeigt. Es gibt einen Kontrollpunkt in einigen Monaten, an dem die gesammelten Daten geprüft werden und die Roadmap die Richtung wechseln kann — und die Unterlagen für diese Prüfung werden jetzt schon in operativer Sprache festgelegt, denn ein Strategiefoliensatz voller Funnel-Diagramme wäre ein Dokument, mit dem die Person, für die es gedacht ist, nichts anfangen kann.
Was dieses Projekt zeigt
Architektur aus der Randbedingung heraus
“Kein Dashboard” ist keine Einschränkung, die man umgehen muss, sondern die Spezifikation. Sie ernst zu nehmen ergab ein saubereres System als die Variante, die sich mit einem Verwaltungsmenü im Web abgesichert hätte, das niemand öffnet.
Disziplin bei der Produktivintegration
WhatsApp Business API, das Token-Modell von Meta, Vercel, Supabase RLS und ein Modell mit Tool Calling, durchgängig verdrahtet und gegen Live-Daten validiert — einschließlich der unspektakulären Fehlschläge (unsichtbare Zeichen, ablaufende Tokens), die eine Demo von etwas unterscheiden, das an einem Dienstagmorgen läuft.
Sicherheit als Struktur, nicht als Anweisung
Berechtigungen werden über Kontextfilterung und Prüfung je Werkzeug durchgesetzt. Audit-Trails schreibt der Schreibpfad selbst. Das Modell ist nie die letzte Verteidigungslinie.
Ernsthafter Entwurf für einen nicht technischen Betreiber
Farbcodierte Interview-PDFs, operative Begriffe, ein nicht entfernbarer Rückhalt in der Eskalation und die ausdrückliche Entscheidung, die Buchhaltung zurückzustellen, bis der Steuerberater sich äußert. Das Schwierige an diesem Projekt war nie die Tool-Calling-Schleife.
Bauen für ein Geschäft, das bereits funktioniert
Ein fünfzig Jahre altes Geschäft muss nicht disruptiert werden. Es braucht, dass die Teile, die im Kopf einer einzigen Person liegen, dauerhaft werden, ohne die Arbeitsweise dieser Person zu ändern. Das ist ein engeres und interessanteres Problem als eine Neuentwicklung auf der grünen Wiese.