feat: support safe recurrence additions
Parse, persist, expand, and round-trip compatible RDATE values while preserving whole-series TUI behavior and conservative rewrite guards. Verified: normal, warning-as-error, and ASan/UBSan builds pass all 9 suites; storage failure paths preserve calendar and backup bytes; live PTY restores terminal state.
This commit is contained in:
@@ -36,8 +36,11 @@ requested time window and return values that point back to their source series,
|
||||
preserving series-level storage and mutation semantics. The supported rule
|
||||
surface is deliberately bounded to daily/weekly/monthly/yearly frequency,
|
||||
interval, count or until, weekly `BYDAY`, monthly `BYMONTHDAY`, yearly
|
||||
`BYMONTH`, and `EXDATE`. Invalid metadata retains at most the base event rather
|
||||
than crashing a render.
|
||||
`BYMONTH`, compatible DATE or DATE-TIME `RDATE`, and `EXDATE`. An occurrence set
|
||||
merges `DTSTART`, rule expansion, and additional `RDATE` starts, deduplicates by
|
||||
start, and then subtracts exclusions. Mutations continue to address the source
|
||||
series as a whole. Invalid metadata retains at most the base event rather than
|
||||
crashing a render.
|
||||
|
||||
Search matching is a pure domain predicate over normalized event text; the TUI
|
||||
owns result presentation and occurrence identity. Recurring searches expand a
|
||||
@@ -107,12 +110,13 @@ combined with any of the other modes.
|
||||
|
||||
The current writer deliberately refuses to mutate an existing file when the
|
||||
loader encounters information it cannot round-trip, including recurrence
|
||||
overrides, `RDATE`, custom `VTIMEZONE` definitions, alarms, attendees, unknown
|
||||
properties, or malformed components. Supported recurrence rules, exclusions,
|
||||
and system IANA time-zone identifiers round-trip semantically. Browsing remains
|
||||
available for unsupported files. This conservative boundary is more important
|
||||
than partial editing because a successful-looking edit must not erase unrelated
|
||||
calendar data.
|
||||
overrides, `RDATE` periods or values incompatible with `DTSTART`'s time basis or
|
||||
`TZID`, custom `VTIMEZONE` definitions, alarms, attendees, unknown properties,
|
||||
or malformed components. Supported recurrence rules, compatible additional
|
||||
starts, exclusions, and system IANA time-zone identifiers round-trip
|
||||
semantically. Browsing remains available for unsupported files. This
|
||||
conservative boundary is more important than partial editing because a
|
||||
successful-looking edit must not erase unrelated calendar data.
|
||||
|
||||
Provider synchronization will not write directly into this UI file. It will use
|
||||
a transaction-capable local cache and preserve remote ETags/sync tokens in a
|
||||
|
||||
@@ -89,22 +89,28 @@ read-only instead of being discarded. Saves reject external changes, retain a
|
||||
last-known-good backup, and feed bounded session undo/redo history. Supported
|
||||
recurring instances appear throughout the month, preserve civil time across
|
||||
daylight-saving changes, and expose their source zone and whole-series mutation
|
||||
semantics in the reader. `/` searches occurrence-aware title, description,
|
||||
location, and calendar-ID matches in a finite ten-year window centered on the
|
||||
selected date. `c` toggles session-only calendar visibility consistently across
|
||||
the grid, appointment focus, and search without filtering the model supplied to
|
||||
persistence. `g` opens an occurrence-aware agenda at the selected month date;
|
||||
navigation is bounded to consecutive 42-day windows and `Enter` returns to the
|
||||
exact occurrence in the month grid. `Esc` or `g` closes the agenda without
|
||||
changing the month selection unless an occurrence was chosen. Hidden calendars
|
||||
remain filtered there, while calendar selection and search can overlay the
|
||||
agenda. Agenda navigation never persists state, and add/edit/delete remain in
|
||||
the month workflow. Week-start selection rotates only the month grid, header,
|
||||
and the visible range used by its month queries; storage, agenda windows, and
|
||||
semantics in the reader. A supported recurrence set combines `DTSTART`, rule
|
||||
expansion, and compatible DATE or DATE-TIME `RDATE` starts, deduplicates starts,
|
||||
and then removes `EXDATE` exclusions. `/` searches occurrence-aware title,
|
||||
description, location, and calendar-ID matches in a finite ten-year window
|
||||
centered on the selected date. `c` toggles session-only calendar visibility
|
||||
consistently across the grid, appointment focus, and search without filtering
|
||||
the model supplied to persistence. `g` opens an occurrence-aware agenda at the
|
||||
selected month date; navigation is bounded to consecutive 42-day windows and
|
||||
`Enter` returns to the exact occurrence in the month grid. `Esc` or `g` closes
|
||||
the agenda without changing the month selection unless an occurrence was
|
||||
chosen. Hidden calendars remain filtered there, while calendar selection and
|
||||
search can overlay the agenda. Agenda navigation never persists state, and
|
||||
add/edit/delete remain in the month workflow. Week-start selection rotates only
|
||||
the month grid, header, and the visible range used by its month queries;
|
||||
storage, agenda windows, and
|
||||
recurrence rules are unchanged. The default remains Monday for backward
|
||||
compatibility. The CLI accepts the exact lowercase values `monday`, `tuesday`,
|
||||
`wednesday`, `thursday`, `friday`, `saturday`, and `sunday`. The next local-data
|
||||
work adds advanced recurrence overrides and rule editing.
|
||||
`wednesday`, `thursday`, `friday`, `saturday`, and `sunday`. `RDATE` periods,
|
||||
values incompatible with the event's `DTSTART` time basis or `TZID`, detached
|
||||
`RECURRENCE-ID` overrides, and embedded `VTIMEZONE` definitions remain
|
||||
read-only. Remaining local-data work includes detached overrides and rule
|
||||
editing.
|
||||
|
||||
## Local file interchange
|
||||
|
||||
|
||||
@@ -8,7 +8,8 @@
|
||||
- Validated add/edit/delete forms with confirmation and failure rollback
|
||||
- Guarded atomic `.ics` persistence, advisory locking, and round-trip tests
|
||||
- Bounded session undo/redo, exact external-change detection, and backup recovery
|
||||
- Windowed recurrence expansion, EXDATE, IANA TZID, and multi-day segment cues
|
||||
- Windowed recurrence expansion, compatible RDATE, EXDATE, IANA TZID, and
|
||||
multi-day segment cues
|
||||
- Occurrence-aware appointment search with exact result-to-grid navigation
|
||||
- Session calendar toggles shared by month rendering, focus, and search
|
||||
- Read-only 42-day agenda with bounded recurrence and exact return navigation
|
||||
@@ -19,7 +20,8 @@
|
||||
|
||||
## 0.1 — complete local calendar
|
||||
|
||||
- Advanced recurrence editing, RDATE/overrides, and embedded VTIMEZONE support
|
||||
- Advanced recurrence rule editing and detached RECURRENCE-ID overrides
|
||||
- Embedded VTIMEZONE support
|
||||
- Screen-reader-friendly linear view and full Unicode display-width handling
|
||||
|
||||
## 0.2 — durable cache and provider boundary
|
||||
|
||||
Reference in New Issue
Block a user