# [FEATURE] Add Google Calendar support ## Description Add Google Calendar support. ## User Story As a user, I want my Google Calendar events displayed so I have a unified daily view. ## Technical Context - New integration following existing patterns in `internal/api/` - OAuth2 flow required; store refresh token in `sync_tokens` table - New partial for calendar events display ## Test Strategy ### Unit Test (Red) **File:** `internal/api/gcal_test.go` ```go func TestParseCalendarEvents(t *testing.T) { // Mock Google Calendar API response // Assert events parsed correctly with title, time, all-day flag } func TestGCalClient_FetchEvents(t *testing.T) { // Mock HTTP client // Assert correct API calls made // Assert events returned in expected format } ``` ### Integration Test (Red) Test cache/store roundtrip for events. ```go func TestGCalEventsCache(t *testing.T) { // Store events in cache // Retrieve from cache // Assert data integrity } ``` ## Proposed Approach 1. **OAuth Setup:** - Add `GOOGLE_CLIENT_ID`, `GOOGLE_CLIENT_SECRET` to config - Implement OAuth2 flow with PKCE - Store refresh token in `sync_tokens` table 2. **API Client:** - Create `internal/api/gcal.go` implementing interface pattern from existing clients - Use `google.golang.org/api/calendar/v3` - Fetch events for configurable date range (default: today + 7 days) 3. **Data Model:** - Add `calendar_events` table or reuse existing structure - Handle all-day vs timed events 4. **UI:** - New partial: `partials/gcal-events.html` - Integrate into existing tabs or new calendar tab ## Traps to Avoid - **All-day events:** Google returns these differently (date vs dateTime) - **Timezone:** Events have their own timezone; convert to user's local - **Recurring events:** Decide whether to expand or show as single item - **Token refresh:** Handle expired access tokens gracefully ## Affected Components - `internal/api/gcal.go` (new) - `internal/api/gcal_test.go` (new) - `internal/api/interfaces.go` (add interface) - `internal/config/config.go` - `internal/store/sqlite.go` (new table/queries) - `web/templates/partials/gcal-events.html` (new) - `cmd/dashboard/main.go` (wire up client) ## Definition of Done - [ ] OAuth2 flow authenticates with Google - [ ] Events fetched from Google Calendar API - [ ] Events cached in SQLite - [ ] Events displayed in UI - [ ] All-day and timed events handled correctly - [ ] Token refresh works - [ ] Unit and integration tests pass