Files
shop/module.md
Marek Lenczewski 9c5da44f64 wahnsinn
2026-04-16 17:10:40 +02:00

9.4 KiB

Shopsystem — Module (Implementierungs-Schritte)

Jedes Modul ist ein end-to-end Feature (Backend + Frontend + Tests + Migrationen + ggf. Doku gemeinsam). Module bauen aufeinander auf, können aber jeweils eigenständig gemerged werden.

Format pro Modul:

  • Ziel: Was soll am Ende funktionieren
  • Backend: API-Endpunkte, Modelle, Migrationen, Events
  • Frontend: Welche App (shop/admin), welche Seiten/Komponenten
  • Fertig wenn: Akzeptanzkriterium — konkret und testbar

Modul 0 — Projektgerüst

Ziel: Monorepo steht, alle drei Apps (backend, frontend/shop, frontend/admin) starten lokal, Docker-Compose bringt Postgres/Redis/Meilisearch/Ollama hoch.

Backend:

  • pyproject.toml mit uv, FastAPI, SQLAlchemy, Alembic, Redis-Client, pytest, ruff
  • Health-Endpunkt GET /health (Backend + DB + Redis ping)
  • APP_ENV + .env.example

Frontend:

  • frontend/shop und frontend/admin via pnpm create vue mit TS, Pinia, Router, Vitest
  • Shared Package frontend/shared für API-Client, i18n-Keys, gemeinsame Typen
  • Jede App startet mit Platzhalter-Seite und zeigt Backend-Health-Status

Infra:

  • docker-compose.yml: Postgres, Redis, Meilisearch, Ollama (mit Modell-Pull-Init)
  • Makefile oder justfile mit dev, test, lint, migrate

Fertig wenn: docker-compose up + make dev → Browser zeigt grünen Health-Status auf localhost:5173 (shop) und localhost:5174 (admin).


Modul 1 — Core-Framework

Ziel: App-basiertes Laden funktioniert. Der Core kennt Apps, lädt deren Router/Migrationen/Events.

Backend:

  • App-Loader: Entdeckt apps/*/manifest.yaml, prüft Abhängigkeiten/Konflikte, lädt Reihenfolge auf
  • Manifest-Schema: name, version, depends_on, conflicts_with, provides, required
  • DI-Container (minimal, z.B. via punq oder eigen): Services pro App registrierbar
  • Event-Bus (in-process für MVP, Interface offen für Broker): publish(event), subscribe(handler), persistierte events-Tabelle für Audit
  • Settings-Service: Key-Value-Store in Postgres, App-Namespace, Typisierung
  • Redis-Projector-Interface: Apps registrieren Projektoren, die bei Events Redis aktualisieren
  • Migrations-Runner: sammelt Alembic-Heads aus allen Apps

Frontend:

  • Kein User-facing Code. Aber frontend/shared bekommt Typen für Setting + Event-Envelope.

Fertig wenn:

  • Eine Dummy-App apps/hello mit leerer Route /api/hello lädt automatisch.
  • Setting core.shop_name lässt sich setzen und lesen (API).
  • Event beim Setting-Change landet in events-Tabelle und aktualisiert Redis-Key.

Modul 2 — Auth & User

Ziel: Registrierung, Login, Rollen (Kunde / Admin) funktionieren end-to-end in beiden Frontends.

Backend (apps/auth):

  • Entitäten: user (id, email, password_hash, role, locale, created_at), refresh_token
  • Endpunkte: POST /auth/register, POST /auth/login, POST /auth/refresh, POST /auth/logout, GET /auth/me
  • JWT (Access 15 min, Refresh 30 Tage), argon2 für Passwörter
  • Events: user.registered, user.logged_in
  • Seed: 1 Admin (admin@example.com / admin)

Frontend (shop + admin):

  • Shop: Register/Login-Seite, Account-Seite (persönliche Daten ändern, Passwort ändern)
  • Admin: Login-Seite mit Rollen-Check (nur role=admin darf rein)
  • Pinia-Store auth + API-Interceptor für Access-Token-Refresh

Fertig wenn: Kunde kann sich im Shop registrieren & einloggen. Admin kann sich im Admin-Frontend einloggen, Kunde wird dort abgewiesen.


Modul 3 — Produkte & Kategorien

Ziel: Admin pflegt Produkte + Kategorien, Shop zeigt sie.

Backend (apps/catalog):

  • Entitäten: product (id, sku, name_i18n, description_i18n, price, currency, stock, active, images[], category_id), category (id, slug, name_i18n, parent_id)
  • Endpunkte: GET /products, GET /products/{id}, GET /categories (public, aus Redis)
  • Admin-Endpunkte: POST/PUT/DELETE /admin/products, dto. Kategorien
  • Events: product.created/updated/deleted, category.*
  • Redis-Projektor schreibt nach Events
  • Image-Upload (zunächst lokaler Storage, per Interface austauschbar)

Frontend Shop:

  • Startseite mit Produktliste
  • Kategorieseite, Produktdetailseite

Frontend Admin:

  • Produktliste, Produkt-Bearbeitungs-Form (inkl. i18n-Felder DE/EN, Bild-Upload)
  • Kategorieverwaltung (Baum)

Fertig wenn: Admin legt Kategorie + Produkt an, Shop zeigt beides ohne Reload (Redis synchron).


Modul 4 — Warenkorb & Checkout

Ziel: Kunde kann Produkte in den Warenkorb legen und eine Bestellung abschließen (ohne echte Zahlung — Stub).

Backend (apps/cart, apps/checkout, apps/payment als Stub):

  • cart (user_id oder session_id, items[])
  • checkout: validiert Cart, nimmt Adress- + Zahlungsmethoden-Daten entgegen, erzeugt Order
  • payment: Stub-Provider (DummyPayment) mit Interface PaymentProvider
  • Endpunkte: GET/POST/DELETE /cart/items, POST /checkout/preview, POST /checkout/confirm

Frontend Shop:

  • Warenkorb-Seite + Mini-Cart
  • Checkout-Flow (Adresse → Zahlungsmethode → Bestätigung)

Fertig wenn: Kunde legt Produkt in den Warenkorb und schließt Checkout ab → Order liegt in DB mit Status paid (Dummy-Provider).


Modul 5 — Bestellungen & Mail

Ziel: Bestellliste für Kunde + Admin, Bestellbestätigungs-Mail nach Order.

Backend (apps/orders, apps/mail):

  • orders-App reagiert auf checkout.confirmed → schreibt Order, Status-Historie
  • Endpunkte: GET /orders (eigene), GET /admin/orders (alle), GET /orders/{id}
  • mail-App: Interface MailProvider (dev = Konsole/Mailhog, prod = SMTP/Anbieter)
  • Event-Handler: order.created → Bestätigungs-Mail mit Template (Jinja2, i18n)

Frontend Shop:

  • /account/orders — Bestellliste + Detailseite

Frontend Admin:

  • /admin/orders — Liste mit Filter, Detailseite mit Statusänderung

Fertig wenn: Nach Checkout landet Mail in Mailhog, Kunde + Admin sehen Bestellung in ihrer jeweiligen Liste.


Modul 6 — KI-Core (RAG)

Ziel: RAG-Infrastruktur steht. Produkte, Kategorien, Settings sind indiziert und abfragbar.

Backend (apps/ai_core):

  • LLMProvider-Interface + OllamaProvider (Default): chat(), embed()
  • Vector-Store: pgvector-Extension in Postgres, Tabelle ai_documents (id, source_type, source_id, text, embedding, metadata)
  • Indexer reagiert auf Events (product.*, category.*, core.settings_updated) und aktualisiert Embeddings
  • Endpunkt: POST /ai/query — nimmt Text + Kontext-Typ, liefert Antwort + relevante Dokument-IDs
  • Tool-System: Apps registrieren "Tools" (Funktionen), die die KI aufrufen darf — aber nur als Vorschlag, keine direkte Ausführung. Vorschläge werden als strukturiertes JSON zurückgegeben.

Frontend: keines in diesem Modul — Infrastruktur only.

Fertig wenn: POST /ai/query mit "grüner Pulli" liefert passende Produkt-IDs. Änderung an einem Produkt aktualisiert dessen Embedding automatisch.


Modul 7 — Shop-KI-Suche

Ziel: Kunde kann im Shop natürlichsprachlich nach Produkten suchen.

Backend (apps/ai_shop):

  • Endpunkt POST /ai/shop/search — nutzt ai_core, liefert gefilterte/sortierte Produktliste
  • System-Prompt ist Shop-aware (Währung, Sprache des Users)

Frontend Shop:

  • KI-Suchleiste oben (neben klassischer Suche)
  • Eingabe "ich suche einen grünen Pulli" → Produktgrid aktualisiert sich, KI-Begründung optional ausklappbar

Fertig wenn: Suche nach "etwas warmes zum Wandern" liefert plausible Produkte (abhängig von Seed-Daten).


Modul 8 — Admin-KI-Chat mit Vorschlags-Cards

Ziel: Admin kann per Chat Aktionen planen lassen und per Card bestätigen.

Backend (apps/ai_admin):

  • Endpunkt POST /ai/admin/plan — nimmt Prompt (oder JSON), nutzt ai_core-Tools, gibt Aktionsplan als Liste von Cards zurück:
    [{"tool": "settings.update", "args": {...}, "missing": [], "preview": "..."}]
    
  • Endpunkt POST /ai/admin/execute — nimmt bestätigte Card(s), validiert, führt die zugrundeliegenden Tools aus, gibt Resultat zurück
  • Tools registrieren sich mit JSON-Schema für Args, sodass fehlende/ungültige Felder erkennbar sind
  • Audit-Log jedes ausgeführten Tools

Frontend Admin:

  • Chatbox auf Startseite
  • Eingabe Text ODER JSON-Bulk → zeigt Cards mit Tool, geplanten Args, fehlenden Feldern (editierbar)
  • "Bestätigen" pro Card oder "Alle bestätigen" → ruft execute
  • Erfolg/Fehler-Feedback pro Card

Beispiele, die nach Modul 8 funktionieren müssen:

  • "setze den Shopnamen auf TEST123" → eine Card settings.update {key: core.shop_name, value: TEST123} → Bestätigen → Setting geändert
  • (JSON mit 3 Produkten) "das sind neue Produkte, erstelle sie" → 3 Cards catalog.product.create; fehlende SKU editierbar → Bestätigen → Produkte angelegt

Fertig wenn: Beide Beispiele oben funktionieren end-to-end.


Querschnittliche Themen (werden in jedem Modul mitgemacht)

  • Tests: pytest für Backend, vitest für Frontend; jedes Modul bringt mindestens einen Happy-Path-Test mit
  • i18n: Alle user-sichtbaren Strings DE + EN
  • Migrationen: Alembic-Head pro App, Core-Runner orchestriert
  • Code-Qualität: ruff + eslint/prettier laufen in CI (CI selbst in einem späteren Wartungs-Modul)
  • Fehlendes bewusst ausgelassen (optionale Apps, Phase 2+ der Analyse): Wunschliste, Bewertungen, Gutscheine, echte Payment-Provider, B2B-Preise, Genehmigungsworkflows, erweiterte Suche, SEO, Analytics. Werden als optionale Apps später gebaut.