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

207 lines
9.4 KiB
Markdown

# 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:
```json
[{"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.