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.