summaryrefslogtreecommitdiff
path: root/docs/adr/002-timeline-aggregation.md
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-02-05 10:37:09 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-02-05 10:37:09 -1000
commit223c94f52ebaa878f6951ebf7d08754e413bdca7 (patch)
treefc02a201fb83ec49fd5978d2ec9bf79f83e5d57c /docs/adr/002-timeline-aggregation.md
parent4ac78382343e14c00ba21ee11ee4642255509eef (diff)
Document multi-agent workflow, ADRs, and Agent API
- Add Development Workflow section to DESIGN.md documenting three-role system (Architect, Implementor, Reviewer) with handoff documents - Update CLAUDE.md with Key Documents section pointing to DESIGN.md, role definitions, and ADRs - Add ADR-first documentation policy across all role definitions - Update REVIEWER_ROLE.md with comprehensive test quality checklist - Document Agent API and completed tasks log in DESIGN.md - Update database schema table with 5 missing tables - Update endpoint reference with 10 missing routes - Create ADRs 002-005 capturing key architectural decisions: - 002: Timeline aggregation architecture - 003: HTMX write operations pattern - 004: Concurrent data fetching with graceful degradation - 005: Agent API notification-based authentication - Add migrations/README.md documenting schema history and 007 gap Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Diffstat (limited to 'docs/adr/002-timeline-aggregation.md')
-rw-r--r--docs/adr/002-timeline-aggregation.md76
1 files changed, 76 insertions, 0 deletions
diff --git a/docs/adr/002-timeline-aggregation.md b/docs/adr/002-timeline-aggregation.md
new file mode 100644
index 0000000..2700776
--- /dev/null
+++ b/docs/adr/002-timeline-aggregation.md
@@ -0,0 +1,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