diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-02-17 14:43:42 -1000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-02-17 14:43:42 -1000 |
| commit | ec7d895c00c571b37ad9255b99b2e1756776c9e1 (patch) | |
| tree | 31f8a925375fd5b00ee5febfe5d83f35487b1dd3 /internal/handlers/handlers.go | |
| parent | 44fa97ce901bbfc5957e6d9ba90a53086bb5950b (diff) | |
Add calendar cache layer, incremental sync tests, completion assertions
- Google Calendar events now cached via CacheFetcher pattern with
stale-cache fallback on API errors (new migration 015, store methods,
fetchCalendarEvents handler, BuildTimeline reads from store)
- Todoist incremental sync path covered by 5 new tests
- Task completion tests assert response body, headers, and template data
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/handlers/handlers.go')
| -rw-r--r-- | internal/handlers/handlers.go | 23 |
1 files changed, 18 insertions, 5 deletions
diff --git a/internal/handlers/handlers.go b/internal/handlers/handlers.go index 876326e..e06c35e 100644 --- a/internal/handlers/handlers.go +++ b/internal/handlers/handlers.go @@ -267,7 +267,7 @@ func (h *Handler) aggregateData(ctx context.Context, forceRefresh bool) (*models if h.googleCalendarClient != nil { fetch("Google Calendar", func() error { - events, err := h.googleCalendarClient.GetUpcomingEvents(ctx, 10) + events, err := h.fetchCalendarEvents(ctx, false) if err == nil { mu.Lock() data.Events = events @@ -450,6 +450,22 @@ func (h *Handler) fetchMeals(ctx context.Context, forceRefresh bool) ([]models.M return fetcher.FetchWithCache(ctx, forceRefresh) } +// fetchCalendarEvents fetches Google Calendar events from cache or API +func (h *Handler) fetchCalendarEvents(ctx context.Context, forceRefresh bool) ([]models.CalendarEvent, error) { + if h.googleCalendarClient == nil { + return nil, nil + } + fetcher := &CacheFetcher[models.CalendarEvent]{ + Store: h.store, + CacheKey: store.CacheKeyGoogleCalendar, + TTLMinutes: h.config.CacheTTLMinutes, + Fetch: func(ctx context.Context) ([]models.CalendarEvent, error) { return h.googleCalendarClient.GetUpcomingEvents(ctx, 50) }, + GetFromCache: h.store.GetCalendarEvents, + SaveToCache: h.store.SaveCalendarEvents, + } + return fetcher.FetchWithCache(ctx, forceRefresh) +} + // fetchBoards fetches Trello boards from cache or API func (h *Handler) fetchBoards(ctx context.Context, forceRefresh bool) ([]models.Board, error) { fetcher := &CacheFetcher[models.Board]{ @@ -999,10 +1015,7 @@ func (h *Handler) HandleTabPlanning(w http.ResponseWriter, r *http.Request) { boards, _ := h.store.GetBoards() tasks, _ := h.store.GetTasks() - var events []models.CalendarEvent - if h.googleCalendarClient != nil { - events, _ = h.googleCalendarClient.GetUpcomingEvents(r.Context(), 20) - } + events, _ := h.fetchCalendarEvents(r.Context(), false) var scheduled []ScheduledItem var unscheduled []models.Atom |
