Files
hd-commerce/README.md
T
till e5514dd5da v2.2: Verkaufsfertig-Fundament — Mollie/Payment-Abstraktion, MwSt/Grundpreis (PAngV), Versandzonen, Bestellmails (Listmonk/SMTP/Log), Feature-Flags
- payments.js: einheitliche createPayment/Webhook-Schnittstelle (Mollie Default, Stripe, Demo); Auto-Provider-Wahl; Mollie-REST + /api/payments/webhook (idempotent); Fake-Key => sauberer Demo-Fallback
- mailer.js: sendMail via Listmonk-Tx / SMTP (nodemailer) / Log-Fallback (email_log); gebrandete Bestellbestaetigung bei paid
- DACH: products.mwst + base_amount/base_unit/base_price_per (Grundpreis); Storefront/Warenkorb/Checkout/Erfolg/Admin mit MwSt-Ausweis + Versand-Transparenz; tax_cents/shipping_cents/country an Orders
- shipping_zones-Tabelle + CRUD + shippingFor(); Admin 'Versand'; serverseitige Versandberechnung in /api/checkout + /api/shipping-quote (Laenderwahl live)
- Feature-Flags (feature_*) + feature()-Helper; Admin Module-Toggles; Newsletter-Gating (Popup/Subscribe)
- Admin-API/Manifest/ai-admin.txt um shipping_zones erweitert; MCP list/upsert/delete_shipping; README/.env.example ergaenzt; Version 2.2.0
2026-06-17 16:37:10 +00:00

114 lines
9.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# hd-commerce
**hd-commerce** ist ein eigenständiges, brand-neutrales E-Commerce-Backend von Heidrich Digital: eine wiederverwendbare Astro-SSR-Anwendung mit Commerce-Engine (SQLite), Session-gesichertem Admin, Visual-Block-Builder, KI-/MCP-Editierbarkeit, JSON-API und einem schlanken, neutralen Demo-Storefront.
Die mitgelieferte Demo-Instanz heißt **„Brittas Nähkiste"** (Kurzwaren/Nähbedarf) und dient nur als Beispiel. Name, Akzentfarbe, Texte und Logo-Wortmarke sind über die Einstellungen frei anpassbar — derselbe Code läuft für beliebige Shops.
## Features
- **Storefront** (hell, editorial, neutral): Startseite mit Announcement-Bar, Slider, Kategorien, Featured-Produkten und Newsletter; Shop-Katalog; Produktdetailseiten; Warenkorb (localStorage); Checkout; Inhaltsseiten aus der DB — wahlweise klassisch oder über den **Block-Builder** gestaltet.
- **Admin** (Premium, „Warmth & Approachability"): Session-Login statt Browser-Basic-Auth, Rollen (Owner/Redaktion/Versand), Command-Palette (⌘K), Toasts, aufgewertetes Dashboard mit KPI-Trends, Sparkline, Aktivitäts-Feed und Schnellaktionen.
- **Visual-Block-Builder**: Vollbild-Editor mit Block-Liste (Drag/▲▼/duplizieren/löschen), Live-Vorschau (Desktop/Mobil) und Block-Einstellungen. Block-Typen: Hero, Rich-Text, Bild, Galerie, Slider, Feature-Grid, Produkt-Grid, CTA-Banner, Abstand, Roh-HTML.
- **KI-Editierbarkeit**: token-gesicherte Admin-JSON-API (`/api/admin/*`) plus maschinenlesbares Manifest (`/api/admin`, `/ai-admin.txt`) und ein **MCP-Server** (`mcp/`).
- **Gutschein-/Rabatt-Engine** (v2.1): Codes vom Typ `percent` / `fixed` / `freeshipping` mit Zeitplan, Mindestbestellwert, Gesamt- und Pro-Kunde-Limit, „geheim" (nicht öffentlich listbar) und „automatisch" (greift ohne Code, wenn Bedingungen erfüllt). Admin-Bereich **Rabatte** (Owner/Redaktion) mit Status-Badges (Aktiv/Geplant/Abgelaufen/Aufgebraucht/Inaktiv); Storefront-Einlösung im Checkout über `/api/discount`; serverseitige Re-Validierung in `/api/checkout`; Stripe-Coupon-Anbindung. Popups können einen Code anzeigen (+ Kopieren-Button) — auch für gezielt verteilte geheime Codes; Popup-Stile `modal` / `slidein` / `bar`.
- **Verkaufsfertig-Fundament (v2.2):**
- **Payment-Abstraktion** (`src/lib/payments.js`): einheitliche Schnittstelle für **Mollie** (Default, REST), **Stripe** und **Demo**. Provider via Setting `payment_provider` / ENV `PAYMENT_PROVIDER`, sonst Auto-Wahl nach vorhandenen Keys. Mollie-Webhook unter `/api/payments/webhook`; ungültiger Key ⇒ sauberer Demo-Fallback statt Fehler.
- **DACH-Recht**: MwSt-Ausweis pro Produkt (`mwst` 0/7/19), **Grundpreis** (PAngV) über `base_amount`/`base_unit`/`base_price_per`; Warenkorb/Checkout zeigen Zwischensumme, enthaltene MwSt (nach Satz gruppiert) und **Versand vor dem Bezahlen**.
- **Versandzonen** (Tabelle `shipping_zones`, Admin „Versand"): länderbasierte Preise mit Gratis-ab-Schwelle; Helper `shippingFor(country, subtotal)`; Checkout berechnet Versand serverseitig neu.
- **Bestell-/Versandmails** (`src/lib/mailer.js`): Provider **Listmonk** (Transactional-API) / **SMTP** (nodemailer) / **Log-Fallback** (Tabelle `email_log`, Admin „E-Mail-Log"). Gebrandete Bestellbestätigung bei bezahlter Bestellung.
- **Feature-Flags**: Module pro Shop abschaltbar (`feature_newsletter`, `feature_accounts`, `feature_reviews`, `feature_wishlist`, `feature_abandoned_cart`, `feature_search`) über Admin → Einstellungen → Module; Helper `feature(key)`.
- **Editierbare, gebrandete 404** (v2.1): `src/pages/404.astro` rendert die System-Seite mit Slug `404` über den Block-Builder. Wird per `ensureSystemPages()` bei jedem Boot idempotent angelegt und ist im Admin unter **Inhalte** editierbar.
- **Engine**: synchron via `better-sqlite3` (WAL), automatisches Seeding beim ersten Start.
- **First-Party-Analytics**: eigene `events`-Tabelle, kein externer Dienst (Session = täglich rollender Hash).
- **Branding konfigurierbar**: Shop-Name, Akzentfarbe, Währung u. a. in einer `settings`-Tabelle.
- **Self-hosted Fonts** (Fraunces + Public Sans), kein Google-CDN. Chart.js via cdnjs.
## Authentifizierung & Rollen
- **Session-Login** per HTML-Formular (signiertes HMAC-Cookie, „Angemeldet bleiben" = 30 Tage). Passwörter werden mit `node:crypto.scryptSync` + zufälligem Salt gehasht.
- **Initial-Owner** wird beim ersten Boot aus `ADMIN_EMAIL` / `ADMIN_PASS` angelegt; weitere Nutzer im Admin unter **Nutzer & Zugänge** (Owner-only).
- **Rollen**: `owner` (alles), `redaktion` (Produkte/Inhalte/Marketing/Analytics), `versand` (nur Bestellungen). Navigation und Seiten werden serverseitig nach Rolle gegated.
- **Konfigurierbarer Admin-Pfad** über `ADMIN_PATH` (Default `admin`, z. B. `intern` → Admin unter `/intern`). Direkter Zugriff auf `/admin` wird bei abweichendem Pfad mit 404 blockiert.
- **Audit-Log** (Tabelle `audit`) protokolliert Create/Update/Delete; Ansicht unter **Aktivität (Audit)** (Owner). Login-Rate-Limit: nach 5 Fehlversuchen 60 s Sperre pro IP.
## Umgebungsvariablen (ENV)
| Variable | Beschreibung | Default |
|---|---|---|
| `DB_PATH` | Pfad zur SQLite-Datenbank (wird angelegt) | `./data/hdc.db` |
| `ADMIN_EMAIL` | Initial-Owner-E-Mail (erster Boot) | `admin@example.com` |
| `ADMIN_PASS` | Initial-Owner-Passwort (erster Boot) | `admin` |
| `ADMIN_PATH` | Pfad-Segment des Admin-Bereichs | `admin` |
| `SESSION_SECRET` | HMAC-Geheimnis für Session-Cookies | interner Fallback (in Prod setzen!) |
| `HDC_API_TOKEN` | Bearer-Token für `/api/admin/*`. Leer ⇒ API gesperrt | |
| `STRIPE_PUBLIC_KEY` | Stripe Publishable Key (optional) | |
| `STRIPE_SECRET_KEY` | Stripe Secret Key. Ohne echten Key läuft der Demo-Checkout. | |
| `PAYMENT_PROVIDER` | Zahlungsanbieter erzwingen: `mollie` / `stripe` / `demo`. Leer ⇒ Auto-Wahl | |
| `MOLLIE_API_KEY` | Mollie API-Key (`test_…`/`live_…`). Ohne gültigen Key Demo-Fallback | |
| `MAIL_PROVIDER` | `listmonk` / `smtp` / leer (⇒ Log-Fallback in `email_log`) | |
| `MAIL_FROM` | Absenderadresse ausgehender Mails | |
| `LISTMONK_URL` / `LISTMONK_USER` / `LISTMONK_PASS` / `LISTMONK_TX_TEMPLATE_ID` | Listmonk Transactional-API | |
| `SMTP_HOST` / `SMTP_PORT` / `SMTP_USER` / `SMTP_PASS` / `SMTP_SECURE` | SMTP-Versand (nodemailer) | |
Siehe `.env.example`.
## Lokal starten
```bash
npm install
npm run dev # http://localhost:4321
# oder produktiv:
npm run build
node ./dist/server/entry.mjs
```
Storefront: `/` · Admin: `/admin` (bzw. `/${ADMIN_PATH}`). Erst-Login mit `ADMIN_EMAIL` / `ADMIN_PASS`.
## Block-Builder
Jede Seite (`pages`) hat ein Feld `blocks` (JSON-Array). Der Vollbild-Editor liegt unter `/${ADMIN_PATH}/inhalte/editor/<id>` (Button „Editor" in der Seitenliste). Gespeicherte Blöcke werden vom **Storefront-Block-Renderer** (`src/components/BlockRenderer.astro`) auf `/seite/<slug>` ausgegeben.
## KI-Editierbarkeit (API)
Token-gesicherte JSON-API unter `/api/admin/*` (Header `Authorization: Bearer <HDC_API_TOKEN>`):
- `GET /api/admin` — maschinenlesbares Manifest (Ressourcen, Felder, Block-Typen, Endpunkte).
- `GET /ai-admin.txt` — dieselbe Beschreibung als Klartext für LLMs.
- `GET /api/admin/{resource}` · `GET /api/admin/{resource}/{id}` — lesen.
- `POST /api/admin/{resource}` — Upsert (mit `id` oder `slug` ⇒ Update, sonst Create).
- `DELETE /api/admin/{resource}/{id}` — löschen.
- `POST /api/admin/pages/{id}/blocks` — Block-Array einer Seite setzen.
Schreibbar: `products`, `pages`, `slides`, `popups`, `settings`. Nur lesbar: `orders`, `customers`. Preise in Cent.
```bash
curl -H "Authorization: Bearer $HDC_API_TOKEN" https://shop.example.com/api/admin/products
curl -H "Authorization: Bearer $HDC_API_TOKEN" -X POST https://shop.example.com/api/admin/products \
-H 'Content-Type: application/json' -d '{"name":"Neues Produkt","priceCents":1990,"category":"Test"}'
```
## MCP-Server
Unter `mcp/` liegt ein eigenständiger **Model-Context-Protocol-Server** (stdio), mit dem ein LLM/Agent den Shop über die Admin-API bearbeitet. Tools u. a.: `list_products`, `upsert_product`, `get_page`, `update_page_blocks`, `list_orders`, `update_settings`, `create_page`. Installation, ENV (`HDC_BASE_URL`, `HDC_API_TOKEN`) und Registrierung in Claude/Cowork: siehe [`mcp/README.md`](mcp/README.md).
## Docker / Coolify
```bash
docker build -t hd-commerce .
docker run -p 4321:4321 -v hdc-data:/data \
-e ADMIN_EMAIL=admin@example.com -e ADMIN_PASS=geheim \
-e SESSION_SECRET=langes-geheimnis -e HDC_API_TOKEN=token hd-commerce
```
Das `Dockerfile` (node:22-slim) baut `better-sqlite3` nativ, legt `/data` an und setzt `DB_PATH=/data/hdc.db`. Auf Coolify ein persistentes Volume auf `/data` mounten. HEALTHCHECK prüft `/`.
## Datenmodell
`settings` (inkl. Feature-Flags & `payment_provider`), `products` (inkl. `mwst` / `base_amount` / `base_unit` / `base_price_per`), `orders` (inkl. `discount_code`/`discount_cents`, `tax_cents`/`shipping_cents`/`country`, `payment_provider`/`payment_id`), `customers`, `slides`, `pages` (inkl. `blocks`; System-Seite `404`), `popups` (inkl. `style` / `discount_id`), `discounts`, `discount_redemptions`, `shipping_zones`, `email_log`, `subscribers`, `events`, `media`, `users`, `audit` — alles seed-bar und im Admin pflegbar.
---
> **Hinweis:** „Brittas Nähkiste" ist nur die mitgelieferte Demo-Instanz. Brand (Name, Farben, Texte) ist über **Admin → Einstellungen** anpassbar.
Lizenz: MIT (siehe `LICENSE`).