fix(caldav): point-event round-trip, recurrence push, delete propagation
CI & Build / Python lint (push) Successful in 2s
CI & Build / TypeScript typecheck (push) Successful in 36s
CI & Build / Python tests (push) Successful in 48s
CI & Build / Build & push image (push) Successful in 1m16s

Drift-audit Group 5 #7/#8 + Group 7 (CalDAV write-path):

- Point events no longer fabricate a 60-min DTEND: caldav.create_event emits
  DTSTART-only when there's no end and no duration, so the next pull doesn't
  read it back as duration_minutes=60 and silently lengthen the event.
- Recurrence edits now propagate: caldav.update_event gains a recurrence param
  (sentinel = leave unchanged; value/empty = set/clear RRULE), and _push_update
  passes the local event's rule so a changed/cleared RRULE isn't overwritten
  by the stale remote rule on the next pull.
- Event deletions propagate to CalDAV: trash.delete captures an event's
  caldav_uid before soft-deleting and fires _push_delete, so a UI/MCP delete
  removes the remote copy instead of leaving it to linger. (delete_event the
  service primitive is kept — still tested/usable — rather than removed.)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-02 19:20:14 -04:00
co-authored by Claude Opus 4.8
parent c016bd664e
commit 2fd9a2300a
3 changed files with 56 additions and 6 deletions
+3
View File
@@ -450,6 +450,9 @@ async def _push_update(event: Event, user_id: int, old_title: str = "") -> None:
end=derived_end.isoformat() if derived_end else None,
description=event.description or None,
location=event.location or None,
# Propagate the (possibly cleared) RRULE so a local recurrence edit
# isn't overwritten by the stale remote rule on the next pull.
recurrence=event.recurrence,
)
except Exception:
logger.warning("CalDAV push (update) failed for event %d", event.id, exc_info=True)