Files
Aether/kalender-plan.md
T
marcandClaude Opus 5 8f90a7fbd6 docs: Plan für einen Kalender in Aether
Radicale ist für einen einfachen Kalender zu umständlich, vor allem fehlt
die OIDC-Anbindung. Der Plan hält fest, warum das als Modul in Aether
besser aufgehoben ist: Ein CalDAV-Client kann ohnehin kein OIDC, er will
Benutzername und Passwort – und App-Passwörter für DAV gibt es hier schon.

Vor dem Schreiben nachgesehen statt geschätzt: emersion/go-webdav v0.7.0
beantwortet PROPFIND/REPORT selbst, caldav.Filter() filtert, und der
Zeitraumfilter löst Wiederholungen über go-ical und rrule-go auf. Damit
ist der Teil, vor dem ich gewarnt hatte, in der Bibliothek. Zu erfüllen
bleibt eine Schnittstelle mit neun Methoden – Speicherarbeit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-03 20:43:56 +02:00

105 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Kalender in Aether – Plan
Stand 02.09.2026. Ausgangspunkt: Radicale ist für einen einfachen selbst
gehosteten Kalender überraschend umständlich (Konfigurationsdateien, dünne
Doku, keine OIDC-Anbindung).
## Entscheidung: ein Modul in Aether, kein eigener Dienst
Der Grund ist genau das, was bei Radicale gefehlt hat.
**Ein CalDAV-Client kann kein OIDC.** DAVx5, Thunderbird und die Kalender-App
melden sich mit Benutzername und Passwort an – ein Anmeldefenster im Browser
gibt es dort nicht. Wer OIDC für CalDAV sucht, sucht etwas, das es so nicht
gibt. Die richtige Antwort sind **App-Passwörter**, und die hat Aether schon:
Das WebDAV unter `/dav/` läuft bereits darüber.
Damit ist die Rechnung einfach:
| | Radicale o. ä. | Modul in Aether |
|---|---|---|
| Anmeldung Oberfläche | eigenes Konzept, kein OIDC | PocketID, schon da |
| Anmeldung DAVx5 | eigene Nutzerdatei | App-Passwörter, schon da |
| Reverse Proxy, TLS | zusätzlicher Eintrag | schon da |
| Sicherung | zweiter Datenbestand | dieselbe Datenbank |
| Oberfläche | im Grunde keine | die, die wir bauen |
## Was die Bibliothek abnimmt
`github.com/emersion/go-webdav` (v0.7.0, Oktober 2025) bringt einen
CalDAV-Handler mit. Nachgesehen, nicht angenommen:
- Der Handler beantwortet `PROPFIND`, `OPTIONS` und `REPORT` selbst und liest
`calendar-query` wie `calendar-multiget`.
- `caldav.Filter()` wendet die Filter der Anfrage auf die Termine an.
- **Der Zeitraumfilter löst Wiederholungen auf:** `matchCompTimeRange` ruft
`comp.RecurrenceSet(loc)`, und go-ical stützt sich dafür auf
`teambition/rrule-go`. Genau der Teil, vor dem ich gewarnt hatte – „jeden
zweiten Dienstag, über die Zeitumstellung hinweg" – steckt in der Bibliothek
und nicht in unserem Code.
Zu erfüllen ist eine Schnittstelle mit **neun Methoden** plus dem
Nutzer-Principal:
CalendarHomeSetPath · CreateCalendar · ListCalendars · GetCalendar
GetCalendarObject · ListCalendarObjects · QueryCalendarObjects
PutCalendarObject · DeleteCalendarObject
Das ist Speicherarbeit, keine Protokollarbeit. Die Einschätzung „zwei Wochen
bis DAVx5 läuft, danach ein halbes Jahr Kleinkram" gilt für einen Server von
Grund auf – hier nicht.
## Datenmodell
Zwei Tabellen, mehr braucht es nicht:
- `calendars` – Besitzer, Name, Farbe, Zeitzone, `ctag` (ändert sich bei jeder
Änderung, daran erkennt der Client, dass es etwas Neues gibt).
- `calendar_objects` – Kalender, UID, **das `.ics` roh und unverändert**,
`etag`, dazu abgeleitet `dtstart`/`dtend` und ein Kennzeichen, ob eine
Wiederholung dranhängt.
**Die wichtigste Regel: das `.ics` byte-genau speichern, wie der Client es
geschickt hat.** Nicht zerlegen und neu zusammensetzen – sonst gehen
Eigenschaften verloren, die wir nicht kennen (Anhänge, Teilnehmerstatus,
Herstellerfelder), und beim nächsten Abgleich fehlt etwas, das vorher da war.
Die abgeleiteten Spalten sind nur zum Vorsortieren da.
## Phasen
| | Inhalt | Aufwand |
|---|---|---|
| **1** | CalDAV lesend und schreibend, ein Kalender, Anmeldung über App-Passwörter, Auffindpfade (`/.well-known/caldav`, `current-user-principal`, `calendar-home-set`). Ziel: DAVx5 gleicht ab. | 1–2 Abende |
| **2** | Mehrere Kalender, Farbe, Umbenennen, Löschen. Export als `.ics`, Import einer bestehenden Datei. | 1 Abend |
| **3** | Weboberfläche in Aether: Monat, Woche, Liste; Termin anlegen, ändern, löschen. Der Teil, der Spaß macht – und dessen Fehler man **sieht**. | 2–3 Abende |
| **4** | `sync-collection` statt Vollabgleich, Aufgaben (VTODO), Kalender in der HoneyOS-Leiste. | offen |
| **5** | Kontakte (CardDAV). Dieselbe Maschinerie, dieselbe Bibliothek – und **einfacher**, weil es dort keine Wiederholungen gibt. | später entscheiden |
## Was es ausdrücklich nicht wird
Keine Einladungen an andere Leute (iMIP/Scheduling), keine Frei/Belegt-Abfragen
über Häuser hinweg, kein Teilen zwischen Nutzern. Das ist der Teil, an dem
Groupware-Server groß und kompliziert werden. Ein Kalender für dich, auf allen
deinen Geräten – das ist das Ziel.
## Die Notausfahrt
Ein Kalender, der lautlos einen Termin verschluckt, ist schlimmer als einer,
der ausfällt. Deshalb:
- **Export als `.ics` je Kalender ist Teil von Phase 2, nicht später.** Solange
du deine Termine jederzeit herausbekommst, ist keine Entscheidung endgültig.
- Auf Wunsch zusätzlich als Verzeichnis mit einer Datei je Termin – das ist der
Aufbau, den Radicale liest. Umziehen wäre dann ein Kopiervorgang.
- Tests mit echten Anfragen, die DAVx5 stellt (mitgeschnitten, nicht erfunden),
und eine Prüfliste in `TESTING.md` fürs Telefon.
## Offene Fragen
1. Wie viele Kalender – einer, oder getrennt nach Privat/Arbeit/Geburtstage?
2. Aufgaben mit dazu (VTODO), oder reine Termine?
3. Der Kalender in der HoneyOS-Leiste: nur der nächste Termin, oder eine
eigene Kachel?
4. Kontakte: ernsthaft geplant oder erst mal offenlassen? Es ändert nichts an
Phase 1–3, nur an der Benennung der Pakete.