2026-10-08 20:41:35 +02:00

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)

# 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

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

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.

Description
No description provided
Readme 244 KiB
Languages
TypeScript 89.8%
JavaScript 8.7%
Dockerfile 1.1%
Shell 0.2%
CSS 0.2%