feat(02-03): hydrateEvents + calendarStore + windowed fetchEvents; RED stubs green

- Create hydrateEvents.ts: Temporal.PlainDate for allDay, ZonedDateTime for timed
  calendarId routes via isShared ? 'shared' : String(ownerUserId) — NOT String(calendarId)
  _familySync carries uid/color/isShared through to popover
- Update hydrateEvents.test.ts: add temporal-polyfill/global import; all 4 RED stubs now GREEN
- Create calendarStore.ts: Zustand store with selectedView (localStorage per breakpoint group),
  selectedDate, openEventId, calendarRange; D-05 view defaults; calendarRange ± buffer for
  initial TanStack Query key without depending on onRangeUpdate firing on mount
- Update client.ts: add CalendarOccurrence/OccurrencesResponse, windowed fetchEvents(start,end)
  with credentials:include; keep legacy CalendarEvent/EventsResponse + fetchEventsLegacy
  as deprecated for EventProof.tsx (removed in Plan 05)
- Update EventProof.tsx: switch to fetchEventsLegacy to keep build clean until Plan 05
- tsc --noEmit clean; all 18 PWA tests pass
This commit is contained in:
Lucas Berger
2026-06-05 09:47:07 -04:00
parent 43554f491b
commit f377d7c3f8
5 changed files with 303 additions and 13 deletions
+5 -3
View File
@@ -14,7 +14,9 @@
*/
import { useQuery } from '@tanstack/react-query'
import { fetchEvents, type CalendarEvent } from '../api/client'
// fetchEventsLegacy: Phase 1 broker-proof; replaced by windowed fetchEvents in Plan 04.
// This component is removed in Plan 05.
import { fetchEventsLegacy, type CalendarEvent } from '../api/client'
import ICAL from 'ical.js'
/**
@@ -57,8 +59,8 @@ function formatDate(event: CalendarEvent): string {
export function EventProof() {
const eventsQuery = useQuery({
queryKey: ['events'],
queryFn: fetchEvents,
queryKey: ['events-legacy'],
queryFn: fetchEventsLegacy,
retry: false,
staleTime: 5 * 60 * 1000, // 5 min — matches broker poll interval
})