first commit

This commit is contained in:
2026-05-07 13:03:46 +02:00
commit 51acfe9488

142
README.md Normal file
View File

@@ -0,0 +1,142 @@
# CalBook
CalBook ist ein modernes, self-hosted Terminbuchungssystem mit genau einem Termintyp: **Gespräch**.
Die öffentliche Buchung hat eine optionale Personenauswahl: Nutzer wählen "Alle" oder eine spezifische Person.
CalBook wählt automatisch verfügbare Personen und legt den Termin für alle passenden Personen an.
Das Backend ist **Admin-only**:
- Es gibt keinen separaten Mitarbeiter-Login/-Bereich.
- Buchungskapazität entsteht aus den im Admin angelegten Personen-Kalendern.
- Die Personenanzahl wird automatisch aus aktiven Kalender-Personen berechnet.
## Stack
- Next.js 15 (App Router)
- Tailwind CSS + framer-motion
- Prisma + PostgreSQL
- NextAuth Credentials Login
- tsdav für CalDAV
- node-cron für 5-Minuten-Sync
- Nodemailer SMTP
- Docker + Docker Compose
## Schnellstart
```bash
./deploy.sh
```
**Ein Befehl** führt interaktiv durch Konfiguration, generiert Secrets, baut Container, richtet Datenbank ein und legt Admin an.
Die App ist danach unter der eingegebenen URL erreichbar.
### Deployment-Modi
- `direct`: App auf `:3000`, Mailhog auf `:8025`
- `proxy`: keine Host-Ports, Routing über vorhandenes Traefik
Für echte Mail-Links (Storno/Umbuchen) als URL deine Domain angeben (z.B. `https://calbook.deinedomain.tld`).
## Docker Build
- App-Image als Next.js-Standalone-Build.
- BuildKit-Cache für `npm ci` Folge-Builds ohne erneuten Download.
- Prisma/Seed über separaten `calbook-tools` Service.
- DB-Volumes stack-spezifisch: `./volumes/postgres-<stack-name>`.
## Default Login
- E-Mail: Wert aus `ADMIN_EMAIL` in `.env`
- Passwort: Wert aus `ADMIN_PASSWORD` in `.env`
## Wichtige Routen
**Öffentlich:**
- Buchung: `/buchen`
- Einbettung: `/buchen?embed=true`
- Mitarbeiter-Buchung: `/buchen/<slug>`
- Datenschutz: `/datenschutz`
- Impressum: `/impressum`
- Stornierung: `/stornieren?token=...`
- Login: `/anmelden`
**Admin (alle unter `/admin/*`):**
- Dashboard: `/admin/uebersicht`
- Termine: `/admin/termine`
- Kalender-Personen: `/admin/kalender`
- E-Mail-Templates: `/admin/email-templates`
- Branding (Header + Footer): `/admin/branding`
- Rechtliches: `/admin/rechtliches`
- Instant Meeting: `/admin/instant-meeting`
- Backup: `/admin/backup`
- Einstellungen (global + SMTP): `/admin/einstellungen`
**Mailhog (nur direct-Modus):**
- `http://localhost:8025`
## API
- `GET /api/public/mitarbeiter`
- `GET /api/public/slots?datum=YYYY-MM-DD`
- `GET /api/public/slots-monat`
- `POST /api/public/buchen`
- `GET /api/public/umbuchen?token=`
- `POST /api/public/stornieren`
- `GET|PATCH /api/admin/einstellungen`
- `POST /api/admin/einstellungen/test-smtp`
- `GET|POST /api/admin/kalender`
- `PATCH|DELETE /api/admin/kalender/[id]`
- `GET|POST /api/admin/kalender/[id]/sync`
- `POST /api/admin/kalender/test-connection`
- `GET|PATCH /api/admin/termine`
- `GET /api/admin/letzte-buchungen`
- `PATCH /api/admin/letzte-buchungen`
- `GET|POST /api/admin/backup`
- `GET|POST /api/admin/instant-meeting`
- `POST /api/cron/sync`
## Hinweise
- UI und API sind auf Deutsch (ohne i18n-Framework).
- Zeitzone standardmäßig `Europe/Berlin`.
- Embed-Modus: `/buchen?embed=true`.
- SMTP kann im Admin-Backend unter Einstellungen gepflegt werden.
- Deployment: `./deploy.sh` führt durch alles (Konfiguration, Build, Prisma, Seed).
- Traefik-Integration über Labels + externes Docker-Netzwerk (`proxy`).
- Zwei Compose-Varianten: `docker-compose.proxy.yml`, `docker-compose.direct.yml`.
- `calbook-app`: schlankes Runtime-Image. `calbook-tools`: nur für Prisma/Seed-Kommandos.
- Container-Namen via `STACK_NAME` (`<stack>-app`, `<stack>-db`, `<stack>-mailhog`).
- Postgres-Daten unter `./volumes/postgres-<stack-name>` (stack-spezifisch).
- `POST /api/cron/sync` benötigt Header `x-cron-secret` mit `CRON_SECRET`.
- `TRUST_PROXY_HEADERS=true` für korrektes Rate-Limiting hinter Reverse-Proxy.
- Buchbare Wochentage/Uhrzeiten pro Personen-Kalender im Admin unter Kalender.
- E-Mail-Templates: 10 Event-Typen, 9 Design-Styles, Live-Vorschau, Custom-Templates.
- Öffentliche API-Routen sind IP-basiert rate-limitiert.
- Mutierende API-Requests prüfen Request-Herkunft (Origin/Sec-Fetch-Site).
- Buchungen nutzen serielle DB-Transaktionen und Slot-Locking gegen Race-Conditions.
- In-Memory-Caches für Settings und Slot-Abfragen (TTL via Env konfigurierbar).
- SMTP/CalDAV-Fehler mit Retry/Backoff + persistenter DeliveryIssue-Queue.
- Umbuchung per Token-Link, Reminder-Mails (24h und 2h vorher) via Cron.
- Admin: No-Show-Markierung, SMTP-Testmail.
- Backup: Vollständiger Export/Import inkl. CalDAV-Key-Re-Encryption (URLs werden ausgefiltert).
- Standalone-Export-Script: `scripts/export-backup.sh` (für Versionen ohne Backup-API).
- Session-Timeout: Nach 2 Stunden Inaktivität automatischer Logout.
- Prisma-Migrationen unter `prisma/migrations`.
## Traefik (vorhanden)
CalBook startet keinen eigenen Traefik-Container. Labels werden auf den `calbook-app`-Service gesetzt.
Relevante `.env`-Variablen:
- `DEPLOYMENT_MODE=proxy`
- `ENABLE_TRAEFIK=true`
- `TRAEFIK_HOST=deine-domain.tld`
- `TRAEFIK_ENTRYPOINTS=websecure`
- `TRAEFIK_TLS=true`
- `TRAEFIK_CERTRESOLVER=tls_resolver`
- `TRAEFIK_ROUTER_NAME=calbook`
- `TRAEFIK_SERVICE_NAME=calbook`
- `TRAEFIK_DOCKER_NETWORK=proxy`
`deploy.sh` setzt automatisch den passenden Compose-Modus und erstellt das Proxy-Netzwerk.