Commit Graph
4 Commits
Author SHA1 Message Date
Lucas Berger a9d3de658e fix(03): correct event-write timezone + per-user calendar identity (Gate 2 Part D)
BUG A — timed events written 4h off: EventForm sent a naive local wall-clock
string with no offset; the UTC API container parsed it via new Date() as UTC, so
09:00 America/Toronto serialized to DTSTART:...090000Z. Fix: new
apps/pwa/src/lib/eventDateTime.ts serializes timed events to an unambiguous UTC
instant in the browser (where the operator's zone is known); all-day stays a DATE
string. No backend change.

BUG B — created events attached to the wrong user's calendar + duplicate calendar
rows per poll: calendars had no unique key on url, and poller/sync matched
calendars by url alone — so under the shared single Fastmail account (D-16) one
member's collection resolved to the other member's row. Fix: composite
unique(user_id, url); scope poller lookup + sync select to (userId, url); hand
migration 0001 (dedup + add key), applied to the live DB.

Regression tests fail against the buggy url-only predicate. API 98/98, PWA 140/140,
tsc clean both packages.
2026-06-06 22:32:10 -04:00
Lucas Berger 0c0bcefeef feat(03-01): populate calendarEvents.objectUrl in sync.ts from obj.url
- Set objectUrl: obj.url ?? null in both .values() and .onDuplicateKeyUpdate({ set: {} })
  alongside existing etag assignment — stores CalDAV object URL for If-Match on
  update/delete (D-08)
- All existing broker/sync tests pass (47 total)
2026-06-05 17:23:06 -04:00
Lucas Berger f70496871a fix(02): populate hasRrule on every sync upsert so recurring masters are flagged
- Use ICAL.Event.isRecurring() (parity with expand.ts) to detect RRULE/RDATE
- Add hasRrule to .values() INSERT and .onDuplicateKeyUpdate() SET so the flag
  is set on first sync and self-heals on every subsequent re-sync
- Without this fix every event had has_rrule=0 (column default), causing the
  events route recurring-master pre-filter to return zero recurring occurrences
- Add sync.test.ts cases: hasRrule=true for timed+all-day recurring VEVENTs,
  hasRrule=false for non-recurring, and hasRrule in onDuplicateKeyUpdate.set
2026-06-05 14:50:18 -04:00
Lucas Berger dd02207318 feat(01-03): implement broker client, syncCalendar, and events route (CAL-01)
- client.ts: createFastmailClient(email, appPassword) → tsdav DAVClient via Basic auth
- sync.ts: syncCalendar upserts calendar row, selects ID, fetches+parses VEVENTs with ical.js
  - all-day DATE → dtstartDate (Date obj at T00:00:00Z), dtstartUtc=null, allDay=true
  - timed → dtstartUtc (JS Date), dtstartDate=null, allDay=false (D-13/Pitfall #3)
  - onDuplicateKeyUpdate on calendarId+uid composite key (idempotent)
- routes/events.ts: GET /api/events reads cache only — no tsdav import (T-03-02)
- tsc --noEmit clean; all 6 sync tests pass
2026-06-04 10:33:28 -04:00