Files
kalendartool/plan.md

13 KiB

1. Produktidee

Ein einfaches Kalender- und Reservierungstool, bei dem ein Admin Kalender anlegt und Personen gezielt Zugang zu einem bestimmten Kalender gibt.

Der wichtigste Grundsatz sollte sein:

Ein User gehört genau einem Kalender an und sieht ausschließlich diesen Kalender.

Ein Admin kann dagegen mehrere Kalender besitzen und verwalten.

Beispiel

Ein Admin betreibt drei Kalender:

  • „Fußballplatz“
  • „Besprechungsraum“
  • „Tennisplatz“

Er erstellt für „Fußballplatz“ einen Invite-Link und verschickt ihn an die entsprechenden Personen.

Ein eingeladener User sieht nach der Anmeldung ausschließlich:

Fußballplatz

und kann dort freie Zeiten ansehen und Reservierungen erstellen.


2. Rollen und Rechte

Admin

Der Admin kann:

  • sich registrieren/anmelden
  • Kalender erstellen
  • Kalender bearbeiten
  • Kalender löschen/deaktivieren
  • Kalender-Titel festlegen
  • Beschreibung festlegen
  • Zeitzone festlegen
  • Invite-Links erzeugen
  • Benutzer einem Kalender zuordnen
  • alle Reservierungen seines Kalenders sehen
  • Reservierungen verwalten/löschen
  • optional Reservierungen für andere Benutzer erstellen

Ein Admin sollte mehrere Kalender besitzen können.


User

Ein User kann:

  • sich per E-Mail und Passwort anmelden
  • seinen zugewiesenen Kalender öffnen
  • freie Zeiten sehen
  • bestehende Reservierungen sehen
  • eigene Reservierungen erstellen
  • Dauer einer Reservierung festlegen
  • eigene Reservierungen ändern
  • eigene Reservierungen stornieren

Wichtig:

Ein User darf niemals Daten eines anderen Kalenders über die URL oder API abrufen können.

Also nicht nur im Frontend verstecken, sondern auch serverseitig erzwingen.


3. Invite-System

Das würde ich etwas stärker ausbauen als in deinem ursprünglichen Konzept.

Ein Admin klickt auf:

„Benutzer einladen“

und bekommt einen Link wie:

https://deine-app.de/invite/a8f73kd92...

Der Link enthält einen zufälligen, nicht erratbaren Token.

Der Empfänger öffnet den Link und sieht:

Du wurdest zum Kalender „Besprechungsraum“ eingeladen.

Danach:

E-Mail + Passwort erstellen

und der Benutzer wird automatisch diesem Kalender zugeordnet.

Wichtig

Ein Invite sollte:

  • einen zufälligen Token besitzen
  • optional ein Ablaufdatum haben
  • optional nur einmal verwendbar sein
  • deaktivierbar sein

Noch besser:

Der Admin kann später sehen:

Einladungen
────────────────────────────
Aktiv     3
Abgelaufen 1
Verwendet 5

4. Kalender

Jeder Kalender sollte mehr Informationen als nur einen Titel besitzen.

Zum Beispiel:

Calendar
-------------------------
Titel
Beschreibung
Zeitzone
Erstellt am
Besitzer
Status

Beispiel:

Besprechungsraum 1
Raum für interne Meetings
Europe/Berlin
Aktiv

Sinnvolle spätere Einstellungen

  • Öffnungszeiten
  • erlaubte Reservierungsdauer
  • maximale Reservierungsdauer
  • minimale Vorlaufzeit
  • maximale Vorausbuchung
  • Puffer zwischen Reservierungen
  • Wochenenden erlauben/deaktivieren

Das würde ich aber teilweise erst nach dem MVP bauen.


5. Reservierungen

Eine Reservierung sollte mindestens folgende Daten haben:

Reservierung
-------------------------
Kalender
Benutzer
Startzeit
Endzeit
Dauer
Titel / Betreff
Notiz
Status
Erstellt am
Geändert am

Beispiel:

Besprechungsraum

10:00 ─────────────────
      Max Mustermann
      60 Minuten
      Projektmeeting
11:00 ─────────────────

Dauer

Der Benutzer soll nicht nur eine Startzeit wählen, sondern auch eine Dauer:

Start: 14:00
Dauer: 90 Minuten

Das System berechnet:

Ende: 15:30

Intern würde ich Startzeit + Endzeit speichern und die Dauer daraus berechnen.


6. Ganz wichtig: Doppelbuchungen verhindern

Das ist eine der wichtigsten Funktionen der gesamten Anwendung.

Wenn bereits existiert:

14:00 - 15:00

darf niemand buchen:

14:30 - 15:30

Ebenso nicht:

14:00 - 14:30

oder:

13:00 - 14:01

Das muss serverseitig und in der Datenbanklogik geprüft werden.

Nicht nur:

„Button deaktivieren, wenn es im Frontend belegt aussieht.“

Denn zwei Benutzer könnten gleichzeitig buchen.

Der Server muss die Reservierung atomar validieren.


7. Kalenderansicht

Für das MVP würde ich drei Ansichten anbieten:

Monat

Gut für den Überblick.

Woche

Wahrscheinlich die wichtigste Ansicht für Reservierungen.

Tag

Sehr praktisch, wenn viele Buchungen vorhanden sind.

Optisch beispielsweise:

Montag 18. September

08:00
09:00
10:00   █████████████
11:00   █████████████
12:00
13:00        ███████
14:00        ███████
15:00

Reservierungen sollten anklickbar sein.


8. Sichtbarkeit

Hier würde ich dein ursprüngliches Konzept etwas anders definieren.

Ich würde nicht sagen:

„Öffentlicher Kalender = jeder im Internet kann ihn sehen.“

Das kann später Datenschutzprobleme verursachen.

Besser:

Standard: Invite-only

Ein Kalender ist nur für Benutzer sichtbar, die ihm zugeordnet sind.

Der Invite-Link dient als Zugang.

Später kannst du einen zweiten Modus einbauen:

Öffentlich

Der Kalender kann ohne Anmeldung angesehen werden.

Zum Beispiel:

https://deine-app.de/c/public/abc123

Aber:

Reservierungen erfordern weiterhin Anmeldung.

Damit hast du beide Möglichkeiten.


9. Datenbank

Für das Projekt würde ich PostgreSQL verwenden.

Eine mögliche Struktur:

users
----------------
id
email
password_hash
role
created_at
updated_at
calendars
----------------
id
owner_id
title
description
timezone
is_active
created_at
updated_at
calendar_members
----------------
id
calendar_id
user_id
created_at

Damit kannst du sauber abbilden:

Admin
  │
  ├── Kalender A
  │     ├── User 1
  │     ├── User 2
  │     └── User 3
  │
  └── Kalender B
        ├── User 4
        └── User 5

Reservierungen:

reservations
----------------
id
calendar_id
user_id
title
start_at
end_at
status
notes
created_at
updated_at

Invites:

invites
----------------
id
calendar_id
token_hash
expires_at
used_at
created_at

Ich würde den Invite-Token nicht im Klartext speichern, sondern nur seinen Hash.


10. Rollen würde ich technisch einfach halten

Zum Start:

ADMIN
USER

Nicht sofort ein kompliziertes Berechtigungssystem bauen.

Später könntest du erweitern:

SUPER_ADMIN
ADMIN
USER
VIEWER

Aber für Version 1 reichen zwei Rollen völlig.


11. Authentifizierung

Login:

E-Mail
Passwort
[Anmelden]

Registrierung:

E-Mail
Passwort
Passwort wiederholen

Zusätzlich:

  • Passwort-Hashing
  • Passwort vergessen
  • Session-Management
  • E-Mail-Verifizierung
  • Rate-Limiting beim Login
  • sichere Cookies
  • CSRF-Schutz, falls dein Auth-Setup das erfordert

Passwörter niemals selbst verschlüsseln oder im Klartext speichern.


12. Mein technischer Stack

Für dein Projekt würde ich etwas Modernes und relativ simples nehmen:

Frontend + Backend

Next.js + TypeScript Docker Cotainer

Damit kannst du Frontend und Backend in einem Projekt haben.

Datenbank

PostgreSQL

ORM

Prisma

UI

Tailwind CSS *ShadCN

plus eine Kalender-Komponente wie z. B. FullCalendar.

Auth

Eine etablierte Auth-Lösung statt eigener Session-Implementierung.

Deployment

Zum Beispiel:

Frontend/API    → Next.js Hosting
Datenbank       → PostgreSQL
Domain          → deine-domain.de
Dockercontainer -> als stack 

Damit bleibt die Architektur relativ klein:

Browser
   │
   ▼
Next.js
   │
   ├── Auth
   ├── API
   ├── UI
   │
   ▼
PostgreSQL

13. Seiten der Anwendung

Ich würde ungefähr diese Struktur bauen.

/
├── login
├── register
├── forgot-password
│
├── dashboard
│
├── calendar/[id]
│
├── reservation/new
├── reservation/[id]
│
├── invite/[token]
│
└── admin
    ├── calendars
    ├── calendars/new
    ├── calendars/[id]
    ├── users
    └── invites

14. Dashboard

User

Der User bekommt praktisch nur:

Mein Kalender

┌──────────────────────────────┐
│ Besprechungsraum             │
│                              │
│ [ Kalender öffnen ]          │
└──────────────────────────────┘

Da ein User nur einen Kalender haben darf, brauchst du keine komplizierte Kalenderauswahl.

Admin

Beim Admin:

Dashboard

Meine Kalender

[ Besprechungsraum ]
[ Fußballplatz     ]
[ Tennisplatz      ]

+ Kalender erstellen

15. Reservierung erstellen

Ich würde den Ablauf sehr einfach halten:

Neue Reservierung

Datum
[ 18.09.2026 ]

Startzeit
[ 14:00 ]

Dauer
[ 60 Minuten ]

Titel
[ Besprechung ]

Notiz
[ ............. ]

[ Reservieren ]

Nach dem Abschicken prüft der Server:

Ist der Kalender gültig?
Ist der Benutzer berechtigt?
Ist die Zeit verfügbar?
Liegt die Zeit innerhalb der erlaubten Buchungszeiten?
Ist die Dauer erlaubt?

Dann wird gebucht.


16. Zusätzliche Funktion, die ich unbedingt ergänzen würde

Verfügbarkeitsregeln

Sonst kann jemand beispielsweise um 03:00 Uhr nachts einen Raum reservieren.

Der Admin sollte deshalb irgendwann einstellen können:

Buchungszeiten

Montag       08:00 - 18:00
Dienstag     08:00 - 18:00
Mittwoch     08:00 - 18:00
Donnerstag   08:00 - 18:00
Freitag      08:00 - 16:00
Samstag      geschlossen
Sonntag      geschlossen

Und:

Mindestdauer:       30 Minuten
Maximaldauer:       4 Stunden
Buchbar bis:        30 Tage im Voraus
Vorlaufzeit:        1 Stunde

Das macht aus einem simplen Kalender tatsächlich ein brauchbares Reservierungssystem.


17. Weitere sinnvolle Funktionen

Für Version 1.0 würde ich nur das Nötigste bauen.

Danach könnten kommen:

E-Mail-Benachrichtigungen

Bei:

  • neuer Reservierung
  • Änderung
  • Stornierung
  • Einladung

Wiederkehrende Reservierungen

Zum Beispiel:

Jeden Montag
18:00 - 19:00

ICS / Kalender-Export

Damit Benutzer Reservierungen in Outlook, Apple Calendar oder Google Calendar übernehmen können.

Admin-Statistiken

Zum Beispiel:

Reservierungen diesen Monat: 143
Auslastung: 67 %

Audit-Log

Damit der Admin nachvollziehen kann:

10:31  Max erstellt Reservierung
10:42  Max geändert Reservierung
11:03  Admin gelöscht Reservierung

18. Was ich ausdrücklich nicht in Version 1 bauen würde

Sonst wird das Projekt unnötig groß.

Zunächst würde ich weglassen:

  • Chat
  • Push-Benachrichtigungen
  • Mobile Apps
  • komplizierte Rollen
  • mehrere Kalender pro User
  • Zahlungen
  • Abonnements
  • externe Kalender-Synchronisierung
  • komplexe Ressourcenverwaltung

Erst einmal:

Login → Kalender → Einladung → Reservierung → Konfliktprüfung

Das ist dein Kernprodukt.


19. MVP-Definition

Ich würde dein erstes Release auf diese Funktionen begrenzen:

Auth

  • Registrierung
  • Login
  • Logout
  • Passwort vergessen

Admin

  • Kalender erstellen
  • Kalender bearbeiten
  • Kalender deaktivieren
  • Invite-Link erstellen
  • Benutzer sehen
  • Reservierungen sehen/löschen

User

  • genau einem Kalender zugeordnet
  • Kalender ansehen
  • Reservierung erstellen
  • Startzeit wählen
  • Dauer wählen
  • eigene Reservierung bearbeiten
  • eigene Reservierung löschen

System

  • Berechtigungsprüfung
  • Doppelbuchungen verhindern
  • Zeitzonen sauber behandeln
  • responsive Oberfläche
  • sichere Sessions
  • saubere Fehlerbehandlung

20. Projektstruktur

Ich würde ungefähr so starten:

calendar-app/
│
├── app/
│   ├── login/
│   ├── register/
│   ├── dashboard/
│   ├── calendar/
│   ├── invite/
│   └── admin/
│
├── components/
│   ├── calendar/
│   ├── reservation/
│   ├── forms/
│   └── ui/
│
├── lib/
│   ├── auth/
│   ├── db/
│   ├── permissions/
│   ├── reservations/
│   └── invites/
│
├── prisma/
│   └── schema.prisma
│
├── api/
│
└── tests/

Besonders wichtig ist eine zentrale Berechtigungsschicht.

Zum Beispiel konzeptionell:

canViewCalendar(user, calendar)
canCreateReservation(user, calendar)
canDeleteReservation(user, reservation)
canManageCalendar(user, calendar)

Dann verteilst du Berechtigungslogik nicht überall im Code.


21. Eine wichtige Entscheidung für dein Konzept

Ich würde den Satz

„Jeder kann nur seinen einen Kalender sehen“

technisch als feste Regel definieren:

USER → genau 1 Kalender

ADMIN → 0..n Kalender

Damit ist das Datenmodell eindeutig.

Und bei einem Invite gilt:

Invite
   ↓
User registriert sich
   ↓
User wird Kalender zugeordnet
   ↓
User sieht ausschließlich diesen Kalender

Ein User kann anschließend nicht selbstständig einen zweiten Kalender hinzufügen.

Das verhindert sehr viel Komplexität.