b2in/dev/2026-08-28/preview-deployment.md
Kevin Adametz a52347845e Abstimmungsrunde 03.09.: CABINET-Seite, korrigierte Markentexte, Galerie-Hinweise, Abschluss-CTA
Setzt die vier Punkte aus dev/2026-08-28/umsetzung-03-09-2026.md um.

1. Markenseiten
   - Rotpunkt und Febrü auf die korrigierten Fassungen (*_FINAL.md) gebracht:
     bei Rotpunkt sind die beiden Nachhaltigkeitsabschnitte zusammengefuehrt,
     bei Febrü behaelt der Blaue-Engel-Satz seinen Produktbezug ohne den
     erklaerenden Zusatz.
   - CABINET nach demselben Muster neu verfasst: 8 Abschnitte, 3 Vertiefungen,
     eigener Abschlussblock und eigene Widget-Beschriftung. Bewusst ohne Zahlen,
     Zertifizierungen oder Herstelleraussagen – dafuer gibt es keine Quelle.
     Braucht Marcels Freigabe.
   - Febrü-Claim korrigiert: „Arbeiten, wo man gerne bleibt.“

2. „BEISPIEL“-Vermerk aus den Bildunterschriften entfernt. Weil die Demobilder
   auf Vorschau und Live bereits in der Datenbank stehen, entfernt
   BrandGalleryCaptionNormalizerSeeder ihn dort in-place – nur der Text, Bild,
   Kategorie und Reihenfolge bleiben unberuehrt.

3. Hinweise zu Visualisierungen neu formuliert (Markengalerie und /referenzen).
   Die Trennung bleibt, sie laeuft nur nicht mehr ueber eine Verneinung.

4. Abschluss-CTA der Markenseiten ueberarbeitet: weiche Lichtflaechen statt
   Vollton, gesetzter Hauptbutton mit Pfeil, Herstellerseite als gleichwertiger
   Outline-Button, Showroom als Fusszeile.

Ein Pruefskript hat jeden veroeffentlichten Satz gegen die abgestimmten
Markdown-Fassungen gehalten: keine Abweichung.

Tests: 859 gruen (3180 Assertions), Pint sauber, npm run build:b2in gebaut.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 09:17:16 +00:00

336 lines
11 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.

# Vorschau-Instanz auf dem Live-Server einrichten
**Ziel:** `https://preview.b2in.eu` zeigt den neuen Stand zur Abstimmung. **Die Live-Seite bleibt
unangetastet** – es wird keine einzige Datei im Live-Verzeichnis überschrieben und keine Zeile in
der Live-Datenbank geändert.
**Prinzip:** zweites, eigenständiges Verzeichnis · eigene `.env` · eigene Datenbank.
```
/var/www/b2in/ ← Live, bleibt wie es ist
/var/www/b2in-preview/ ← Kopie davon, darauf das Update
```
> Pfade unten sind Beispiele. Ersetze `/var/www/b2in` durch das echte Live-Verzeichnis und
> `b2in_live` / `b2in_preview` durch die echten Datenbanknamen.
---
## 0. Warum nicht einfach die Live-Dateien tauschen
Zwei Gründe, die diesen Aufwand rechtfertigen:
1. **Der Relaunch-Seeder überschreibt CMS-Sektionen.** `InteriorRelaunchCmsSeeder` schreibt 23
Sektionen mit den neuen Texten. Auf der Live-Datenbank ausgeführt wäre der alte Stand weg.
2. **Migrationen sind nicht umkehrbar.** `cms_brands` und die beiden Spalten `summary` /
`highlights` kommen neu dazu.
Mit einer eigenen Datenbank kann beim Testen nichts passieren, was die Live-Seite betrifft.
---
## 1. Voraussetzungen
- [ ] DNS-Eintrag `preview.b2in.eu` → dieselbe Server-IP wie `b2in.eu`
- [ ] SSL-Zertifikat für die Subdomain (Let's Encrypt genügt)
- [ ] vhost mit `DocumentRoot /var/www/b2in-preview/public`
- [ ] Zweite MySQL-Datenbank plus Benutzer
- [ ] Genug Plattenplatz für eine Kopie des Live-Verzeichnisses (vor allem `storage/`)
---
## 2. Sicherung ziehen
Auch wenn wir live nichts anfassen – der Dump ist zugleich die Grundlage für die Vorschau-DB.
```bash
cd /var/www/b2in
mysqldump -u USER -p b2in_live > ~/b2in_live_$(date +%F_%H%M).sql
ls -lh ~/b2in_live_*.sql # Größe prüfen, darf nicht 0 sein
```
---
## 3. Vorschau-Verzeichnis anlegen
Kopie des Live-Standes, **inklusive `vendor/`**. Das erspart ein `composer install` auf dem
Server – für `livewire/flux-pro` bräuchte es sonst die Zugangsdaten aus `auth.json`.
```bash
cp -a /var/www/b2in /var/www/b2in-preview
cd /var/www/b2in-preview
# Laufzeit-Reste der Kopie entfernen
rm -rf bootstrap/cache/*.php
rm -f public/storage # Symlink wird in Schritt 7 neu gesetzt
```
**Zu `storage/app/public` (Medienbibliothek, Display-Videos):** Durch `cp -a` liegt eine echte
Kopie in der Vorschau – sauber getrennt, kostet aber den Speicherplatz. Wenn das zu groß ist:
```bash
rm -rf storage/app/public
ln -s /var/www/b2in/storage/app/public storage/app/public
```
⚠️ Mit dem Symlink landen **Uploads aus der Vorschau in den Live-Dateien**. Zum Anschauen in
Ordnung, zum Testen von Uploads nicht. Im Zweifel kopieren.
---
## 4. `.env` der Vorschau anpassen
Der wichtigste Schritt. Der `ThemeServiceProvider` sucht den aufgerufenen Host in
`config/domains.php` und setzt `URL::forceRootUrl()` samt Asset-Origin auf die dort hinterlegte
URL. Fehlt `DOMAIN_B2IN_URL`, greift der Vorgabewert **`https://b2in.test`** – eine Domain, die es
im Internet nicht gibt. Dann laden Bilder, Favicon und `livewire.min.js` nicht mehr.
```bash
cd /var/www/b2in-preview
nano .env
```
Diese Werte ändern:
```dotenv
APP_ENV=preview
APP_DEBUG=false
APP_URL=https://preview.b2in.eu
APP_DOMAIN_NAME=preview.b2in.eu
# Vorschau-Domain, damit Routing, Links und Assets stimmen
DOMAIN_B2IN=preview.b2in.eu
DOMAIN_B2IN_URL=https://preview.b2in.eu
# Assets ebenfalls auf die Vorschau-Domain, sonst laedt der Browser sie von woanders
ASSET_URL=https://preview.b2in.eu
# Eigene Datenbank
DB_DATABASE=b2in_preview
DB_USERNAME=…
DB_PASSWORD=…
# Eigener Cache-/Session-Namensraum, damit sich Live und Vorschau nicht ins Gehege kommen
CACHE_PREFIX=b2in_preview
SESSION_COOKIE=b2in_preview_session
# Keine Mails aus der Vorschau verschicken
MAIL_MAILER=log
```
`APP_ENV=preview` sorgt automatisch für `noindex, nofollow` in jeder Seite
(`config/app.php` → `app.indexable`). Wer ganz sichergehen will, setzt zusätzlich
`SITE_INDEXABLE=false`.
**Nicht ändern:** `APP_KEY` – sonst sind verschlüsselte Werte in der kopierten Datenbank
nicht mehr lesbar.
---
## 5. Datenbank der Vorschau befüllen
```bash
mysql -u USER -p -e "CREATE DATABASE b2in_preview CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;"
mysql -u USER -p b2in_preview < ~/b2in_live_JJJJ-MM-TT_HHMM.sql
```
Gegenprobe, dass die Vorschau wirklich auf ihrer eigenen DB steht:
```bash
cd /var/www/b2in-preview
php artisan tinker --execute="echo config('database.connections.mysql.database');"
# muss b2in_preview ausgeben – wenn hier b2in_live steht: STOPP
```
---
## 6. Update einspielen
Das Archiv `dev/2026-08-28/deploy/b2in-interior-update.tar.gz` enthält genau die geänderten und
neuen Dateien plus die gebauten Assets (`public/build/b2in`, `public/build/portal`). **Node wird
auf dem Server nicht gebraucht.** Die enthaltene Dateiliste steht in `deploy/dateiliste.txt`.
```bash
# Archiv hochladen, dann:
cd /var/www/b2in-preview
tar xzf ~/b2in-interior-update.tar.gz
```
Das Archiv enthält bewusst **keine** `.env`, kein `vendor/` und nichts aus `storage/`.
---
## 7. Artisan-Schritte
```bash
cd /var/www/b2in-preview
php artisan config:clear
php artisan storage:link
php artisan migrate --force # legt cms_brands an, ergänzt summary/highlights
# Kernmarken anlegen – überschreibt nichts, was schon gepflegt ist
php artisan db:seed --class=CmsBrandSeeder --force
# Die neuen Texte ins CMS: genau die 23 umgetexteten Sektionen
php artisan db:seed --class=InteriorRelaunchCmsSeeder --force
# Magazin: die zwei neuen Beiträge plus Reihenfolge
php artisan db:seed --class=CmsArticleSeeder --force
# Markenseiten CABINET, Rotpunkt und Febrü – nur Textfelder, Bilder und Galerie bleiben
php artisan db:seed --class=BrandPageTextSeeder --force
# Entfernt den Vermerk „BEISPIEL – “ aus vorhandenen Bildunterschriften (Nachtrag 5).
# Nur nötig, wenn die Demogalerien schon eingespielt sind. Mehrfach ausführbar.
php artisan db:seed --class=BrandGalleryCaptionNormalizerSeeder --force
# Display-Branding auf das Interior-Logo
php artisan db:seed --class=DisplayInteriorBrandingSeeder --force
# Medien-URLs host-unabhängig (sonst zeigen vier Playlists auf b2in.test)
php artisan db:seed --class=DisplayMediaUrlNormalizerSeeder --force
php artisan config:cache
php artisan route:cache
php artisan view:clear
```
**Optional, nur für die Abstimmung:** Beispielbilder in die Markengalerien, damit Galerie,
Referenzen-Seite und Lightbox nicht leer sind.
> ⚠️ Es sind Stockmotive und KI-Renderings, kein einziges echtes Projekt. Der frühere Vermerk
> „BEISPIEL" in der Bildunterschrift ist auf Kundenwunsch entfallen – die Bilder der Rubrik
> „Realisiertes Projekt" geben sich damit als echte Referenzen aus. Für die Abstimmung in
> Ordnung, **vor dem Livegang zwingend ersetzen**.
```bash
php artisan db:seed --class=DemoBrandGallerySeeder --force
```
Wieder entfernen:
```bash
php artisan tinker --execute="App\Models\CmsBrand::query()->update(['gallery' => null]);"
```
---
## 8. Vorschau abschirmen
**Suchmaschinen** – `noindex` kommt schon aus `APP_ENV=preview`, die `robots.txt` gehört
zusätzlich umgestellt:
```bash
printf 'User-agent: *\nDisallow: /\n' > /var/www/b2in-preview/public/robots.txt
```
**Passwortschutz** (empfohlen, damit die Vorschau nicht zufällig gefunden wird):
```bash
htpasswd -c /etc/apache2/.htpasswd-preview vorschau
```
Apache:
```apache
<Directory /var/www/b2in-preview/public>
AuthType Basic
AuthName "B2in Vorschau"
AuthUserFile /etc/apache2/.htpasswd-preview
Require valid-user
</Directory>
```
Nginx:
```nginx
auth_basic "B2in Vorschau";
auth_basic_user_file /etc/nginx/.htpasswd-preview;
```
---
## 9. Prüfen
| Seite | Erwartung |
|---|---|
| `/` | Hero → Marken-Teaser → Vision → Sponsoring → Showroom-Display → Immobilien → CTA |
| `/marken` | Grauer Seitenkopf mit Bild, drei gerahmte Markenblöcke |
| `/marken/cabinet` | Detailseite, Galerie mit den zwei Rubriken (falls Demo-Seeder lief) |
| `/marken/rotpunkt` | Neun Abschnitte, vier davon mit aufklappbarer Vertiefung; Button unten rechts heißt „Persönliche Küchenberatung vereinbaren" |
| `/marken/februe` | Elf Abschnitte, Zitat von Marcel; Button heißt „Persönliche Arbeitsplatzberatung vereinbaren" |
| `/referenzen` | Realisierte Projekte, darunter das Showroom-Display im Hochformat |
| `/magazin` | Die zwei Interior-Beiträge stehen oben |
| `/faq` | Rubriken „Für Ihr Zuhause" und „Für Projekte und Objekte" |
| `/about` | Werte: Beratung statt Verkauf, Maßarbeit, … |
| `/contact` | Betreffliste beginnt mit Beratungstermin |
| `/immobilien` | unverändert |
Und diese vier Punkte:
- [ ] Terminanfrage-Widget unten rechts öffnet sich, Absenden zeigt die Bestätigung
- [ ] Alle Links bleiben auf `preview.b2in.eu` – **springt einer auf `b2in.eu`, stimmt Schritt 4 nicht**
- [ ] Seitenquelltext enthält `<meta name="robots" content="noindex, nofollow">`
- [ ] Die Live-Seite `https://b2in.eu` sieht unverändert aus
---
## 10. Aufräumen
Vorschau wieder abbauen:
```bash
rm -rf /var/www/b2in-preview
mysql -u USER -p -e "DROP DATABASE b2in_preview;"
# vhost und DNS-Eintrag entfernen
```
Beim späteren echten Livegang gilt **Abschnitt 8 des Entwicklungsplans**, nicht dieses Dokument.
Vorher offen: Rechtstexte, OG-Bild, Seeder-Passwort rotieren.
---
## Wenn etwas nicht stimmt
| Symptom | Ursache |
|---|---|
| **„Kein Server mit dem angegebenen Hostnamen gefunden" für Bilder, Favicon, `livewire.min.js`** | `DOMAIN_B2IN_URL` fehlt oder ist falsch geschrieben → Vorgabewert `https://b2in.test`. Siehe Diagnose unten. |
| Links springen auf `b2in.eu` | `DOMAIN_B2IN` / `DOMAIN_B2IN_URL` in Schritt 4 nicht gesetzt, oder `config:cache` fehlt |
| Seite ohne Styles | `public/build/b2in` fehlt – Archiv nicht vollständig entpackt |
| „Vite manifest not found" | dasselbe, oder `build/portal` fehlt für das Admin-Panel |
| Bilder fehlen | `php artisan storage:link` vergessen, oder `storage/app/public` nicht mitkopiert |
| Display-Kachel bleibt leer | Kein aktives Display mit veröffentlichter Playlist – dann wird die Sektion bewusst gar nicht angezeigt |
| Änderungen wirken nicht | `php artisan config:clear && php artisan config:cache` |
### Diagnose: Assets zeigen auf den falschen Host
```bash
cd /var/www/b2in-preview
# 1. Was steht in der .env?
grep -E '^(APP_ENV|APP_URL|APP_DOMAIN_NAME|ASSET_URL|DOMAIN_B2IN|DOMAIN_B2IN_URL)=' .env
# 2. Was macht die Anwendung daraus? (zeigt den zwischengespeicherten Stand)
php artisan tinker --execute="echo config('domains.domains.b2in.domain_name').' -> '.config('domains.domains.b2in.url').PHP_EOL;"
# 3. Liegt ein alter Config-Cache herum?
ls -l bootstrap/cache/config.php 2>/dev/null
```
Steht in Zeile 2 etwas mit `.test`, fehlen die beiden `DOMAIN_B2IN*`-Zeilen. Beheben:
```bash
cd /var/www/b2in-preview
php artisan config:clear # zuerst den Cache weg, sonst wirkt die .env nicht
nano .env # DOMAIN_B2IN, DOMAIN_B2IN_URL, ASSET_URL, APP_URL setzen
php artisan config:cache
php artisan view:clear
```
**Sicherheitsnetz seit dieser Runde:** Findet der `ThemeServiceProvider` den aufgerufenen Host
nicht in der Konfiguration, verwendet er außerhalb von `APP_ENV=production` den tatsächlich
aufgerufenen Origin – die Vorschau verlinkt sich dann auf sich selbst statt auf eine fremde
Domain. In `production` bleibt es bei der konfigurierten URL, damit ein gefälschter Host-Header
keine Links auf fremde Domains erzeugen kann. Die `.env` sollte trotzdem stimmen.