feat(privat/CV): sync to latest upstream (cv-upstream/main, 30f9608b)

This commit is contained in:
2026-07-07 15:20:55 +02:00
parent 8ac664d33d
commit a4efabbc60
417 changed files with 48564 additions and 712 deletions
+114
View File
@@ -0,0 +1,114 @@
# Deployment-Plan — andreknie.de
> Ablauf für den Produktiv-Gang. **Voraussetzung:** Die funktionalen Lücken und die 🔴-Punkte aus `SICHERHEITS-AUDIT.md` sind geschlossen.
## Architektur im Überblick
```
Internet ──HTTPS──> Caddy (Reverse Proxy, Auto-TLS)
├── /api/* ──> Express-Backend (Docker, Port 3003)
│ └── server/data/*.json (Volume)
└── /* ──> statische SPA-Dateien (/opt/andreknie/site)
```
- **Frontend:** statisches Build-Artefakt (`dist/`), von Caddy direkt ausgeliefert.
- **Backend:** Express-Container, nur für Formulare (Kontakt, Vortrag, Newsletter, Resource).
- **Datenhaltung:** JSON-Dateien im gemounteten Volume `server/data/`.
---
## Voraussetzungen (vor dem ersten Deploy)
### Funktionale Lücken geschlossen
- [ ] Confirmation-Landingpages im SPA (siehe Erläuterung unten) + Routen `/bestaetigung/...`
- [ ] Backend leitet Bestätigungs-Klick auf eine SPA-Seite weiter (statt rohem JSON)
- [ ] Security-🔴: Rate-Limiting, Honeypot, resource_id-Validierung
### Infrastruktur
- [ ] Server (VM/VPS) mit Docker + Docker Compose
- [ ] Caddy installiert (oder als Container)
- [ ] DNS: A/AAAA-Record `andreknie.de` (+ `www`) zeigt auf die Server-IP
- [ ] Ports 80 + 443 offen (für Let's Encrypt / TLS)
- [ ] SMTP-Zugangsdaten vorhanden (Versand-Postfach bei d-hive)
---
## Schritt-für-Schritt
### 1. Secrets konfigurieren
`.env` auf dem Server anlegen (nicht im Repo!):
```
PORT=3003
NODE_ENV=production
BASE_URL=https://andreknie.de
SMTP_HOST=<host>
SMTP_PORT=587
SMTP_USER=<user>
SMTP_PASS=<pass>
STAKEHOLDER_EMAIL=kontakt@d-hive.de
```
### 2. Frontend bauen
Lokal oder im CI:
```
npm ci
npm run build
```
Ergebnis: `dist/`. Inhalt nach `/opt/andreknie/site/` auf den Server kopieren (rsync/scp).
### 3. Backend starten
Auf dem Server im Projektverzeichnis:
```
docker compose up -d --build
```
- Container lauscht auf `localhost:3003`.
- Volume `./server/data` persistiert Tokens/Subscriber/Leads über Neustarts.
### 4. Caddy aktivieren
`Caddyfile` deployen, dann `caddy reload` (bzw. Container neu starten). Caddy holt automatisch das TLS-Zertifikat.
### 5. Smoke-Tests (Produktion)
- [ ] `https://andreknie.de` lädt, alle Seiten navigierbar
- [ ] `GET https://andreknie.de/api/health``{ status: "ok" }`
- [ ] Kontaktformular absenden → Bestätigungsmail kommt an
- [ ] Bestätigungslink klicken → Landingpage „bestätigt", Weiterleitung an Stakeholder kommt an
- [ ] Newsletter-Doppel-Opt-In komplett durchspielen
- [ ] Rate-Limit greift (mehrfaches Absenden → 429)
- [ ] Security-Header prüfen (z.B. securityheaders.com)
---
## Wichtige Erläuterung: die „funktionalen Lücken"
Zwei zusammenhängende Punkte, die vor dem Deploy zu klären sind:
**A) Confirmation-Landingpages.**
Aktuell zeigt die Bestätigungsmail auf den Backend-Endpunkt direkt:
`https://andreknie.de/api/contact/confirm/<token>`. Klickt der Nutzer, antwortet Express mit **rohem JSON** (`{ ok: true, ... }`) — keine gestaltete Seite. Für eine saubere UX braucht es:
1. Eine SPA-Seite (z.B. `/bestaetigung`) mit Erfolg-/Abgelaufen-Zustand.
2. Entweder der Backend-Endpunkt antwortet mit einem Redirect (302) auf diese SPA-Seite, oder die Mail verlinkt direkt die SPA-Seite, die dann per fetch den Token beim Backend bestätigt.
**B) ContentFilter / Pagination / SEOHead.**
Geplante, aber noch nicht gebaute Komponenten:
- *ContentFilter* — Tag-Filter für lange Listen (Kniepunkt, Posts).
- *Pagination* — Blättern bei >10 Einträgen.
- *SEOHead* — pro Seite eigene `<title>`/Meta-Tags (wichtig fürs Teilen auf LinkedIn).
Diese sind **kein harter Go-Live-Blocker**, verbessern aber Auffindbarkeit und Bedienbarkeit deutlich. Empfehlung: SEOHead vor Go-Live (wegen Social-Sharing), Filter/Pagination danach.
---
## Rollback
- Frontend: vorheriges `dist/` zurückkopieren (alte Builds versioniert aufbewahren).
- Backend: `docker compose down` + vorheriges Image-Tag starten.
- Daten: `server/data/` regelmäßig sichern (Cron + Backup off-site).
## Wartung
- [ ] Backup-Cron für `server/data/`
- [ ] Log-Rotation für Container-Logs
- [ ] `npm audit` + Dependency-Updates im Quartalsrhythmus
- [ ] Zertifikats-Erneuerung: automatisch durch Caddy (kein manueller Eingriff)