summaryrefslogtreecommitdiff
path: root/internal/models
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-01-12 09:27:16 -1000
committerPeter Stone <thepeterstone@gmail.com>2026-01-12 09:27:16 -1000
commit9fe0998436488537a8a2e8ffeefb0c4424b41c60 (patch)
treece877f04e60a187c2bd0e481e80298ec5e7cdf80 /internal/models
Initial commit: Personal Consolidation Dashboard (Phase 1 Complete)
Implemented a unified web dashboard aggregating tasks, notes, and meal planning: Core Features: - Trello integration (PRIMARY feature - boards, cards, lists) - Todoist integration (tasks and projects) - Obsidian integration (20 most recent notes) - PlanToEat integration (optional - 7-day meal planning) - Mobile-responsive web UI with auto-refresh (5 min) - SQLite caching with 5-minute TTL - AI agent endpoint with Bearer token authentication Technical Implementation: - Go 1.21+ backend with chi router - Interface-based API client design for testability - Parallel data fetching with goroutines - Graceful degradation (partial data on API failures) - .env file loading with godotenv - Comprehensive test coverage (9/9 tests passing) Bug Fixes: - Fixed .env file not being loaded at startup - Fixed nil pointer dereference with optional API clients (typed nil interface gotcha) Documentation: - START_HERE.md - Quick 5-minute setup guide - QUICKSTART.md - Fast track setup - SETUP_GUIDE.md - Detailed step-by-step instructions - PROJECT_SUMMARY.md - Complete project overview - CLAUDE.md - Guide for Claude Code instances - AI_AGENT_ACCESS.md - AI agent design document - AI_AGENT_SETUP.md - Claude.ai integration guide - TRELLO_AUTH_UPDATE.md - New Power-Up auth process Statistics: - Binary: 17MB - Code: 2,667 lines - Tests: 5 unit + 4 acceptance tests (all passing) - Dependencies: chi, sqlite3, godotenv Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Diffstat (limited to 'internal/models')
-rw-r--r--internal/models/types.go77
1 files changed, 77 insertions, 0 deletions
diff --git a/internal/models/types.go b/internal/models/types.go
new file mode 100644
index 0000000..d39a1d6
--- /dev/null
+++ b/internal/models/types.go
@@ -0,0 +1,77 @@
+package models
+
+import "time"
+
+// Task represents a task from Todoist
+type Task struct {
+ ID string `json:"id"`
+ Content string `json:"content"`
+ Description string `json:"description"`
+ ProjectID string `json:"project_id"`
+ ProjectName string `json:"project_name"`
+ DueDate *time.Time `json:"due_date,omitempty"`
+ Priority int `json:"priority"`
+ Completed bool `json:"completed"`
+ Labels []string `json:"labels"`
+ URL string `json:"url"`
+ CreatedAt time.Time `json:"created_at"`
+}
+
+// Note represents a note from Obsidian
+type Note struct {
+ Filename string `json:"filename"`
+ Title string `json:"title"`
+ Content string `json:"content"` // First 200 chars or full content
+ Modified time.Time `json:"modified"`
+ Path string `json:"path"`
+ Tags []string `json:"tags"`
+}
+
+// Meal represents a meal from PlanToEat
+type Meal struct {
+ ID string `json:"id"`
+ RecipeName string `json:"recipe_name"`
+ Date time.Time `json:"date"`
+ MealType string `json:"meal_type"` // breakfast, lunch, dinner
+ RecipeURL string `json:"recipe_url"`
+}
+
+// Board represents a Trello board
+type Board struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+ Cards []Card `json:"cards"`
+}
+
+// Card represents a Trello card
+type Card struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+ ListID string `json:"list_id"`
+ ListName string `json:"list_name"`
+ DueDate *time.Time `json:"due_date,omitempty"`
+ URL string `json:"url"`
+}
+
+// CacheMetadata tracks when data was last fetched
+type CacheMetadata struct {
+ Key string `json:"key"`
+ LastFetch time.Time `json:"last_fetch"`
+ TTLMinutes int `json:"ttl_minutes"`
+}
+
+// IsCacheValid checks if the cache is still valid based on TTL
+func (cm *CacheMetadata) IsCacheValid() bool {
+ expiryTime := cm.LastFetch.Add(time.Duration(cm.TTLMinutes) * time.Minute)
+ return time.Now().Before(expiryTime)
+}
+
+// DashboardData aggregates all data for the main view
+type DashboardData struct {
+ Tasks []Task `json:"tasks"`
+ Notes []Note `json:"notes"`
+ Meals []Meal `json:"meals"`
+ Boards []Board `json:"boards,omitempty"`
+ LastUpdated time.Time `json:"last_updated"`
+ Errors []string `json:"errors,omitempty"`
+}