Files

8.7 KiB

HANDOVER — hd-commerce

Betriebs- und Übergabe-Runbook für hd-commerce. Zielgruppe: wer das Produkt deployt, einen echten Kundenshop daraus ausrollt und betreibt. Ergänzt README.md (Features) und CLAUDE.md (Arbeitsregeln am Code).

Stand: v2.4 · Repo till/hd-commerce (Gitea, GitHub-Mirror siehe MIRROR.md).


1. Was übergeben wird

Ein wiederverwechselbares E-Commerce-Backend-Produkt (eine Codebasis, viele Shops). Enthalten: Storefront + Premium-Admin, Katalog mit Varianten-Matrix, Warenkorb/Checkout, Zahlung (Mollie/Stripe/Demo), Rabatt-Engine, Versandzonen + MwSt/Grundpreis (DACH), Inhalte/Block-Builder, Medienbibliothek + WebP, Kundenkonten, Bewertungen, Merkliste, Volltextsuche, Abandoned-Cart, first-party Analytics, Bestellmails (Listmonk/SMTP/Log), KI-/MCP-API, Litestream-Backups (optional).

Demo-Instanz „Brittas Nähkiste" (Beispiel, kein echter Shop):

  • App (Coolify): lbv524oul6b6mxvo95pgxgso · Server localhost (heidrich-infra-01)
  • URL: https://lbv524oul6b6mxvo95pgxgso.46.224.49.66.sslip.io
  • Admin-Pfad: /login (per ADMIN_PATH=login) · DB: /data/hdc2.db · RAM-Cap 640 MB
  • Let's-Encrypt-Zertifikat, http→https erzwungen, PUBLIC_BASE_URL=https://… gesetzt
  • Zugangsdaten: nicht hier — im 1Password/Chat. Niemals Credentials ins Repo/in Doku.

2. „Selbst gebaut" — bewusste Entscheidung

Der Eigenbau ist gerechtfertigt, weil hd-commerce ein über die Care-Abo-Basis mehrfach ausrollbares HD-Produkt ist: Datenhoheit, Tempo, Marge (keine Shopify-Gebühren), DSGVO-nativ, KI-/MCP-automatisiert. Der Preis ist dauerhafte Eigen-Wartung. Faustregeln (belegt im Portal-Research „SQLite-Eigenbau-Commerce — realistisch oder Overkill?"):

  • SQLite + Litestream ist für DACH-KMU-Shops (read-heavy Katalog, überschaubare Bestell-Schreiblast) technisch tragfähig.
  • Harte Grenze: eine Server-Maschine, ein Writer — gut bis Größenordnung ~500 aktive Nutzer/Tag; darüber Postgres auf derselben Box.
  • Für einen einzelnen 08/15-Shop ist Shopware 6 / Medusa / Snipcart+Stripe pragmatischer.
  • Postgres-Exit absichern: Datenzugriff bleibt hinter store-sqlite.js (siehe CLAUDE.md, Regel 3).

3. Neuen Kundenshop ausrollen (eine Codebasis, neue Instanz)

  1. Coolify-App anlegen (Build-Pack: Dockerfile, Branch main, Repo till/hd-commerce).
    • application create_public verwirft den Git-Host → danach application update mit voller https://till:TOKEN@git.heidrich-digital.de/till/hd-commerce.git-URL.
  2. Persistentes Volume auf /data mounten (eigener DB-Pfad je Shop, z. B. DB_PATH=/data/<kunde>.db).
  3. ENV setzen (Minimal-Set, siehe §4). SESSION_SECRET, HDC_API_TOKEN, CRON_TOKEN je Shop eindeutig und zufällig.
  4. Domain eintragen (echte Kundendomain statt sslip), Coolify zieht das Let's-Encrypt-Zertifikat; redirect: both (http→https). PUBLIC_BASE_URL=https://<domain> setzen.
  5. Deploy → danach App control restart (Altcontainer räumen) → verifizieren (§6).
  6. Branding im Admin → Einstellungen: Shop-Name, Akzentfarbe, Währung, Logo-Wortmarke, Module (Feature-Flags). Kein Code-Eingriff.
  7. Inhalte: Startseite/Seiten über den Block-Builder, Produkte + Varianten, Versandzonen, Rabatte, Popups anlegen — alles im Admin oder per KI/MCP-API.

Pro Shop unterscheidet sich nur ENV + settings + DB-Inhalt. Der Code bleibt identisch und generisch (CLAUDE.md, Leitsatz).

4. ENV — Go-Live-Checkliste

Pflicht (Minimal-Betrieb):

  • DB_PATH=/data/<kunde>.db (auf gemountetem Volume)
  • ADMIN_EMAIL + ADMIN_PASS (Initial-Owner, nur erster Boot; danach im Admin verwaltbar)
  • ADMIN_PATH (z. B. login oder intern — nicht das offensichtliche admin)
  • SESSION_SECRET (langes Zufallsgeheimnis — in Prod zwingend, sonst nur persistenter Fallback)
  • PUBLIC_BASE_URL=https://<domain> (korrigiert Proxy-Origin für Zahlungs-Return/Webhook)

Zahlung (für echten Verkauf):

  • MOLLIE_API_KEY=test_… zum Testen, dann live_… → Provider wählt automatisch Mollie. Webhook automatisch {PUBLIC_BASE_URL}/api/payments/webhook.
  • (Alternativ Stripe: STRIPE_SECRET_KEY + STRIPE_PUBLIC_KEY.) Ohne gültigen Key läuft der Demo-Checkout (kein echtes Geld).

Bestellmails (sonst nur Log-Fallback in email_log):

  • MAIL_PROVIDER=listmonk + LISTMONK_URL/USER/PASS/TX_TEMPLATE_ID + MAIL_FROMeine Listmonk-Instanz reicht für alle Shops (pro Shop Liste+Template+Absender).
  • oder MAIL_PROVIDER=smtp + SMTP_HOST/PORT/USER/PASS/SECURE.

Backup (dringend für echten Shop):

  • LITESTREAM_REPLICA_URL=s3://<bucket>/<pfad> + LITESTREAM_ACCESS_KEY_ID + LITESTREAM_SECRET_ACCESS_KEY + LITESTREAM_ENDPOINT (B2-EU). Siehe §7.

Optional:

  • HDC_API_TOKEN (KI/MCP-API; leer ⇒ API gesperrt)
  • CRON_TOKEN + Coolify-Scheduled-Task für Abandoned-Cart (§5)
  • WEBP_QUALITY / WEBP_MAX_WIDTH, ABANDONED_AFTER_MINUTES

Vollständige Referenz: .env.example + README-Tabelle.

5. Wiederkehrende Jobs

Abandoned-Cart-Erinnerung — Coolify-Scheduled-Task (z. B. alle 30 Min):

curl -fsS -X POST -H "Authorization: Bearer $CRON_TOKEN" https://<domain>/api/cron/abandoned

Schickt fälligen, nicht erinnerten Warenkörben eine Mail (Mailer/Log-Fallback) und setzt reminded=1.

6. Verifizieren nach jedem Deploy

Immer cache-bustend per curl (nicht WebFetch — cacht):

curl -fsS -o /dev/null -w "%{http_code}\n" https://<domain>/                  # Storefront 200
curl -fsS -o /dev/null -w "%{http_code}\n" https://<domain>/<ADMIN_PATH>       # Login 200
curl -fsS -o /dev/null -w "%{http_code}\n" https://<domain>/api/admin -H "Authorization: Bearer $HDC_API_TOKEN"
curl -fsS -o /dev/null -w "%{http_code}\n" -I https://<domain>/                # http→https-Redirect prüfen

Erwartung: Storefront/Login 200, gebrandete 404 auf Unsinns-Pfad, ein Test-Checkout (Mollie-Test) bis „bezahlt".

7. Backup & Restore (Litestream)

  • Aktiv, sobald LITESTREAM_REPLICA_URL gesetzt ist: der Container streamt DB_PATH live nach S3/B2 und stellt beim Start bei Bedarf wieder her. Ohne die Variable: normaler Node-Start ohne Backup.
  • Status sichtbar unter Admin → Einstellungen → Backup (Litestream).
  • Disaster-Recovery / Restore (neue Instanz, leeres Volume): erfolgt beim Start automatisch. Manuell:
    litestream restore -config /app/litestream.yml -if-replica-exists /data/<kunde>.db
    
  • B2-Empfehlung: Bucket in EU (s3.eu-central-003.backblazeb2.com), Application-Key mit Schreibrechten, pro Shop eigener Pfad/Bucket.

8. Wartung / Care-Abo

  • Updates: Änderungen am Produkt-Repo main; pro Kundenshop neu deployen + restart + verifizieren (§6). Migrationen laufen idempotent beim Boot — kein manueller DB-Schritt.
  • Monitoring: Coolify-Healthcheck (/), App-Logs (application_logs). RAM-Cap je Shop setzen (Demo: 640 MB) — heidrich-infra-01 hat 8 GB ohne Swap, also nicht überbuchen.
  • npm test muss grün sein, bevor neuer Code nach main geht (Geld/Versand/Rabatt/Sanitizer).
  • Logs/Audit: Admin → Aktivität (Audit) protokolliert Create/Update/Delete; E-Mail-Log unter Einstellungen.

9. Sicherheit (Betreiber-Pflichten)

  • SESSION_SECRET, HDC_API_TOKEN, CRON_TOKEN je Shop eindeutig und geheim (nur ENV).
  • ADMIN_PATH nicht auf admin lassen. Rollen sparsam vergeben (owner/redaktion/versand).
  • Roh-HTML in Inhalten läuft durch sanitizeHtml() — trotzdem nur vertrauenswürdigen Redakteuren html-Blöcke erlauben.
  • Vor produktivem Verkauf: /engineering:security-review-Pass einplanen.

10. Reife-Status & offene Punkte (vor echtem, zahlendem Shop)

Funktional auf dem Niveau eines kleinen Shopify/Woo-Shops. Noch betrieblich zu erledigen (keine Features):

  • Mollie live-Key getestet (Test-Checkout bis „bezahlt", Webhook setzt Bestellung auf bezahlt + Mail).
  • Litestream mit echten Backblaze-B2-Zugangsdaten scharf geschaltet + ein Restore geprobt.
  • Echte Rechtstexte: Impressum, Datenschutz, AGB, Widerruf + Cookie/Consent (DSGVO/BFSG).
  • Listmonk/SMTP angebunden, damit Bestellmails real rausgehen (statt Log-Fallback).
  • Security-Review-Pass vor Verkaufsstart.

11. Schnellreferenz

Sache Wert
Repo https://git.heidrich-digital.de/till/hd-commerce (Branch main)
Demo-App (Coolify) lbv524oul6b6mxvo95pgxgso
Demo-URL https://lbv524oul6b6mxvo95pgxgso.46.224.49.66.sslip.io
Demo-Admin /login (ADMIN_PATH=login)
Demo-DB /data/hdc2.db (Volume), RAM 640 MB
Port / Volume 4321 / /data
Tests npm test
Nach Deploy App restart → §6 verifizieren