# 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/.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://` 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/.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://` (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_FROM` — **eine** 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:///` + `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:///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:/// # Storefront 200 curl -fsS -o /dev/null -w "%{http_code}\n" https:/// # Login 200 curl -fsS -o /dev/null -w "%{http_code}\n" https:///api/admin -H "Authorization: Bearer $HDC_API_TOKEN" curl -fsS -o /dev/null -w "%{http_code}\n" -I https:/// # 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/.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 |