vcard4reseller/README.md
Thomas Peterson c3e05257cb Deployment: Hetzner Cloud via Terraform (Multi-Node, skalierbar)
Infrastruktur als Code für den Skalierungs-Test auf Hetzner:
- deploy/terraform: privates Netz, Firewalls, 2 App-Nodes, DB-Node, Load
  Balancer (Health-Check /health); cloud-init bootet Docker + Stack je Node
- deploy/compose/docker-compose.prod.yml + nginx.prod.conf: App-Node-Stack
  (PHP-FPM + Nginx) routet /api,/p,/t,/css,/health → Symfony, Rest → Vue-SPA
- App-Anpassungen: HealthController (/health für LB), brand.css nach /css
  verschoben (kein Pfad-Clash mit SPA-Assets im Prod-Routing)
- deploy/README.md: Anleitung inkl. JWT-Key-Verteilung & Cross-Node-Test
- reference.php (auto-generiert) aus Versionierung entfernt

Terraform validiert (terraform validate), Prod-Compose-Syntax geprüft.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-05-31 21:20:58 +02:00

120 lines
4.7 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.

# vcard4reseller
White-Label-Plattform für digitale Visitenkarten (Reseller → Firmenkunde → Mitarbeiter).
Konzept & Datenmodell: siehe [`docs/KONZEPT.md`](docs/KONZEPT.md).
## Stack
- **Backend:** Symfony 7.4 + API Platform 4.3, Doctrine ORM, LexikJWT, Messenger
- **Frontend:** Vue 3 + TypeScript (Vite), Vue Router, Pinia, Axios
- **DB:** MariaDB 11.4
- **Dev-Umgebung:** Docker (PHP-FPM, Nginx, MariaDB)
## Verzeichnisse
```
backend/ Symfony-API (JSON/JSON-LD)
frontend/ Vue-3-SPA (Dashboards)
docker/ Dockerfile (PHP) + Nginx-Config
deploy/ Hetzner-Deployment (Terraform + Prod-Compose) — siehe deploy/README.md
docs/ Konzept & Datenmodell
```
## Schnellstart
Voraussetzung: Docker + Node 25.
```bash
# 1) Backend-Stack starten (PHP, Nginx, MariaDB)
export UID=$(id -u) GID=$(id -g)
docker compose up -d php nginx mariadb
# 2) JWT-Schlüssel erzeugen (einmalig)
docker compose exec php php bin/console lexik:jwt:generate-keypair --skip-if-exists
# 3) Frontend (Dev-Server mit API-Proxy auf :8080)
cd frontend && npm install && npm run dev
```
- API: http://localhost:8080/api
- Frontend: http://localhost:5173
- MariaDB: localhost:3306 (DB `vcard4reseller`, User `app` / `app`)
### Nützliche Befehle
```bash
# Symfony-Console im Container
docker compose exec php php bin/console <cmd>
# Migration erstellen / ausführen
docker compose exec php php bin/console doctrine:migrations:diff
docker compose exec php php bin/console doctrine:migrations:migrate
```
## Status
**Phase 0 (Setup) + Phase 1 (Kern-Domäne & Auth) abgeschlossen.**
Phase 1 umfasst: Entitäten (User, PlatformPlan, Reseller, Company, Domain,
Location, Employee, ContactLink), JWT-Login (`POST /api/login`),
Rollen-Hierarchie und automatische Mandantentrennung über eine
API-Platform-Query-Extension (`src/Doctrine/TenantExtension.php`).
Demo-Daten via `docker compose exec php php bin/console app:seed`:
| Rolle | E-Mail | Passwort |
|-------|--------|----------|
| Plattform-Admin | admin@vcard4reseller.de | admin |
| Reseller-Admin | reseller@demo.de | reseller |
| Firmen-Admin | firma@muster.de | firma |
**Phase 2 (öffentliche Profile) läuft.** Bereits umgesetzt: serverseitig
gerenderte Profilseite, vCard-Download und QR-Code im Marken-Look von
vcard4reseller.de (Design-Tokens in `backend/public/assets/brand.css`,
Referenz in `docs/design-reference/`).
Öffentliche Endpunkte (kein Login):
- `GET /p/{firma}/{mitarbeiter}` — Profil-Landingpage (Twig/SSR)
- `GET /p/{firma}/{mitarbeiter}/vcard.vcf` — vCard-Download
- `GET /p/{firma}/{mitarbeiter}/qr.png` — QR-Code (codiert die stabile Kurz-URL)
- `GET /t/{code}` — stabiler NFC/QR-Kurz-Link → Redirect aufs aktuelle Profil
Beispiel (nach `app:seed`): http://localhost:8080/p/muster/erika-mustermann
**Verwaltungsoberfläche (Vue-SPA) läuft.** Echtes Login gegen `/api/login`,
rollenbasierte App-Shell (dunkle Sidebar + Topbar im Brand-Look) und live an
die API gebundene Screens:
- **Dashboard** — Kennzahlen (rollenabhängig: Reseller/Firmen/Mitarbeiter/…)
- **Reseller** — Übersicht + Anlegen inkl. Admin-Zugang (nur Plattform-Admin)
- **Firmen** — Liste + Anlegen/Löschen (Reseller)
- **Mitarbeiter** — Tabelle, Suche, Anlegen/Bearbeiten/Löschen, Link zur öffentlichen Profilseite
- **Standorte**, **Domains** — Liste + Anlegen (Domains mit A-Record-Hinweis)
- **Design** — firmenspezifisches Branding (Primärfarbe/Logo) mit Live-Vorschau
- **Einstellungen** — Platzhalter
`/api/me` liefert der SPA Rollen + Mandantenkontext.
Start: `cd frontend && npm run dev` → http://localhost:5173 (Login z. B.
reseller@demo.de / reseller).
**Druckdaten (Kerngeschäft, in Arbeit):** druckfertige Visitenkarten als PDF
(CMYK, 85×55mm + 2mm Beschnitt + Schnittmarken, Vorder-/Rückseite) — Endpunkt
`GET /api/employees/{id}/card.pdf`. Layout via `CardTemplate` (Standardvorlage
greift Firmen-Branding + QR ab). Siehe `docs/KONZEPT.md` §13.
**Visueller Karten-Editor** (SPA, Menü „Visitenkarten"): Canvas im mm-Maßstab
mit Beschnitt/Endformat/Sicherheits-Markierung, Elemente per Drag&Drop
(Feld/Text/QR/Logo/Fläche/Linie), Eigenschaften-Panel (Position/Größe/Schrift/
Farbe/Datenbindung), Vorder-/Rückseite, Live-Vorschau mit echten Daten,
Speichern + PDF-Vorschau. Backend: `GET|PUT /api/companies/{id}/card-template`.
**Hintergrund-PDF (Variable Data Printing) + eigene Schriften:** Kunde kann
ein fertig gestaltetes Karten-PDF hochladen; die Plattform legt nur die
dynamischen Felder + QR darüber. Eigene Schriften (TTF/OTF) werden eingebettet.
Endpunkte: `POST /api/companies/{id}/card-template/background` und `.../font`.
Nächster Schritt: Editor-UI für Hintergrund-/Font-Upload, PDF/X-1a-Finishing
(Ghostscript), Sammel-PDF/Druckbogen, dann Wallet-Pässe (§12). Siehe `docs/KONZEPT.md` §9.