v2: Session-Login & Rollen, Premium-Admin, Visual-Block-Builder, KI-/MCP-API

- Auth-Umbau: Session-Login (signiertes HMAC-Cookie, scrypt-Hashing) statt Basic-Auth;
  users-/audit-Tabellen, Initial-Owner aus ENV, Rate-Limit, konfigurierbarer ADMIN_PATH
  (Middleware-Rewrite), Rollen-Gate (owner/redaktion/versand), Nutzerverwaltung, Audit-Log,
  Login/Logout/Konto-Seiten.
- Premium-Pass: Command-Palette (Cmd-K), Toasts, Account-Menue, aufgewertetes Dashboard
  (KPI-Trend+Sparkline, Aktivitaets-Feed, Schnellaktionen), schoene Empty-States.
- Block-Builder: pages.blocks, Vollbild-Editor (Liste/Live-Vorschau/Settings, Desktop/Mobil),
  10 Block-Typen, Storefront-BlockRenderer auf /seite/[slug], Save-Endpoint.
- KI-Editierbarkeit: token-gesicherte /api/admin/* (CRUD), Manifest /api/admin + /ai-admin.txt,
  MCP-Server unter mcp/ (14 Tools).
- Docs: README + .env.example + mcp/README aktualisiert.
This commit is contained in:
2026-06-17 12:46:31 +00:00
parent 3c48b69880
commit aec179db36
41 changed files with 9525 additions and 143 deletions
+55 -15
View File
@@ -1,28 +1,40 @@
# 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), Shopify-artigem Admin, JSON-API und einem schlanken, neutralen Demo-Storefront.
**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 mit Kategorie-Filter; Produktdetailseiten; Warenkorb (localStorage); Checkout; Rechts-/Inhaltsseiten aus der DB.
- **Admin** (Shopify-Stil): Dashboard mit KPIs & Funnel, Bestellungen mit Status-Workflow, Produkt-Editor (CRUD), Kunden, eigene Analytics (First-Party, Chart.js), Marketing (Popups & Announcement-Bar), Inhalte (Seiten, Slider, Medien-Upload) und Einstellungen.
- **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/`).
- **Engine**: synchron via `better-sqlite3` (WAL), automatisches Seeding beim ersten Start.
- **API**: `/api/checkout` (Stripe Hosted Checkout oder Demo-Fallback), `/api/track`, `/api/subscribe`, `/api/upload`, `/uploads/[file]`.
- **First-Party-Analytics**: eigene `events`-Tabelle, kein externer Dienst, keine personenbezogenen Rohdaten (Session = täglich rollender Hash aus IP+UA+Tag).
- **Branding konfigurierbar**: Shop-Name, Akzentfarbe, Währung u. a. in einer `settings`-Tabelle; Akzentfarbe wird als CSS-Variable in Storefront **und** Admin injiziert.
- **Self-hosted Fonts** (Fraunces + Public Sans), kein Google-CDN.
- **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_USER` | Basic-Auth-Benutzer für `/admin` | `admin` |
| `ADMIN_PASS` | Basic-Auth-Passwort für `/admin` | `admin` |
| `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 (`sk_test_…`/`sk_live_…`). Ohne echten Key läuft der Demo-Checkout. | |
| `STRIPE_SECRET_KEY` | Stripe Secret Key. Ohne echten Key läuft der Demo-Checkout. | |
Siehe `.env.example`.
@@ -30,27 +42,55 @@ Siehe `.env.example`.
```bash
npm install
npm run dev # Entwicklungsserver auf http://localhost:4321
npm run dev # http://localhost:4321
# oder produktiv:
npm run build
node ./dist/server/entry.mjs
```
Storefront: `/` · Admin: `/admin` (Standard `admin` / `admin`).
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_USER=admin -e ADMIN_PASS=geheim hd-commerce
-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, damit Datenbank und Uploads erhalten bleiben. HEALTHCHECK prüft `/`.
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`, `products`, `orders`, `customers`, `slides`, `pages`, `popups`, `subscribers`, `events`, `media` — alles seed-bar und im Admin pflegbar.
`settings`, `products`, `orders`, `customers`, `slides`, `pages` (inkl. `blocks`), `popups`, `subscribers`, `events`, `media`, `users`, `audit` — alles seed-bar und im Admin pflegbar.
---