Odoo Online (SaaS) als Multi-Vertical-Backend
Overview
Replacement fuer Plan 003 Phase A (Self-Host Odoo auf Fargate verworfen wegen Aufwand + Kosten — siehe Plan 003 Document-Review-Findings S1/S2/S3). Stattdessen: Odoo Online (Odoo’s eigener Cloud-SaaS), 0–24 EUR/Mo statt 70–85 EUR/Mo, kein Hosting-Setup, in 1 Tag live.
Zwei Ziele in einem Plan:
- Aylem-Reference-Case-UI — Inhaber-Backend fuer Reservierungen + Bestellungen (Tabelle, Tischplan, Filter, Mobile-App).
- Multi-Vertical-Bundle-Asset — gleiche
_odoo.py-Helper-Schicht funktioniert fuer Restaurant + Friseur + Werkstatt + Praxis + Hotel. Pro Vertical eigener Odoo-Workspace, gleicher MCP-Tool-Code.
Das ersetzt die Frage „wo speichern wir Reservierungen/Bestellungen” mit einer Antwort die nicht nur fuer Aylem skaliert, sondern fuer jeden zukuenftigen KMU-Service-Kunden.
Problem Frame
Plan 002 hat den Voice-Bot mit SQLite + Telegram-Push fuer Aylem-Demo lauffaehig gemacht. Plan 003 versuchte Self-Host-Odoo zu addieren — Reviewer-Konsens: ueberdimensioniert (50 EUR/Mo Infra + 2–3 Wochen Setup + Cloudflare-Tunnel + RDS + Fargate-Memory-Tuning) fuer ein „einfaches” Reference-Case-Asset.
Marvin’s Klarstellung: Vereinfachen + guenstig. Plus: das Backend soll multi-vertical sein — Friseur, Werkstatt, Praxis, Hotel sollen mit derselben Plattform bedient werden koennen, sonst ist es kein Bundle-Asset.
Loesung: Odoo Online (gehosteter Odoo-SaaS direkt von Odoo S.A.) mit pro-Tenant-Workspace. Marvin hostet nichts selbst, hat aber denselben JSON-RPC-API-Layer wie Self-Host — der _odoo.py-Helper im tools-mcp funktioniert identisch. Migration auf Self-Host bleibt offen als Option fuer DSGVO-strenge Industriekunden in der Zukunft.
Requirements Trace
- R1. Aylem-Workspace in Odoo Online angelegt: Tisch-Layout (~20 Tische), Speisekarte (mind. die Items aus
knowledge/aylem/menu.md), Oeffnungszeiten, Reservierungs-Form aktiv. Erreichbar unter<workspace>.odoo.com. - R2.
tools-mcp/_odoo.pyHelper-Modul mit JSON-RPC-Wrapper, schreibt Reservierungen + Bestellungen ueberODOO_URL+ODOO_DB+ODOO_API_KEY(alles per ENV). - R3. Feature-Flag
STORAGE_BACKEND=sqlite|odoo|bothintools-mcp/server.py— beide Pfade lauffaehig, Defaultbothauf Marvin’s Mac (SQLite als lokaler Audit + Odoo als Source-of-Truth). - R4. Multi-Vertical-Pattern dokumentiert: pro Vertical (Restaurant, Friseur, Werkstatt, Praxis, Hotel) ein kurzes Onboarding-File mit Odoo-Modulen + Workspace-Setup + Beispiel-Stammdaten. Marvin kann Vertical Nr 2 in ~1 h aufsetzen.
- R5. Telegram-Push bleibt parallel zum Odoo-Insert aktiv — Push ist instant-Mobile-Channel, Odoo ist Read-on-demand-Inspector.
- R6. End-to-End-Smoke: Voice-Call macht
book_reservation→ Eintrag in Odoo + SQLite + Telegram-Push.
Scope Boundaries
In Scope:
- Odoo Online Workspace fuer Aylem (Restaurant)
tools-mcp/_odoo.pyals stdlib-JSON-RPC-HelperSTORAGE_BACKEND-Feature-Flag intools-mcp/server.py- 5 Multi-Vertical-Pattern-Docs (Restaurant, Friseur, Werkstatt, Praxis, Hotel) als Skelett
- ENV-Setup-Anleitung
- Smoke-Test Voice-Bot → Odoo-Insert
- Tests fuer
_odoo.py
Out of Scope (Folge-Plaene):
- WhatsApp-Kanal — eigener Plan (Plan 003, depends on dieser Plan)
- Self-Host Odoo auf Fargate (kommt zurueck wenn DSGVO-strenger Industriekunde SaaS-Veto einlegt)
- Multi-Tenant innerhalb eines Workspaces (Odoo Online macht das ueber separate Workspaces pro Kunde — sauberer)
- Echte Tenant-Onboarding fuer Friseur/Werkstatt/Praxis/Hotel (heute nur Pattern-Doku, kein lebender zweiter Tenant)
- Bondrucker-Hardware (Odoo unterstuetzt ESC/POS via App, aber Hardware-Setup ist eigener Plan)
- Stripe-Payment / Online-Shop
- LMIV-Allergen-Audit fuer echten Live-Pilot
- Aylem-Inhaber-Live-Pilot mit echter AVV
Context & Research
Relevant Code and Patterns
tools-mcp/_telegram.py— stdlib-only-Wrapper-Pattern, kein urllib3, kein Cross-Repo._odoo.pyfolgt demselben Stil (urllib.request + json).tools-mcp/_knowledge.py— Helper-Modul-Pattern mit Validation, fail-open, Logging, Test-Coverage.tools-mcp/server.py— bestehender MCP-Server mit 9 Tools. Wird um Feature-Flag erweitert, nicht refactored.book_reservation/take_order/escalate_to_humankriegen einen zweiten Persistence-Pfad.tools-mcp/tests/— pytest-Setup ist da, 33 Tests gruen. Neuetest_odoo.pyintegriert sich nahtlos.
Institutional Learnings
- Brain+MCPs-Modell (ADR keine-eigene-plattform): Backend-Schreibrecht lebt im MCP, Channels (Voice + WhatsApp) sind Adapter.
_odoo.pyist konsequent — kein eigenes Odoo-MCP als separates Repo (Overhead fuer 1 Tenant). - Stdlib-only-Helper-Pattern (
_telegram.pyLesson, Plan 002): Cross-Repo-Bindungen sind Fallen._odoo.pybraucht keine externe Library —urllib.requestreicht fuer JSON-RPC. - Voice-Bot-DE-Pattern (voice-bot-de-pattern.md): Persona + Tool-Discipline + Anti-IVR-Liste — unveraendert. Odoo ist Persistence-Schicht, beruehrt das nicht.
- MCP-as-a-Service-Vision (Memory): hosted MCPs in
av-productionmit OAuth + Multi-Tenant. Odoo Online ersetzt den Self-Host-Teil dieser Vision fuers Restaurant-Vertical — wir nutzen Odoo’s Hosting-Layer, sparen eigenen Aufwand.
External References
- Odoo Online — Cloud-SaaS direkt von Odoo S.A. Hosting in Belgien (EU-Region), DSGVO-tauglich. 1 App kostenlos, danach gestaffelt ab ~24 EUR/User/Monat (Standard-Tier).
- Odoo 18 Web Services / JSON-RPC — offizielle API-Doku. Authentifizierung via API-Key (in Odoo unter Settings → Users → API-Keys generieren).
- Odoo POS Restaurant Module — Tischplan, Reservierungen, Bestellungen.
- Odoo Appointment Module — Termin-Buchung fuer Friseur, Praxis, Coaching.
- Odoo Repair Management — Auftrags-Management fuer Werkstatt.
Key Technical Decisions
- Odoo Online (SaaS) statt Self-Host. Begruendung: Reviewer-Konsens aus Plan 003: 50 EUR/Mo Self-Host-Aufwand + 2–3 Wochen Setup waren overkill fuer Reference-Case. Odoo Online: 0 EUR Free-Tier oder 24 EUR/Mo Standard, kein Setup, kein Wartungsaufwand, automatische Updates. Self-Host bleibt offene Option fuer DSGVO-strenge Folge-Kunden (Folge-Plan).
- Workspace-pro-Tenant statt Multi-Tenant in einer DB. Begruendung: Odoo Online macht das nativ —
aylem-demo.odoo.comist eine eigene DB,friseur-mueller.odoo.comist eine andere. Saubere Trennung, keine Cross-Tenant-Leak-Risiken, kein Custom-Permission-Layer noetig. _odoo.pyals lokales Helper-Modul. Begruendung: gleiche Logik wie_telegram.pyund_knowledge.py. Stdlib-only (urllib.request fuer JSON-RPC), kein Cross-Repo, kein externes pip-Paket. Tenant-Switch ueber ENV-Variablen (ODOO_URL,ODOO_DB,ODOO_API_KEY).- Feature-Flag
STORAGE_BACKEND=sqlite|odoo|both, Defaultbothauf Marvin’s Mac. Begruendung: SQLite bleibt lokaler Audit-Trail (gleich-Filesystem wie der Voice-Worker), Odoo wird Source-of-Truth fuer Inhaber-UI. Bei Odoo-Down geht’s lokal weiter (Mac hat SQLite). Migration spaeter aufodoo-only nach 4 Wochen produktivem Lauf. - Multi-Vertical-Doku in
intern/wissen/prozesse/odoo-pattern-<vertical>.mdstatt im Plan-File. Begruendung: Plan ist Aufgaben-Doku, Pattern-Docs sind Bundle-Assets fuer kuenftige Onboardings. Pro Vertical: Odoo-Module-Liste, Workspace-Setup-Schritte, Stammdaten-Beispiele, MCP-Tool-Mapping. - Telegram-Push parallel zu Odoo-Insert. Begruendung: Push ist Mobile-instant, Odoo ist Read-on-demand. Restaurant-Inhaber checkt nicht permanent Odoo, Telegram bleibt primary-Notification. Odoo-eigene-Notifications werden im Workspace deaktiviert (Doppel-Push vermeiden).
- API-Key statt Username-Password fuer JSON-RPC. Begruendung: Standard seit Odoo 14, scoped, rotierbar, in AWS Secrets Manager hinterlegbar bei spaeterem Fargate-Worker. Heute:
.env.localreicht. - Free-Tier-Pruefung vor Standard-Plan-Commit. Odoo Online hat 1-App-Free-Tier. Restaurant-POS + Appointment passen in eine „App”-Kategorie. Bei knapp: 24 EUR/Mo Standard. Marvin checkt das beim Setup live.
Open Questions
Resolved During Planning
- SaaS vs Self-Host → SaaS (Odoo Online), Self-Host als Folge-Option offen.
- Multi-Vertical-Eignung → Odoo deckt Restaurant + Friseur + Werkstatt + Praxis + Hotel via separate Module ab. Bundle-Asset-Wert ist real.
- WhatsApp-Channel in diesem Plan? → Nein, eigener Plan 003 depends on diesen.
- Tisch-Slot-Race-Verifikation → nachrangig (Marvin’s Klarstellung), Restaurant-Inhaber regelt manuell bei Konflikt.
Deferred to Implementation
- Odoo Online Free-Tier-Grenzen 2026: Werden 2 Module (POS-Restaurant + Appointment) als „1 App” gezaehlt oder als 2? Marvin pruefts beim Setup; bei 2 Apps: 24 EUR/Mo Standard-Plan.
- Konkrete Odoo-Modell-Namen fuer Reservierung vs POS-Order: je nach Odoo-Version unterschiedlich (
calendar.eventvspos.ordervsrestaurant.table.booking). Beim Schreiben von_odoo.pyvia Odoo-Developer-Mode-Inspector verifizieren. - Aylem-Workspace-Name:
aylem-demo.odoo.comoder generischdemo-restaurant.odoo.com(siehe Aylem-Name-Risiko in Risks). Entscheidet Marvin beim Setup. - API-Rate-Limits bei Odoo Online Free-Tier: Plan rechnet mit MVP-Volumen (Marvin’s Test-Calls), Production-Limits werden beim Live-Pilot relevant.
High-Level Technical Design
Directional guidance, kein Implementation-Spec.
flowchart TB A[Voice-Anrufer] L[LiveKit Worker - Mac] M[tools-mcp Subprocess] O[(Odoo Online SaaS - Belgien)] S[(SQLite - lokal Mac)] T[Telegram Bot API] A --> L L <-->|stdio| M M -->|JSON-RPC| O M -->|write| S M --> T style O fill:#fff4e1 style M fill:#e1f5e1
_odoo.py Skelett (Pseudo-Code, directional)
# tools-mcp/_odoo.py — stdlib + json + urllib.request (kein urllib3, kein odoorpc)
class OdooClient:
def __init__(self, url, db, api_key, uid_cache=None):
self.url = url; self.db = db; self.api_key = api_key
self.uid = uid_cache or self._authenticate()
def call(self, model, method, args=None, kwargs=None) -> Any:
# JSON-RPC POST zu /jsonrpc, model + method + auth
...
def create_reservation(self, date, time, guests, name, phone, notes=None) -> Optional[int]:
# Returnt Odoo-Reservation-ID oder None bei Fehler
...
def create_pos_order(self, items: list, customer_name, phone, address=None, pickup_time=None) -> Optional[int]:
...
def list_today_reservations() -> list[dict]: # fuer Inhaber-Sicht oder Status-Tool
...
# Fail-Behavior (analog _telegram.py): exceptions swallowed + log.warning, returnt None
# Caller (server.py) checkt: if odoo_id is not None: success else: SQLite-only-PfadMulti-Vertical-Pattern-Skizze
| Vertical | Odoo-Module | Workspace-Beispiel | Key MCP-Tool-Mapping |
|---|---|---|---|
| Restaurant | point_of_sale_restaurant + pos_restaurant_appointment | aylem-demo.odoo.com | book_reservation → calendar.event; take_order → pos.order |
| Friseur | appointment + hr_attendance (Mitarbeiter-Planung) | friseur-mueller.odoo.com | book_reservation → calendar.event (Stylist-Slot) |
| Werkstatt | repair + appointment | werkstatt-schmidt.odoo.com | book_reservation → repair.order (Annahme-Termin) |
| Arztpraxis | appointment + hr_attendance | praxis-meier.odoo.com | book_reservation → calendar.event (Sprechstunde) |
| Hotel | hotel_management (Community-Modul) | hotel-stadt.odoo.com | book_reservation → hotel.reservation |
Gemeinsamer _odoo.py-Code mit Vertical-spezifischer Mapping-Schicht. Pro neuem Tenant: ENV-Variablen umstellen, ggf. ein Mapping-Dict erweitern. Kein Code-Patch.
Implementation Units
flowchart TB U1[Unit 1: Odoo Online Aylem-Workspace anlegen + befuellen] U2[Unit 2: _odoo.py + STORAGE_BACKEND-Flag + Tests] U3[Unit 3: Multi-Vertical-Pattern-Docs - 5 Markdown-Files] U1 --> U2 U1 -.->|parallel| U3
-
Unit 1: Odoo Online — Aylem-Workspace anlegen + befuellen
Goal:
<workspace>.odoo.comerreichbar mit Admin-Login. POS-Restaurant + Appointment-Module installiert. 20 Tische als Layout. 20 Menu-Items ausknowledge/aylem/menu.mdimportiert. Oeffnungszeiten in Resource-Calendar. Bot-User mit API-Key.Requirements: R1
Dependencies: keine
Files:
- Modify: Odoo-Online-Web-UI (Daten-Setup, kein Code) — Schritte in
docs/aylem-odoo-setup.mdals Runbook - Create:
intern/projekte/telefon-assistent-aws/docs/aylem-odoo-setup.md(Onboarding-Runbook fuer kuenftige Tenants) - Modify: AWS Secrets Manager (falls Marvin spaeter Fargate dazu nimmt) — heute reicht
.env.local
Approach:
- Account-Setup:
https://www.odoo.com/trial→ Datenbank anlegen, Admin-Email = Marvin’s, Workspace-Nameaylem-demo(siehe Aylem-Name-Risiko, ggf.demo-restaurant). Belgien-Region default = EU-DSGVO-tauglich. - Module-Aktivierung: Apps → „Point of Sale - Restaurants” + „Appointment”. Free-Tier check: wenn das als 1 App zaehlt, gratis. Sonst Standard-Plan 24 EUR/Mo akzeptieren oder einen Modul-Tradeoff machen.
- Tisch-Layout: Settings → POS → Restaurant → Floor Plan. Drag-Drop 20 Tische (3× 8er, 8× 4er, 9× 2er, siehe Plan 002 Aylem-Spezifikation).
- Speisekarte: Products → bulk import von
knowledge/aylem/menu.md. 20 Items mit Preisen + Allergen-Tags (Allergene als Odoo-Tags). - Oeffnungszeiten: Resource → Working Hours → identisch zu
knowledge/aylem/hours.md. - Bot-User: Users → neuer User
bot@aylem.demo, Berechtigung „User: All Documents” auf POS + Appointment, KEIN Admin. API-Key generieren in dessen User-Settings. - Stammdaten in
.env.local:ODOO_URL=https://aylem-demo.odoo.com,ODOO_DB=aylem-demo,ODOO_API_USER=bot@aylem.demo,ODOO_API_KEY=<aus-Odoo>. - Runbook schreiben parallel zum Setup — jeder Klick dokumentiert. Naechster Tenant kann in 1 h analog gesetzt werden.
Patterns to follow:
- Plan 002 Aylem-Daten-Spezifikation (Tisch-Anzahl, Karte, Hours) als Inhalts-Quelle
- Odoo Online Onboarding
- Vault-Convention fuer Setup-Runbooks: numerierte Schritte, jeder Klick + Screenshot-Hint
Test scenarios:
- Happy path: Login klappt im Browser, POS-Restaurant + Appointment-Module sichtbar in App-Menue
- Happy path: Floor Plan zeigt 20 Tische in grafischer Anordnung
- Happy path: Products-Liste hat 20 Items mit Preisen + Allergen-Tags
- Happy path: API-Key funktioniert — Smoke-curl
curl -X POST https://...odoo.com/jsonrpc -d '{"jsonrpc":"2.0","method":"call","params":{"service":"common","method":"authenticate",...}}'returnt UID - Edge case: Free-Tier-Limit-Check — wenn 2 Module = 2 Apps, Plan-Wahl entscheiden
- Edge case: 25. Tisch versucht hinzuzufuegen — Tisch-Layout-UI verhaelt sich vernuenftig (Default-Limit?)
- Integration: aylem-odoo-setup.md ist vollstaendig + reproduzierbar (Marvin koennte einen
demo-friseur-Tenant in 1 h analog anlegen)
Verification: Browser-Test komplett. API-Key liefert via JSON-RPC die Liste der Produkte zurueck. Runbook in
docs/aylem-odoo-setup.mdist fertig. - Modify: Odoo-Online-Web-UI (Daten-Setup, kein Code) — Schritte in
-
Unit 2:
_odoo.pyHelper +STORAGE_BACKEND-Feature-Flag im tools-mcpGoal:
tools-mcp/server.pykann Reservierungen + Bestellungen ueber JSON-RPC in Odoo Online schreiben. Feature-Flag erlaubt SQLite-only-, Odoo-only- oder Both-Mode.Requirements: R2, R3, R5
Dependencies: Unit 1 (Odoo erreichbar + API-Key vorhanden)
Files:
- Create:
intern/projekte/telefon-assistent-aws/tools-mcp/_odoo.py(stdlib + urllib.request, kein urllib3) - Modify:
intern/projekte/telefon-assistent-aws/tools-mcp/server.py—STORAGE_BACKENDENV,book_reservation+take_order+escalate_to_humanparallel-write je nach Flag - Modify:
intern/projekte/telefon-assistent-aws/tools-mcp/.env.example—STORAGE_BACKEND,ODOO_URL,ODOO_DB,ODOO_API_USER,ODOO_API_KEY - Modify:
intern/projekte/telefon-assistent-aws/tools-mcp/README.md— Setup-Block fuer Odoo - Create:
intern/projekte/telefon-assistent-aws/tools-mcp/tests/test_odoo.py(mit mocked JSON-RPC, kein Live-Call in CI)
Approach:
- OdooClient-Class mit Methoden:
authenticate()(einmalig, uid wird gecached),call(model, method, args, kwargs)(JSON-RPC-Wrapper viaurllib.request),create_reservation(),create_pos_order(), optionallist_today_reservations()als reuse. - Auth: API-Key-basiert ueber
common.authenticate(db, user, api_key)→ liefert UID. UID + API-Key fuer alle weiterenobject.execute_kw-Calls. - Datentypen-Coercion: Many2One-Felder kommen als
[id, name]-Tupel, Boolean-empty-Listen alsfalse. Helper-Funktionen in_odoo.pynormalisieren das. - Fail-Behavior (differenziert):
- Odoo unreachable (Network/5xx nach 3 Retries) →
log.warning, returnt None. - Bei
STORAGE_BACKEND=both: SQLite-Pfad uebernimmt, Bot antwortet normal, Telegram-Push enthaelt Warning „⚠ Odoo nicht erreicht, Eintrag nur in SQLite”. - Bei
STORAGE_BACKEND=odoo: Bot antwortet User degraded („Es gibt gerade ein technisches Problem, bitte rufen Sie das Restaurant direkt unter 02381 9153000 an”). KEINE falsche „gebucht”-Bestaetigung. - Auth-Fehler →
log.exception, urgent-Telegram-Alert. - 5xx → Retry 3× mit Exponential-Backoff max 3 s gesamt.
- Odoo unreachable (Network/5xx nach 3 Retries) →
- Feature-Flag in
server.py(Defaultboth):if STORAGE_BACKEND in ("sqlite", "both"): _sqlite_insert(...) if STORAGE_BACKEND in ("odoo", "both"): odoo_id = _odoo.create_reservation(...) _telegram.send(..., text=f"Reservierung {res_id}{' (Odoo #'+str(odoo_id)+')' if odoo_id else ''} ...") - ID-Korrelation in Telegram: SQLite-ID
RES-XXXXXX+ Odoo numerische ID, beide im Push falls vorhanden.
Patterns to follow:
tools-mcp/_telegram.py— stdlib-only, fail-loud, Logger-Pattern (1:1-Vorbild)tools-mcp/_knowledge.py— Validation + try/except-Pattern- Bestehende Tool-Funktionen in
tools-mcp/server.pyals Integrations-Stil
Test scenarios:
- Happy path:
STORAGE_BACKEND=both,book_reservation(...)legt Reservation in Odoo + SQLite an, ID-Korrelation in Telegram-Push - Happy path:
STORAGE_BACKEND=odoo,book_reservation(...)legt nur in Odoo an, kein SQLite-Eintrag - Happy path:
STORAGE_BACKEND=sqlite,book_reservation(...)legt nur in SQLite an, Odoo nicht aufgerufen - Edge case:
ODOO_API_KEYfehlt → log.warning beim Modul-Import, alle Odoo-Methoden returnen None, Bot faellt auf SQLite zurueck (imboth-Mode) - Edge case: leeres
STORAGE_BACKEND→ defaultboth - Edge case: Odoo-Many2One-Return
[42, 'Tisch 7']wird zu Integer 42 normalisiert - Error path: Odoo gibt 500 zurueck → 3× Retry mit Backoff, dann log.exception + None
- Error path: Auth fehlgeschlagen → urgent-Telegram-Alert an Marvin
- Error path:
STORAGE_BACKEND=odooaber Odoo unreachable → Bot-Antwort degraded mit Restaurant-Phone, KEIN positive „gebucht” - Integration: voller
book_reservation-Flow ueber server.py, Odoo-UI zeigt die Reservation, SQLite enthaelt sie, Telegram-Push hat beide IDs
Verification: Live-Tool-Call gegen Odoo Online:
python -c "from server import book_reservation; ..."legt Test-Reservierung an, Odoo-UI im Browser zeigt sie binnen 2 s, SQLite-DB enthaelt sie, Telegram-Push hat beide IDs. 6+ pytest-Tests gruen. - Create:
-
Unit 3: Multi-Vertical-Pattern-Docs (5 Markdown-Files)
Goal: Onboarding-Pattern dokumentiert, dass Marvin in ~1 h einen neuen Tenant (Friseur, Werkstatt, Praxis, Hotel) aufsetzen kann — kein Code-Patch noetig.
Requirements: R4
Dependencies: Unit 2 ist optional (Doku kann parallel laufen, aber profitiert vom Erfahrungs-Lernen aus Unit 2)
Files:
- Create:
intern/wissen/prozesse/odoo-pattern-restaurant.md(basiert auf Aylem-Erfahrung aus Unit 1+2) - Create:
intern/wissen/prozesse/odoo-pattern-friseur.md - Create:
intern/wissen/prozesse/odoo-pattern-werkstatt.md - Create:
intern/wissen/prozesse/odoo-pattern-praxis.md - Create:
intern/wissen/prozesse/odoo-pattern-hotel.md - Modify:
intern/wissen/prozesse/_index.md— Verlinkung - Modify:
intern/firma/produkt-bundle.md— KMU-Service-Vertical-Bundle als Capability ergaenzen
Approach:
- Pro Vertical-Datei mit Frontmatter (
type: process,status: draft|stable) und Sections:- Welche Odoo-Module noetig (Restaurant:
point_of_sale_restaurant+pos_restaurant_appointment; Friseur:appointment+hr_attendance; etc.) - Workspace-Setup-Schritte (Klick-Anleitung — copy von
aylem-odoo-setup.md, vertical-spezifisch adaptiert) - Stammdaten-Beispiele (Friseur: Stylist-Liste, Service-Katalog mit Dauer; Werkstatt: Auftragstypen, Annahme-Slots; Praxis: Arzt-Termine; Hotel: Zimmer-Typen)
- MCP-Tool-Mapping: welches
book_reservation/take_orderauf welches Odoo-Modell (calendar.eventvspos.ordervsrepair.ordervshotel.reservation) - Tonalitaet-Adjustments im System-Prompt (Friseur: lockerer, Praxis: foermlicher) — Verweis auf voice-bot-de-pattern.md.
- Pricing-Hint: Odoo Online Free-Tier vs Standard-Tier je nach Module-Anzahl.
- Welche Odoo-Module noetig (Restaurant:
- Restaurant-Pattern ist am detailliertesten (basiert auf Aylem-Realwelt-Erfahrung). Andere 4 sind Skelette mit Standard-Modul-Liste — werden ergaenzt wenn ein echter Kunde dazu kommt.
- Cross-Link zum Master-Plan: produkt-bundle.md bekommt einen neuen Eintrag „KMU-Service-Vertical-Bundle: Voice-Bot + Odoo-Online-Backend, pro Vertical Pattern unter
intern/wissen/prozesse/odoo-pattern-<x>. Setup-Zeit pro neuem Tenant: ~1 h”.
Patterns to follow:
- voice-bot-de-pattern.md als Format-Vorbild fuer Process-Docs
- mcp-hosting-fargate-tunnel.md als Beispiel fuer „Onboarding-Setup-Runbook”
- schemas.md §5.21 (Process-Frontmatter)
Test expectation: none — Dokumentations-Artefakte. Verifikation ueber zwei Wege:
- Pruefen: ist jede Datei lesbar + vollstaendig fuer einen Implementer der den Vertical NICHT kennt?
- Hypothetisch: koennte Marvin in 1 h einen
demo-friseur.odoo.comanalog zu Aylem aufsetzen, nur mit der Doku in der Hand?
Verification: Marvin macht 30-min-Selftest: liest
odoo-pattern-friseur.md, checked ob alle Setup-Schritte + Module + Tool-Mapping klar sind. Wenn ja → fertig. Wenn Lueck: ergaenzen. - Create:
System-Wide Impact
- Interaction graph: Bestehender LiveKit-Worker auf Mac bleibt unveraendert. tools-mcp wird erweitert um
_odoo.py+ Feature-Flag — bestehende Tools (book_reservation,take_order,escalate_to_human) bekommen einen zweiten Persistence-Pfad. WhatsApp-Worker (Plan 003, separat) wird denselben_odoo.py-Pfad nutzen — kein Duplikation-Risiko. - Error propagation: Odoo unreachable → fail-open auf SQLite (im
both-Mode) oder degraded-Reply (imodoo-Mode). Auth-Fehler → urgent-Telegram-Alert. Telegram-Push-Fehler → silent log, beeinflusst Tool-Call nicht. - State lifecycle risks: Race-Condition Voice + WhatsApp auf denselben Tisch-Slot — laut Marvin nachrangig, manuelle Konfliktloesung durch Inhaber. Bei spaeterem Skalierungs-Bedarf: application-level Locking in
_odoo.py. - API surface parity: tools-mcp Tool-Liste unveraendert (immer noch 9 Tools), nur Persistence-Pfad zusaetzlich. Externe Claude-Code/Desktop-Konsumenten brauchen kein Update.
- Integration coverage: End-to-End nur durch manuellen Voice-Call + Odoo-UI-Inspection pruefbar. Mocking nur fuer pytest-Unit-Tests sinnvoll.
- Unchanged invariants: LiveKit-Worker auf Mac bleibt. SQLite-Schema bleibt rueckwaertskompatibel. ID-Format
RES-XXXXXX/ORD-XXXXXXbleibt. Telegram-Push-Format bleibt. Voice-Bot funktioniert auch ohne Odoo (SQLite-Pfad bleibt als Fallback).
Risks & Dependencies
| Risk | Likelihood | Impact | Mitigation |
|---|---|---|---|
| Odoo Online Free-Tier zu klein (2 Apps statt 1) → 24 EUR/Mo Standard noetig | Mittel | Niedrig | Beim Setup pruefen. Bei 24 EUR/Mo: akzeptabel, im Bundle-Pricing einkalkulieren. Self-Host bleibt offen als Option. |
| Odoo Online Hosting in Belgien — DSGVO-AVV mit Odoo S.A. pruefen | Niedrig | Mittel | Odoo Online ist DSGVO-konform (offiziell). AVV-Standardvertrag verfuegbar. Fuer Reference-Case-Demo ohne Live-Anrufer-Daten unkritisch. Bei Live-Pilot: AVV-Unterschrift Pflicht. |
| Aylem-Name-Nutzung ohne Inhaber-Konsens | Mittel | Mittel | Workspace-Name generisch waehlen (demo-restaurant-001 statt aylem-demo), interne Daten von Aylem-Realitaet inspiriert aber nicht 1:1. Bei Demo gegenueber Lead: „anonymisiertes Beispiel-Restaurant” framing. |
| Odoo Online API-Rate-Limits bei MVP-Volumen | Niedrig | Niedrig | Marvin’s Test-Calls sind <10/Tag. Live-Pilot mit 100+ Reservierungen/Tag braucht Limit-Check, Folge-Plan. |
| Multi-Vertical-Docs sind Skelett, bei realem Friseur-Kunde nicht ausreichend | Mittel | Niedrig | Bewusst nur Pattern-Skelett im Plan. Pro echtem Kunde wird das File ausgefuellt mit dessen Realwelt-Daten. Restaurant-Pattern (Aylem) ist Vorlage. |
| _odoo.py Datentypen-Quirks (Many2One als Tupel etc.) | Mittel | Niedrig | Pre-Coding: 30-min-Inspector in Odoo-Web-UI (Developer-Mode) fuer alle benoetigten Modelle. Coercion-Helper in _odoo.py. |
| Workspace-Lock-in bei Odoo S.A. | Niedrig | Mittel | Odoo-Daten sind exportierbar (XML/CSV). Migration auf Self-Host-Odoo bleibt offene Option. _odoo.py-Code ist gleichgueltig ob SaaS oder Self-Host. |
| Setup-Aufwand fuer Plan 004 unterschaetzt | Niedrig | Niedrig | Realistic: 1 Tag Unit 1 + 1 Tag Unit 2 + 0.5 Tag Unit 3 = 2.5 Werktage. Im Gegensatz zu Plan 003 (2-3 Wochen Self-Host) sehr ueberschaubar. |
Documentation Plan
- Update _index.md Open-Loops — Plan 004 als „Odoo SaaS-Backend, ersetzt Plan 003 Phase A”
- Update Master-Plan 2026-05-13-001 Open-Loops „echte Bestell-Anbindung” — entschieden via Plan 004
- Update Plan 003 — Frontmatter + Overview: depends on Plan 004, fokussiert jetzt nur noch auf WhatsApp-Channel
- Create 5 odoo-pattern-Files unter
intern/wissen/prozesse/(Unit 3 Deliverable) - Update
intern/wissen/prozesse/_index.md— Verlinkung der 5 neuen Files - Update
intern/firma/produkt-bundle.md— „KMU-Service-Vertical-Bundle” als neue Capability mit Verweis auf Plan 004
Operational / Rollout Notes
- Rollout-Reihenfolge: Unit 1 zuerst (Odoo-Workspace anlegen). Unit 2 (
_odoo.py) kann erst loslegen wenn Workspace + API-Key da sind. Unit 3 (Docs) kann parallel zu Unit 2 laufen. - Aufwand: realistisch 2.5 Werktage. Unit 1 ~1 Tag (Account, Module, Tisch-Layout, Karte importieren, Hours, API-Key, Runbook). Unit 2 ~1 Tag (
_odoo.py+ Feature-Flag + Tests). Unit 3 ~0.5 Tag (5 Doku-Files, Restaurant-Pattern ausfuehrlich, andere 4 als Skelett). - Kosten: 0–24 EUR/Mo (Odoo Online Free-Tier oder Standard). Im Vergleich zu Plan-003-Self-Host: ~50 EUR/Mo Ersparnis, ~1 Woche Setup-Ersparnis.
STORAGE_BACKEND-Migration: Start mitboth(Default), nach 4 Wochen produktivem Lauf Switch aufodoo. SQLite bleibt als Read-Only-Historical-Archive auf Mac.- Reload-Strategie:
_odoo.pyundserver.pyaendern → MCP-Subprocess wird beim naechsten Job neu gespawned. Bei laufendem Worker: Ctrl-C +python agent.py devneu (~5 s). Knowledge-Markdown-Edits bleiben ohne Restart wirksam. - Plan 003 Status: wird zu „depends on Plan 004”, fokussiert nur noch WhatsApp-Channel. Phase A aus Plan 003 ist via Plan 004 ersetzt.
Sources & References
- Master-Plan: 2026-05-13-001-feat-voice-bot-de-production-plan.md
- Substanz-Iter: 2026-05-13-002-feat-voice-bot-substanz-iteration-plan.md
- WhatsApp-Folge-Plan: 2026-05-13-003-feat-odoo-whatsapp-restaurant-backend-plan.md (depends on diesen)
- Code-Vorbild Telegram-Pattern: _telegram.py
- Code-Vorbild Knowledge-Helper: _knowledge.py
- Vault — Voice-Bot-Pattern: voice-bot-de-pattern.md
- Vault — ADR Brain+MCPs: keine-eigene-plattform.md
- Vault — Produkt-Bundle: produkt-bundle.md
- Externe — Odoo Online: odoo.com/de_DE/page/start
- Externe — Odoo 18 JSON-RPC: odoo.com/documentation/18.0/developer/howtos/web_services.html
- Externe — POS Restaurant: odoo.com/app/point-of-sale-restaurant
- Externe — Appointment: odoo.com/app/appointments
- Externe — Repair Management: odoo.com/app/maintenance
Related
- _index — Projekt-Index Telefon-Assistent
- 2026-05-13-001-feat-voice-bot-de-production-plan — Master-Plan
- 2026-05-13-002-feat-voice-bot-substanz-iteration-plan — Substanz-Iter
- 2026-05-13-003-feat-odoo-whatsapp-restaurant-backend-plan — WhatsApp-Folge (depends on diesen)
- voice-bot-de-pattern
- keine-eigene-plattform
- produkt-bundle