# 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-`. ## 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/` - 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` (`-app`, `-db`, `-mailhog`). - Postgres-Daten unter `./volumes/postgres-` (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.