Files
Aether/backend/internal/calendar/model.go
T
marcandClaude Sonnet 5 87788817f8 feat(calendar): Phase 1 – CalDAV lesend und schreibend, ein Kalender pro Nutzer
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>
2026-09-03 22:27:33 +02:00

42 lines
1.5 KiB
Go
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.
// Package calendar ist ein eigenständiges Modul, kein Kernbestandteil:
// CalDAV für Termine und Aufgaben. Es importiert nichts aus files, sharing
// oder admin – nur auth und acl, wie jeder andere Bereich auch. Ist es
// abgeschaltet, gibt es keine Route und keinen Menüpunkt; die Tabellen
// bleiben dann einfach ungenutzt liegen. Siehe kalender-plan.md.
package calendar
import (
"time"
"github.com/google/uuid"
)
// Calendar ist eine Sammlung von Terminen/Aufgaben – das, was ein Client als
// einen Kalender in seiner Liste zeigt.
type Calendar struct {
ID uuid.UUID `json:"id"`
OwnerID uuid.UUID `json:"owner_id"`
Name string `json:"name"`
Color string `json:"color"`
Description string `json:"description"`
SupportsTodo bool `json:"supports_todo"`
CTag int64 `json:"ctag"`
CreatedAt time.Time `json:"created_at"`
}
// Object ist ein einzelner Termin oder eine Aufgabe. Data ist die
// vollständige .ics-Datei, unverändert wie vom Client geschickt – siehe
// kalender-plan.md, Abschnitt "Felder".
type Object struct {
ID uuid.UUID `json:"id"`
CalendarID uuid.UUID `json:"calendar_id"`
UID string `json:"uid"`
Component string `json:"component"` // "VEVENT" | "VTODO"
Data string `json:"-"`
ETag string `json:"etag"`
DTStart *time.Time `json:"dtstart,omitempty"`
DTEnd *time.Time `json:"dtend,omitempty"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}