# Buchungskalender – Livegang Reihenfolge für den Inhaber. Jeder Schritt braucht seine Freigabe; nichts davon hat Claude gegen Produktion, das Live-Stripe-Konto oder die Website Donau Home ausgeführt. Code: Portal `feature/unterkunft`, WOMS `feature/unterkunft`. Erste Kundin ist Mimi (Donau Home, MIMI FEWO, Website `WEBklar/donau-home`, lokaler Klon `/root/reports/donau-home-website`). **Wichtig beim Pushen:** Den Feature-Zweig nie unter seinem eigenen Namen pushen. Der Portal-Webhook deployt jeden Zweig. Immer mit Zielzweig: - Portal: `git push origin feature/unterkunft:main` - WOMS: `git push origin feature/unterkunft:test` ## 0. Voraussetzung - TP2, Webshop und Öffnungszeiten-Zweig liegen schon auf `origin/main` (Portal) bzw. `test` (WOMS) oder werden vorher gemerged: Das Funktionen-Register, die Mail-Warteschlange (`termineOutbox`) und die Connect-Anbindung stammen von dort. `git merge origin/main` im Worktree, Tests laufen lassen. Erwartbare Konflikte: `server/config.js` (features), `public/funktionen.js`, `test/mailTemplates.test.js` (Vorlagen-IDs: K31 bis K34, G16 bis G22, T22 sind für den Buchungskalender vergeben, vor dem Merge gegen `main` prüfen). - Die Rechtstexte der Fassung 2026-10-07 liegen als HTML und PDF im Zweig (`public/rechtliches/*-2026-10-07.*`, siehe Schritt 6). ## 1. Inhaber prüft die Texte Vom Inhaber freizugeben, bevor irgendetwas live geht: - `docs/rechtliches/leistungsbeschreibung-unterkunft.md` und `avv-unterkunft.md` (beide „Entwurf – Prüfung durch Kanzlei offen“), - `docs/rechtliches/unterkunft-datenschutz-6f-entwurf.md`, - `docs/funktionen/unterkunft-datenschutz-absatz.md` und `unterkunft-storno-muster.md`, - `docs/rechtliches/unterkunft-kanzlei-fragen.md` (Fragen U1 bis U12 für die Kanzlei). **Achtung Widerrufsbelehrung:** Die Datei `widerrufsbelehrung-funktionen-2026-10-07.*` ist eine Kopie des gemeinsamen Textes der Funktionen (Quelle `docs/rechtliches/widerrufsbelehrung-funktionen.md`). Ändert sich dieser Text (neue Fassung beim Terminplaner oder Webshop), braucht der Buchungskalender eine neue Fassung mit neuem Datum; eine ausgelieferte Datei wird nie an Ort und Stelle neu gebaut. Ändert sich ein Text, gibt es eine neue Fassung (neues Datum in `config.unterkunft.fassung` und im Zustimmungs-Pin der Bestelltexte); ausgelieferte Fassungen werden nie überschrieben. ## 2. Datenbank (vor dem Deploy) Zuerst die Datenbank, dann der Schalter (Livegang-Reihenfolge aus `docs/funktionen/unterkunft-api.md`). Reihenfolge der Skripte: erst `termine-setup.mjs --check` und anwenden (Attribut `anhang`), dann `unterkunft-setup.mjs`: ```bash cd /home/webklar/apps/kundenbereich.webklar.com/build docker exec -w /app webklar-kundenbereich-server node scripts/termine-setup.mjs --check docker exec -w /app webklar-kundenbereich-server node scripts/termine-setup.mjs # zieht das Attribut anhang der Mail-Warteschlange nach (Rechnung als Anhang) docker exec -w /app webklar-kundenbereich-server node scripts/unterkunft-setup.mjs --check docker exec -w /app webklar-kundenbereich-server node scripts/unterkunft-setup.mjs # legt ukUnterkuenfte, ukPreise, ukSperren, ukAnfragen, ukRechnungen, ukEinstellungen samt Indizes an ``` Die Skripte müssen aus dem neuen Code laufen (nach Schritt 5 oder vorher aus dem Worktree mit derselben Umgebung). `termine-setup.mjs` ändert nichts an vorhandenen Daten, es fügt nur fehlende Attribute und Indizes hinzu. ## 3. Stripe-Preis ```bash docker exec -w /app webklar-kundenbereich-server node scripts/stripe-products.mjs --pruefen docker exec -w /app webklar-kundenbereich-server node scripts/stripe-products.mjs --anlegen # legt unterkunftSetup (199 €, Lookup-Key webklar_unterkunft_einrichtung_19900) an docker exec -w /app webklar-kundenbereich-server node scripts/stripe-products.mjs --pruefen # Preis-Lookup nach --anlegen prüfen ``` Der vorhandene Connect-Webhook (`https://project.webklar.com/api/shop/stripe-webhook`) bleibt unverändert; er leitet nach dem Metadatum `wkUk` an den Buchungskalender weiter. Kontrolle im Stripe-Dashboard: Die Ereignisse `account.updated`, `checkout.session.completed`, `checkout.session.async_payment_succeeded`, `checkout.session.async_payment_failed`, `checkout.session.expired` und `charge.refunded` sind schon eingetragen (Webshop-Livegang). ## 4. Server-Konfiguration (Pilot) Sicherungen zuerst: `cp /home/webklar/apps/docker-compose.yml /home/webklar/apps/docker-compose.yml.bak-2026-10-07-unterkunft` und `(umask 077; cp /home/webklar/apps/.env /home/webklar/apps/.env.bak-2026-10-07-unterkunft)` (`.env` enthält Zugangsdaten). In `/home/webklar/apps/.env`: ``` UNTERKUNFT_ENABLED=pilot UNTERKUNFT_PILOT_EMAILS=kenso.gri@gmail.com, ``` In `/home/webklar/apps/docker-compose.yml` beim Dienst `kundenbereich-server` neben `ZEITEN_ENABLED` und `SHOP_ENABLED` zwei Zeilen: ``` - UNTERKUNFT_ENABLED=${UNTERKUNFT_ENABLED:-off} - UNTERKUNFT_PILOT_EMAILS=${UNTERKUNFT_PILOT_EMAILS:-} ``` Prüfen mit `docker compose -f /home/webklar/apps/docker-compose.yml config -q` (keine Ausgabe = gültig), dann übernehmen mit `docker compose -f /home/webklar/apps/docker-compose.yml up -d --no-deps kundenbereich-server`. Ein bloßes `docker restart` liest neue Umgebungswerte nicht. Das alles vor dem Push (Schritt 5): Der Container läuft dann mit dem alten Code und den neuen Werten (die kennt er nicht, harmlos), und der Neustart durch den Deploy nach dem Push ist der einzige mit dem neuen Code. Rückweg: `UNTERKUNFT_ENABLED=off`, Compose neu anwenden; das Schema ist rein additiv, es gibt nichts zurückzubauen. ## 5. Push (durch den Inhaber) - Portal: `git push origin feature/unterkunft:main` (der Webhook deployt), - WOMS: `git push origin feature/unterkunft:test`. Nie `git push origin feature/unterkunft` (eigener Name). Danach prüfen: `https://project.webklar.com/embed/unterkunft.js` antwortet 200; `https://project.webklar.com/rechtliches/leistungsbeschreibung-unterkunft.html` und `…/avv-unterkunft.html` antworten 200. ## 6. Rechtstexte in WOMS „Rechtliches“ hochladen (macht Claude) Das macht Claude selbst (Wunsch des Inhabers). Dafür legt der Inhaber vorher den **kurzlebigen** Appwrite-Schlüssel mit dem Recht für Rechtliches unter `/root/.appwrite-rechtliches.key` ab und löscht ihn danach. Claude legt (falls nötig, `scripts/setup-legal.mjs` im WOMS) die Karten „Leistungsbeschreibung Buchungskalender“ und „AVV Buchungskalender“ an und lädt die Fassung 2026-10-07 hoch: - `public/rechtliches/leistungsbeschreibung-unterkunft-2026-10-07.pdf` - `public/rechtliches/avv-unterkunft-2026-10-07.pdf` (Die Widerrufsbelehrung `widerrufsbelehrung-funktionen-2026-10-07.pdf` ist ein Anhang der Bestellmail und der Bestellseite; sie ist inhaltlich die der Funktionen.) ## 7. Mimi freischalten und Donau Home einbauen 1. WOMS → Kunde (Mimi) → Funktionen → Buchungskalender → **„Aktivieren (ohne Zahlung)“** (`action: 'activate'`; der Weg für Kunden, die die Funktion als Teil ihres Projekts bekommen; Pilot-Adressen brauchen keine Textform). 2. Mimi richtet im Portal ein: Unterkünfte, Preise, Stornobedingungen (Muster `docs/funktionen/unterkunft-storno-muster.md`), Firmendaten, Steuerart, optional Stripe; mit dem Team zusammen. 3. **siteKey in Donau Home:** den `siteKey` aus dem Ticket oder dem WOMS in `/root/reports/donau-home-website/index.html` im Abschnitt `#anfrage` einsetzen (`data-webklar-unterkunft="SITEKEY"`), das Skript `https://project.webklar.com/embed/unterkunft.js` einbinden, CSS-Variablen (`--wku-*`) auf Palette A (Eiche & Leinen) und Schrift Figtree stellen, den Datenschutz-Absatz in die Datenschutzerklärung der Website einfügen, den Einleitungstext anpassen. Einbau nach `docs/funktionen/unterkunft-einbau.md`. 4. Donau Home pushen (Inhaber, nicht Claude); die Vorschau zeigt das Widget, solange `UNTERKUNFT_ENABLED=pilot` mit Mimis siteKey läuft. ## 8. Pilot mit Mimi 1. Testanfrage im Widget (eigene Adresse): Mails G16 und K31 prüfen. 2. Im Portal freigeben (G17), Buchungslink öffnen, „vor Ort“ buchen (G19 mit Rechnung als PDF, K32). 3. Rechnung prüfen: Mimis Name und Anschrift, Steuernummer oder USt-ID, Nummer lückenlos, Steuerart, kein WEBklar-Hinweis. 4. Mit Stripe-Konto: Online-Zahlung mit kleinem Betrag testen (G20), dann stornieren mit Erstattung (G22, Stornorechnung). 5. Stornieren (Stornorechnung), Testbuchungen wieder entfernen; iCal-Import und -Export mit einem Test-Kalender prüfen. ## 9. Datenschutz § 6f übernehmen Den Abschnitt 6f aus `docs/rechtliches/unterkunft-datenschutz-6f-entwurf.md` in `public/datenschutz.html` übernehmen (hinter 6d, vor Abschnitt 7; Abschnitt 12 anpassen), danach `FORCE=1 scripts/build-legal-pdfs.sh datenschutz`. Erst mit der Freigabe des Inhabers. ## 10. Freigabe für alle - Kanzlei-Fragen (`unterkunft-kanzlei-fragen.md`) beantworten lassen, Befund einarbeiten (neue Fassung, falls sich Texte ändern; neue Texte hochladen wie in Schritt 6). - Dann `UNTERKUNFT_ENABLED=on` in `.env`, Compose neu anwenden (wie Schritt 4). ## PDFs der Rechtstexte erzeugen Die PDFs entstehen aus den HTML-Seiten auf dem Host mit Chrome (Memory prüfen, `free -m` > 1500 MB verfügbar): ```bash node --max-old-space-size=512 scripts/build-legal-html.mjs unterkunft # schreibt die HTML-Seiten node --max-old-space-size=512 scripts/build-legal-html.mjs unterkunft --check # Exit 0 = ok nice scripts/build-legal-pdfs.sh unterkunft # druckt die PDFs samt .sha256 ``` Änderst Du einen Text, HTML neu erzeugen und die PDFs neu drucken (Prüfsumme entscheidet, was neu gedruckt wird; `FORCE=1` druckt alle neu).