feat(calendar): Phase 2 – mehrere Kalender, Export/Import als .ics
Neuer APIHandler unter /api/v1/calendars (Session-Auth, wie der Rest
der API) neben dem bestehenden CalDAV-Handler (App-Passwörter,
/caldav/) – zwei Handler, zwei Auth-Modelle, wie schon bei /dav.
- GET/POST /api/v1/calendars – Liste, Anlegen
- PATCH/DELETE /api/v1/calendars/{id} – Umbenennen, Farbe, Zeitzone,
Löschen (go-webdav kennt PROPPATCH und Kalender-Löschen nicht – dafür
gibt's im CalDAV-Protokoll selbst keinen Weg)
- GET .../export – alle Termine eines Kalenders als eine .ics-Datei,
VTIMEZONE-Blöcke dedupliziert
- POST .../import – .ics mit mehreren VEVENT/VTODO einlesen, jede
Komponente wird ein eigenes Objekt wie bei einem einzelnen CalDAV-PUT
Gegen den laufenden Container getestet (Session-Login, CSRF-Token):
Anlegen, Umbenennen, zwei Termine importieren, sauberer Re-Export,
Löschen, und dass ohne Login 401 statt Daten kommt.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3f1b2b8a14
commit
4d635fff20
3 files changed
+284
No files matched your search
@@ -91,6 +91,31 @@ func (s *Store) CreateCalendar(ctx context.Context, ownerID uuid.UUID, name, col
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
// UpdateCalendar ändert Name/Farbe/Beschreibung/Zeitzone. Ein nil-Feld lässt
|
||||
// die bestehende Spalte unangetastet – so kann der Aufrufer nur das Feld
|
||||
// schicken, das sich wirklich ändert, ohne vorher den ganzen Datensatz zu
|
||||
// laden.
|
||||
func (s *Store) UpdateCalendar(ctx context.Context, ownerID, id uuid.UUID, name, color, description, timezone *string) (*Calendar, error) {
|
||||
var c Calendar
|
||||
err := s.db.QueryRow(ctx,
|
||||
`UPDATE cal_calendars SET
|
||||
name = COALESCE($3, name),
|
||||
color = COALESCE($4, color),
|
||||
description = COALESCE($5, description),
|
||||
timezone = COALESCE($6, timezone)
|
||||
WHERE owner_id = $1 AND id = $2
|
||||
RETURNING id, owner_id, name, color, description, supports_todo, timezone, ctag, created_at`,
|
||||
ownerID, id, name, color, description, timezone,
|
||||
).Scan(&c.ID, &c.OwnerID, &c.Name, &c.Color, &c.Description, &c.SupportsTodo, &c.TimeZone, &c.CTag, &c.CreatedAt)
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return nil, ErrNotFound
|
||||
}
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("update calendar: %w", err)
|
||||
}
|
||||
return &c, nil
|
||||
}
|
||||
|
||||
func (s *Store) DeleteCalendar(ctx context.Context, ownerID, id uuid.UUID) error {
|
||||
tag, err := s.db.Exec(ctx, `DELETE FROM cal_calendars WHERE owner_id = $1 AND id = $2`, ownerID, id)
|
||||
if err != nil {
|
||||
|
||||
Reference in new issue
Block a user