blob: f3a1f3bc56a2cdb149b67289b97370abedf3f2d9 (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
# [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
|