Project safe calendar BYDAY recurrences (#569) - #545
Conversation
|
Approach for #569: keep Google's expanded occurrence starts from the 60 day event list on each recurring item. In |
There was a problem hiding this comment.
Important
The current projection can expose recurrences that installed clients cannot import faithfully and can approve schedules that drift after the 60-day evidence window.
Reviewed changes I reviewed the full three-commit diff for calendar projection, internal recurrence evidence storage, and its focused coverage.
- Expanded occurrence evidence — Collects recurrence-defined starts from Google's expanded feed and carries them through live events and stored suggestions.
- RRULE projection — Shifts plain daily and weekly
BYDAYtokens across account dates, includingWKSTfor alternate-week rules. - Compatibility storage — Keeps the new evidence out of the response DTO and refreshes legacy timed recurrence rows that lack it.
- Tests — Covers serialization, live and suggestion feed agreement, unsupported rule forms, seasonal clock changes, and alternate-week projection.
GPT Sol | 𝕏
left a comment
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes I reviewed the importer compatibility and timezone stability fixes added since the prior Pullfrog review.
- Normalized importer-facing rules: Rewrote weekly interval-one
BYDAYrules as equivalent daily rules that installed clients can import with weekday filters. - Restricted admitted RRULEs: Rejected unsupported selectors, multi-day interval rules, and inconsistent recurrence anchors while preserving representable single-day interval rules.
- Proved year-round stability: Required shifted rules to keep one projected clock and date offset across the full timezone adjustment cycle in addition to the bounded provider evidence.
- Strengthened regression coverage: Added exact tests for normalized cadence, unsupported rule terms, inconsistent anchors, and drift beyond the provider fetch window.
GPT Sol | 𝕏
commented
Sep 25, 2026
|
left a comment
There was a problem hiding this comment.
✅ No new issues found.
Reviewed changes I reviewed the merge-forward integration added since the prior Pullfrog review.
- Preserved recurrence evidence: Kept expanded occurrence starts in stored suggestion rows and restored them when those rows are read.
- Integrated recurrence timezone responses: Reconstructed
recurrenceTimeZonefrom the recurring master's stored source timezone for timed recurring suggestions while keeping server-only evidence off the response. - Strengthened serialization coverage: Verified the public response exposes only
recurrenceTimeZoneand stored rows retain both recurrence evidence and the response field. - Retained fetcher coverage: Preserved assertions for expanded recurrence-defined starts alongside the merged recurrence timezone behavior.
GPT Sol | 𝕏




Closes thomasluizon/orbit-tickets#569
Change
Return daily and weekly calendar events with plain
BYDAYwhen every Google expanded occurrence in the existing 60 day feed keeps one date shift and displayed start time. ShiftBYDAYto the account weekdays. For alternate week rules, shiftWKSTtoo, including its Monday default, so the week cycle stays aligned. Keep ordinal weekdays,BYSETPOS,BYMONTHDAY, and nonuniform projections omitted. Store the expanded starts with sync suggestions so both import feeds make the same decision. These evidence fields remain absent from the response contract.Assumptions
BYDAY; rejected changing only the weekday tokens because that changes week parity.Weekly interval-one rules become equivalent daily rules with
BYDAY; multi-day alternate-week rules remain withheld. PR Project safe calendar BYDAY recurrences (#569) #545 currently saysCloses #569, which points to the wrong repository.External interface evidence
The installed
Google.Apis.Calendar.v31.75.0.4206 assembly was inspected with reflection.Event.OriginalStartTimeandEvent.StartareEventDateTime;Event.RecurringEventId,Event.Status, andEvent.Summaryare strings;EventDateTime.DateTimeDateTimeOffsetis nullableDateTimeOffset. To reproduce, inspect those properties withtypeof(Event).GetProperty(name)?.PropertyTypeafter referencing that package version. Its installedGoogle.Apis.Calendar.v3.xmldescribesOriginalStartTimeas the recurrence-defined start even when an instance moves.GoogleCalendarApi.ListEventsAsyncalready requests expanded instances for 60 days and follows all pages.Test evidence
LC_ALL=en_US.UTF-8 dotnet test tests/Orbit.Application.Tests/Orbit.Application.Tests.csproj --filter 'FullyQualifiedName~Handle_RecurringByDayEventCrossingAccountDate_OmitsEvent' -v normalpassed with the event omitted.LC_ALL=en_US.UTF-8 dotnet test tests/Orbit.Application.Tests/Orbit.Application.Tests.csproj --filter 'FullyQualifiedName~Handle_RecurringByDayEventCrossingAccountDate_ShiftsWeekdays' --no-build -v minimalfailed because the result was empty.LC_ALL=en_US.UTF-8 dotnet test tests/Orbit.Application.Tests/Orbit.Application.Tests.csproj --filter 'FullyQualifiedName~Handle_RecurringByDayEventCrossingAccountDate_ShiftsWeekdays' --no-restore -v minimalpassed. The calendar group passed 225 tests before the final alternate week test was added; that focused test then passed.LC_ALL=en_US.UTF-8 dotnet build Orbit.slnx -v quietpassed with 0 errors.LC_ALL=en_US.UTF-8 dotnet test -v quietpassed 6,387 tests.BYSETPOS,BYMONTHDAY, and nonuniform omission cases could not fail before implementation because the baseline already omitted shiftedBYDAYevents. They now have explicit controls with expanded occurrence evidence.ReminderSchedulerServiceTests.CheckAndSendReminders_TwoSameDayScheduledReminders_PersistsBothWithoutUniqueViolationat 00:00 UTC, before its 00:01 reminder was due. The full suite passed after 00:01 UTC without code changes.LC_ALL=en_US.UTF-8 dotnet build Orbit.slnx -v quiet: 0 errors.LC_ALL=en_US.UTF-8 dotnet test -v quiet: 6,411 passed, 0 failed.StoredCalendarEventJson.cskeepsExpandedOccurrencesUtcand theRecurrenceTimeZoneprojection; the serialization test now assertsEurope/Lisbonappears only asrecurrenceTimeZone; the fetcher test keeps both sides' assertions).dotnet build Orbit.slnx: 0 errors. Focused: 238 calendar tests and 16 fetcher tests pass.LANG=en_US.UTF-8 LC_ALL=en_US.UTF-8. Under this Mac's default locale nine formatting tests fail, none in the merged files; CI runs en_US.Manual steps
None.