Bounded CalDAV REPORT Calendar-Query & Timezone Expansion #8
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Implement bounded CalDAV
REPORTcalendar-queryqueries against Radicale, performing server-side recurrence expansion via<C:expand>, strict half-open interval[from, to)calculation in a mandatory configured IANA timezone, tagged date/instant representations, and strict query limit enforcement (maximum 93 days, maximum 10,000 expanded instances) with fail-fast error semantics.Background & Technical Rationale
Server-Side Recurrence Expansion as the Primary Engine:
Expanding recurring iCalendar events (
RRULE,RDATE,EXDATE, detached overrides) client-side is notoriously error-prone, bug-ridden, and risks subtle divergence from standard calendar clients. As specified indocs/technical/calendar.md,life-servicedoes not implement a speculative local recurrence expansion engine. Instead, bounded server-side expansion via CalDAV RFC 4791REPORTwith<C:expand start="..." end="..."/>is the authoritative recurrence engine.Mandatory IANA Timezone & Half-Open Temporal Intervals:
Australia/Brisbane,America/New_York) is mandatory. If the timezone is missing or invalid, configuration validation halts startup. Falling back to the host machine's timezone, IP geolocation, or fixed UTC offsets is strictly forbidden.today,tomorrow,week) must be calculated in the configured local calendar time first, then converted to UTC instants. For example,weekstarts at Monday 00:00:00 local time and ends at the following Monday 00:00:00 local time. Because of Daylight Saving Time (DST) transitions, a local calendar day or week may not contain 24 hours or 168 hours.[from, to): All time ranges are half-open: inclusive of the start instant, exclusive of the end instant. A human expression like "through Friday" resolves to Saturday at 00:00:00 local midnight.DATEtypes (DTSTART:20300408,DTEND:20300409). In accordance with RFC 5545,DTENDis exclusive: an event spanning April 8 starts at20300408and ends at20300409. It occupies April 8 only.Strict Query Limits & Denial-of-Service Defense:
Infinite recurrence series and unbounded queries can easily overwhelm the server memory and network bandwidth.
limit_exceeded(HTTP 422 / CLI exit code 2) with instructions to query a narrower window. It must never silently truncate results.Ambiguity and DST Transitions:
Dependency Unavailability vs Empty State (Scenario C01):
A failed network call or unreachable Radicale server MUST return
dependency_unavailable(HTTP 503 / CLI exit code 5). Memory or cached text is never a fallback authority: an unavailable calendar must never be reported as an empty agenda.Exact Technical References & Specifications
Normative Quotations from Technical Architecture
From
docs/technical/calendar.md(Query and time semantics, lines 15–28):From
docs/technical/calendar.md(Recurrence and mutation, lines 29–36):From
docs/technical/cli-api.md(Error identifiers, lines 118–120):From
docs/technical/verification.md(Calendar scenarios, lines 33–42):Protocol Specifications & XML Envelopes
1. Bounded
REPORT calendar-queryRequest Envelope (RFC 4791)2. Expected
207 Multi-Statuswith Expanded ICS Data3. Error JSON Response:
limit_exceeded4. Error JSON Response:
dependency_unavailable(Scenario C01)What to Build (Step-by-Step)
1. Timezone & Range Calculation (
src/calendar/timezone.rs)CalendarTimezone:chrono_tz::Tz, parsed strictly from[radicale.timezone].period_today(tz: Tz, now_utc: DateTime<Utc>) -> HalfOpenInterval: Local midnight today to local midnight tomorrow.period_tomorrow(tz: Tz, now_utc: DateTime<Utc>) -> HalfOpenInterval: Local midnight tomorrow to local midnight day after tomorrow.period_week(tz: Tz, now_utc: DateTime<Utc>) -> HalfOpenInterval: Local Monday 00:00:00 to following Monday 00:00:00.from_to(start: DateTime<Utc>, end: DateTime<Utc>) -> Result<HalfOpenInterval, TimeError>:start < end.(end - start) > 93 days, returnTimeError::LimitExceeded("Query range exceeds 93 days").chrono::TimeZone::from_local_datetime.invalid_inputexplaining that the local time does not exist due to DST transition.2. CalDAV
REPORTXML Builder (src/calendar/report.rs)build_calendar_query_xml(interval: &HalfOpenInterval, component_types: &[ComponentKind]) -> String:<C:calendar-query>requesting<D:getetag/>and<C:calendar-data>.<C:expand start="YYYYMMDDTHHMMSSZ" end="YYYYMMDDTHHMMSSZ"/>.<C:comp-filter name="VCALENDAR">with child<C:comp-filter name="VEVENT">and/orVTODOcontaining<C:time-range start="..." end="..."/>.CalDavClient:REPORTto collection URL with headerDepth: 1andContent-Type: application/xml; charset=utf-8.CalDavError::DependencyUnavailable.3. Response Parsing & Instance Count Enforcement (
src/calendar/expansion.rs)207 Multi-Statusresponse usingquick-xml:<D:response>, identifying the resourcehref,D:getetag, and<C:calendar-data>.ical::PropertyParserinto individual expandedVEVENTandVTODOcomponents.CalDavError::LimitExceeded("Expanded instance count exceeded 10,000").VALUE=DATE): parseDTSTARTandDTENDasNaiveDate. EnsureDTENDis treated as exclusive.DateTime<Utc>.CalendarTimezone.RECURRENCE-IDif present, including its timezone identity.Acceptance Criteria
[radicale]fails startup withconfiguration_invalid; the system never falls back to local machine timezone.today,tomorrow, andweekresolve to exact local-midnight-to-local-midnight half-open intervals in the configured timezone, converted accurately to UTC.DTSTART:20300408andDTEND:20300409is normalized such that it occupies strictly April 8, ending at local midnight on April 9.clarification_required/invalid_input.limit_exceeded(HTTP 422, exit code 2) with instructions to query a narrower range.limit_exceeded.dependency_unavailable(HTTP 503, exit code 5); it never returns an empty agenda (items: []).REPORTXML payload contains<C:expand start="..." end="..."/>and correctly normalizes expanded occurrences returned by Radicale.Blocked by
Issue #008: Bounded CalDAV REPORT Calendar-Query & Timezone Expansionto Bounded CalDAV REPORT Calendar-Query & Timezone Expansion