Fünf Wünsche aus dem Durchtesten:
1. Wiederholungen einstellbar (täglich/wöchentlich/monatlich/jährlich,
alle N, Ende nie/nach Anzahl/an einem Datum). Der eigentliche Aufwand
lag nicht im Formular, sondern im Aufklappen: eine wöchentliche Reihe
erschien sonst als *ein* Eintrag. Der Server klappt sie jetzt im
angefragten Zeitfenster auf (?from=&to=, rrule-go über go-icals
RecurrenceSet), die Ansichten fragen ihren sichtbaren Ausschnitt an.
Geprüft: 5 Termine wöchentlich, nach Umstellung auf 14-tägig korrekt
neu gerechnet, Fenster einer Woche liefert genau einen.
Regeln, die das Formular nicht abbildet (etwa jeder zweite Dienstag
im Monat), werden weiterhin korrekt *angezeigt* -- geprüft, die vier
Termine stimmen -- aber nicht zum Bearbeiten angeboten (409). Ein
halb verstandenes Speichern würde die Regel sonst still beschneiden.
2. Tag wird erst geöffnet, statt sofort einen Termin anzulegen: Klick
auf einen Tag zeigt dessen Termine als Liste, dort wählt man einen
aus oder legt bewusst einen neuen an.
3. Eigene Farbe je Termin (COLOR nach RFC 7986), leer = Kalenderfarbe.
4. Kalenderliste ohne Kästchen: der Farbpunkt selbst ist der Schalter --
gefüllt heißt sichtbar, leerer Ring ausgeblendet.
5. Ganztägig als Schiebeschalter statt Kästchen -- es stellt das
Formular um, das ist keine Nebenangabe.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Neues, eigenständiges Modul internal/calendar: implementiert
caldav.Backend (emersion/go-webdav) gegen zwei neue Tabellen
(cal_calendars, cal_objects). Endpunkt /caldav/ mit eigener Basic Auth
(nur App-Passwörter, wie /dav), plus /.well-known/caldav für die
automatische Einrichtung nach RFC 6764.
Gegen echte Container getestet (nicht nur go build): Discovery-Kette
Principal -> Home-Set -> automatisch angelegter Standardkalender,
PUT/GET/DELETE eines Termins, REPORT mit Zeitraumfilter (Treffer und
Nicht-Treffer), If-Match/If-None-Match-Vorbedingungen (412), und dass
ein fremder Nutzer auf einen Kalender-Pfad mit 404 statt 403 abgewiesen
wird.
Zwei Fallen unterwegs gefunden und dokumentiert:
- go-webdav vergleicht von CurrentUserPrincipal/CalendarHomeSetPath
zurückgegebene Pfade direkt gegen r.URL.Path (inklusive Prefix) und
bestimmt den Ressourcentyp allein an der Segmentzahl dahinter – der
Nutzername beim Principal steht deshalb in einem Segment
(principals-max), nicht als Unterpfad.
- chi kennt REPORT/MKCALENDAR nicht von Haus aus (nur PROPFIND & Co.
waren für /dav bereits registriert) und hätte sie sonst mit 405
abgewiesen, bevor der CalDAV-Handler überhaupt lief.
Migration 000021 nur mit CREATE TABLE IF NOT EXISTS, wie in
kalender-plan.md festgelegt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Go-Backend (chi, pgx, golang-migrate) + React/TS-Frontend als PWA.
Enthalten: Auth inkl. OIDC, Dateien mit Versionen und Papierkorb,
Freigaben (Links + intern), WebDAV, Gruppenordner, Admin/Theming,
Volltextsuche mit OCR, eigener PDF-Betrachter und WOPI-Office
(Collabora/OnlyOffice).
Nicht im Repo: deploy/.env (Sitzungsschlüssel, DB- und Admin-Passwort)
sowie alle Daten- und Build-Verzeichnisse – siehe .gitignore.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>