Initial commit: Kalendartool (Next.js, Prisma, Docker)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
98
README.md
Normal file
98
README.md
Normal file
@@ -0,0 +1,98 @@
|
||||
# Kalendartool
|
||||
|
||||
Einfaches Kalender- und Reservierungstool nach `plan.md`: Ein Admin legt Kalender an und lädt Benutzer per Invite-Link ein. 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
|
||||
- **Invite-System**: nicht erratbare Tokens (32 Bytes), nur SHA-256-Hash in der DB, Ablaufdatum, Übersicht Aktiv/Abgelaufen/Verwendet
|
||||
- **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
|
||||
|
||||
## Schnellstart mit Docker (empfohlen)
|
||||
|
||||
```bash
|
||||
# 1. Session-Secret erzeugen und .env anlegen
|
||||
cp .env.example .env
|
||||
# SESSION_SECRET in .env setzen (mindestens 32 Zeichen):
|
||||
node -e "console.log('SESSION_SECRET=' + require('crypto').randomBytes(48).toString('base64url'))"
|
||||
|
||||
# 2. Stack starten (PostgreSQL + App)
|
||||
docker compose 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 # DATABASE_URL 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. Unter „Benutzer einladen" einen Invite-Link erstellen und verschicken
|
||||
4. Eingeladene Personen registrieren sich über den Link und sehen sofort nur diesen einen Kalender
|
||||
|
||||
## Projektstruktur
|
||||
|
||||
```
|
||||
app/ Next.js App Router (Seiten + API-Routen)
|
||||
api/auth/ register, login, logout, forgot-password
|
||||
api/calendars/ CRUD + Reservierungen + Invites
|
||||
api/reservations/ Bearbeiten/Löschen (atomar)
|
||||
dashboard/ User: 1 Kalender · Admin: alle Kalender
|
||||
calendar/[id]/ Ansicht Tag/Woche/Monat
|
||||
invite/[token]/ Invite-Annahme
|
||||
admin/ Kalenderverwaltung
|
||||
components/ UI-, Kalender-, Reservierungs-, Admin-Komponenten
|
||||
lib/
|
||||
auth/ Session (JWT-Cookies), Passwort-Hashing
|
||||
permissions/ zentrale Berechtigungsschicht
|
||||
reservations/ Konfliktlogik + atomarer Service
|
||||
invites/ Token-Erzeugung/Hashing
|
||||
api/ Response-Helfer, Kontext-Lader
|
||||
validation.ts Zod-Schemas
|
||||
prisma/schema.prisma Datenmodell
|
||||
tests/ Unit-Tests (Kollisionen, Invites, Rechte)
|
||||
```
|
||||
|
||||
## Tests
|
||||
|
||||
```bash
|
||||
npm test
|
||||
```
|
||||
|
||||
Getestet werden insbesondere die **Kollisionslogik** (Überlappungsvarianten aus plan.md Abschnitt 6), Invite-Token-Hashing/-Ablauf, 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 |
|
||||
| Invite-Tokens | 32 Byte Zufall, nur SHA-256-Hash in der DB |
|
||||
| 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.
|
||||
Reference in New Issue
Block a user