CalendarShare bekommt color-Spalte. Im Kalender-Menue kann jeder
Benutzer eine eigene Anzeigefarbe fuer einen mit ihm geteilten
Kalender setzen, ohne dass sich dadurch die Farbe beim
Eigentuemer oder anderen Share-Empfaengern aendert.
* Owner: Farbe aendert den Kalender direkt (wie bisher).
* Share-Empfaenger: Farbe landet in CalendarShare.color und wird
nur fuer ihn ausgeliefert (list_calendars injiziert sie in
'color', Owner-Farbe bleibt in 'owner_color' als Referenz).
Neuer Endpoint: PUT /calendars/<id>/my-color.
UI-Hinweis: "Nur fuer deine Ansicht - <Owner> behaelt seine Farbe".
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
User.calendars hat bereits backref='owner', mein zusaetzlich
hinzugefuegtes Calendar.owner kollidierte damit und SQLAlchemy
weigerte sich, die Mappers zu initialisieren ("Error creating
backref 'owner'..."). Damit waren alle Auth-Endpoints tot.
Jetzt nur noch Kommentar, die backref uebernimmt die Aufgabe.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sharing-Fix:
Calendar-Model hatte keine owner-Relation zu User - list_calendars
stuerzte beim Listen geteilter Kalender ab (c.owner.username ->
AttributeError). Jetzt mit explizitem foreign_keys Relationship.
Benutzer-Autocomplete:
"Kalender teilen" nutzt jetzt /users/search wie bei Dateien.
Tippt man 2+ Zeichen, erscheint ein Dropdown mit passenden
Benutzernamen. Klick uebernimmt den Namen.
Bestehende Freigaben werden im Menue angezeigt mit Muelleimer
zum Entfernen.
Privat-Flag fuer Termine:
CalendarEvent bekommt is_private-Spalte. Checkbox im Termin-
Dialog "🔒 Privat (Teilnehmer sehen nur den Zeitblock)".
Redaction greift an drei Stellen:
* GET /events: Nicht-Owner sehen summary="Privat", description
und location = null. Zeitfenster bleibt voll sichtbar.
* iCal-Export (/ical/<token>): Privat-Events werden mit
CLASS:PRIVATE ausgegeben und SUMMARY/DESCRIPTION/LOCATION
werden gestrippt.
* CalDAV: aktuell werden eh nur eigene Kalender exportiert,
also keine Redaction noetig. Kommt bei Share-Support rein.
Der Eigentuemer sieht natuerlich in seiner eigenen Ansicht alle
Details seines privaten Termins.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Klick auf einen wiederkehrenden Termin oeffnet zuerst einen Dialog:
"Nur diesen Termin" oder "Ganze Serie".
* Serie: bearbeitet den Master wie bisher
* Nur dieser: fuegt EXDATE fuer das geklickte Datum zum Master
hinzu und legt einen eigenstaendigen Ersatz-Termin mit den
bearbeiteten Daten an
Backend:
* CalendarEvent.exdates speichert Ausnahmedaten kommasepariert
* POST /events/<id>/exception fuegt EXDATE hinzu, erstellt
optional das Replacement-Event mit frischer UID
* _build_vevent schreibt jetzt EXDATE-Zeilen in die ical_data,
sodass CalDAV-Clients die Ausnahmen auch sehen werden
Frontend:
* FullCalendar rrule-Plugin bekommt die exdate-Liste und blendet
die uebersprungenen Tage aus
* Drag & Drop verschiebt weiterhin die ganze Serie (Shortcut -
fuer Einzelverschiebung Termin anklicken und bearbeiten)
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>