Initial commit: Kalendartool (Next.js, Prisma, Docker)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
860
plan.md
Normal file
860
plan.md
Normal file
@@ -0,0 +1,860 @@
|
||||
## 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.
|
||||
Reference in New Issue
Block a user