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
|
# ADR 002: Timeline Aggregation Architecture
## Status
Accepted
## Context
The dashboard aggregates data from multiple sources (Todoist, Trello, PlanToEat, Google Calendar, Google Tasks). Users need a unified chronological view of upcoming items across all sources without opening multiple apps.
Key challenges:
- Different data sources have different models (Task, Card, Meal, Event)
- Some sources have time-of-day, others only have dates
- Meals have no explicit time but should appear at logical meal times
- Need to support grouping by day section (Today, Tomorrow, Later)
## Decision
Implement a **polymorphic TimelineItem model** that normalizes all data sources into a single sortable structure.
### Technical Details:
**Unified Model (`internal/models/timeline.go`):**
```go
type TimelineItem struct {
ID string
Type TimelineItemType // task, meal, card, event, gtask
Title string
Description string
Time time.Time
AllDay bool
URL string
DaySection string // overdue, today, tomorrow, later
// ... additional fields
}
```
**Meal Time Defaults:**
- Breakfast → 08:00
- Lunch → 12:00
- Dinner → 19:00
- Other → 12:00
**Implementation:**
- `internal/handlers/timeline_logic.go` - `BuildTimeline()` aggregation function
- `internal/handlers/timeline.go` - HTTP handler
- `internal/models/timeline.go` - Data models
- Store methods: `GetTasksByDateRange()`, `GetMealsByDateRange()`, `GetCardsByDateRange()`
**Grouping Strategy:**
Items are grouped into collapsible day sections:
- **Overdue** - Past due items (expanded)
- **Today** - Due today (expanded)
- **Tomorrow** - Due tomorrow (expanded)
- **Later** - 2+ days out (collapsed by default)
## Consequences
**Pros:**
- Single unified view reduces context switching
- Consistent sorting regardless of data source
- Extensible - new sources just need a converter to TimelineItem
- Collapsible sections reduce cognitive load
**Cons:**
- Meal times are assumed, not actual (user might eat breakfast at 10am)
- All-day items appear at midnight, requiring special handling
- Multiple API calls per request (mitigated by caching)
## Alternatives Considered
**Option A: Source-specific views only**
- Rejected: Defeats the purpose of a unified dashboard
**Option B: Store normalized items in database**
- Rejected: Adds complexity, staleness issues, harder to keep in sync
**Option C: Client-side aggregation (JavaScript)**
- Rejected: More complex, slower on mobile, harder to test
|