Files
kalendartool/README.md

119 lines
5.3 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.

# Kalendartool
Einfaches Kalender- und Reservierungstool: Ein Admin legt Kalender an und ordnet vorhandene Benutzer direkt zu. Jeder User sieht **ausschließlich seinen einen Kalender** und kann dort Reservierungen erstellen.
## Kernfunktionen (MVP)
- **Auth**: Registrierung, Login, Logout, Passwort vergessen – bcrypt-Hashing, signierte HttpOnly-Session-Cookies, Rate-Limiting beim Login
- **Rollen**: `ADMIN` (0..n Kalender) und `USER` (genau 1 Kalender) – serverseitig erzwungen
- **Kalender**: Titel, Beschreibung, Zeitzone, aktiv/inaktiv
- **Mitglieder**: Administratoren ordnen vorhandene Benutzer direkt einem Kalender zu
- **Reservierungen**: Startzeit + Dauer (15-Minuten-Schritte), Titel, Notiz
- **Doppelbuchungsschutz**: atomare Prüfung in serialisierbarer Transaktion (HTTP 409 bei Kollision)
- **Ansichten**: Tag / Woche / Monat
- **Sicherheit**: zentrale Berechtigungsschicht (`lib/permissions`), Zod-Validierung aller Eingaben, Middleware-Schutz, keine Account-Enumeration
## Tech-Stack
Next.js 14 (App Router, TypeScript) · PostgreSQL · Prisma · Tailwind CSS · Docker · Vitest
## MPM Marketplace
Das Repository ist als MPM-Modul vorbereitet. `module.json` beschreibt das
Modul und seine Konfigurationsfelder; `compose.yml` enthält App, PostgreSQL
und tägliche Backups. Die Modul-App veröffentlicht keinen Host-Port. MPM
erreicht sie intern über Port `41030` und die Health-Route `/health`.
Die Anmeldung und Rollen kommen im MPM-Betrieb signiert vom MPM-Gateway.
Die lokale Cookie-Anmeldung bleibt für den eigenständigen Betrieb erhalten.
Kalender und Reservierungen liegen in PostgreSQL. Die benannten Volumes
`pgdata` und `pgbackups` bleiben beim Entfernen des Moduls erhalten.
Bei der ersten MPM-Konfiguration werden zwei getrennte, zufällige Passwörter
für PostgreSQL-Administration und App-Zugriff benötigt. Die Anmeldung läuft
über MPM; lokale Konten und Einladungslinks sind im MPM-Betrieb deaktiviert.
Benutzer und Modulzugriff werden in MPM verwaltet. Öffne das Modul zunächst
einmal mit dem neuen Benutzer, damit sein lokales Profil angelegt wird; ein
Kalenderadministrator kann ihn danach direkt einem Kalender zuordnen. Die
Datenbank-Initialisierung wird nur bei einem leeren Volume ausgeführt. Ein
späteres Ändern der Datenbankpasswörter im MPM-Konfigurationsdialog ändert die
Zugangsdaten eines bestehenden PostgreSQL-Volumes nicht automatisch.
## Schnellstart mit Docker (eigenständiger Betrieb)
```bash
# 1. Session-Secret erzeugen und .env anlegen
cp .env.example .env
# CALENDAR_ADMIN_PASSWORD, CALENDAR_DB_PASSWORD und SESSION_SECRET in .env
# durch zufällige Werte ersetzen. SESSION_SECRET braucht mindestens 32 Zeichen:
node -e "console.log('SESSION_SECRET=' + require('crypto').randomBytes(48).toString('base64url'))"
# 2. Stack starten (PostgreSQL + App)
docker compose -f docker-compose.yml up --build
```
Die App läuft dann auf http://localhost:3000. Migrationen werden beim Containerstart automatisch angewendet (`prisma migrate deploy`).
## Schnellstart ohne Docker
```bash
npm install
cp .env.example .env # Passwörter und SESSION_SECRET anpassen
npx prisma db push # Schema in die Datenbank schreiben
npm run dev
```
Voraussetzung: laufendes PostgreSQL (z. B. nur der `db`-Service aus `docker-compose.yml`: `docker compose up -d db`).
## Erste Schritte
1. Erste Registrierung unter `/register` → der **erste Benutzer wird automatisch ADMIN**
2. Im Dashboard einen Kalender anlegen
3. Im Kalender unter „Mitglieder" vorhandene Benutzer zuordnen
## Projektstruktur
```
app/ Next.js App Router (Seiten + API-Routen)
api/auth/ register, login, logout, forgot-password
api/calendars/ CRUD + Reservierungen + Mitglieder
api/reservations/ Bearbeiten/Löschen (atomar)
dashboard/ User: 1 Kalender · Admin: alle Kalender
calendar/[id]/ Ansicht Tag/Woche/Monat
admin/ Kalenderverwaltung
components/ UI-, Kalender-, Reservierungs-, Admin-Komponenten
lib/
auth/ Session (JWT-Cookies), Passwort-Hashing
permissions/ zentrale Berechtigungsschicht
reservations/ Konfliktlogik + atomarer Service
api/ Response-Helfer, Kontext-Lader
validation.ts Zod-Schemas
prisma/schema.prisma Datenmodell
tests/ Unit-Tests (Kollisionen, Validierung, Rechte)
```
## Tests
```bash
npm test
```
Getestet werden insbesondere die **Kollisionslogik** (Überlappungsvarianten aus plan.md Abschnitt 6), Eingabevalidierung und die komplette Berechtigungsmatrix.
## Sicherheitskonzept (Kurzfassung)
| Thema | Umsetzung |
| --- | --- |
| Doppelbuchungen | `SERIALIZABLE`-Transaktion in `lib/reservations/service.ts` |
| Berechtigungen | zentrale Funktionen in `lib/permissions/permissions.ts`, geprüft in **jeder** API-Route |
| Passwörter | bcrypt (12 Runden), nie im Klartext |
| Sessions | HS256-signierte JWTs in HttpOnly/SameSite-Cookies |
| Login-Missbrauch | Rate-Limiting (5 Versuche / 15 min) |
| Account-Enumeration | generische Fehler, `/forgot-password` antwortet immer 200 |
| Eingaben | Zod-Schemas mit Längen-/Formatgrenzen |
## Bewusste MVP-Grenzen (plan.md Abschnitt 18)
Buchungszeitfenster-Regeln, E-Mail-Versand, ICS-Export, wiederkehrende Reservierungen und Statistiken sind bewusst **nicht** Teil von Version 1 – die Struktur (Service-Schicht, Regeln in `lib/`) ist darauf vorbereitet.