package models import ( "sort" "strings" "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"` IsRecurring bool `json:"is_recurring"` } // 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"` } // ShoppingItem represents an item on the PlanToEat shopping list type ShoppingItem struct { ID string `json:"id"` Name string `json:"name"` Quantity string `json:"quantity"` Category string `json:"category"` Store string `json:"store"` Checked bool `json:"checked"` } // UnifiedShoppingItem combines Trello cards and PlanToEat items type UnifiedShoppingItem struct { ID string `json:"id"` Name string `json:"name"` Quantity string `json:"quantity,omitempty"` Category string `json:"category,omitempty"` Store string `json:"store"` Source string `json:"source"` // "trello" or "plantoeat" Checked bool `json:"checked"` } // ShoppingStore groups items by store type ShoppingStore struct { Name string Categories []ShoppingCategory } // ShoppingCategory groups items within a store type ShoppingCategory struct { Name string Items []UnifiedShoppingItem } // FlattenItemsForStore extracts all items for a specific store, sorted by checked status then name func FlattenItemsForStore(stores []ShoppingStore, storeName string) []UnifiedShoppingItem { var items []UnifiedShoppingItem for _, store := range stores { if strings.EqualFold(store.Name, storeName) { for _, cat := range store.Categories { items = append(items, cat.Items...) } } } // Sort: unchecked first, then by name sort.Slice(items, func(i, j int) bool { if items[i].Checked != items[j].Checked { return !items[i].Checked } return items[i].Name < items[j].Name }) return items } // StoreNames returns the names of all stores func StoreNames(stores []ShoppingStore) []string { names := make([]string, len(stores)) for i, store := range stores { names[i] = store.Name } return names } // List represents a Trello list type List struct { ID string `json:"id"` Name string `json:"name"` } // Board represents a Trello board type Board struct { ID string `json:"id"` Name string `json:"name"` Cards []Card `json:"cards"` Lists []List `json:"lists"` } // 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"` BoardName string `json:"board_name"` DueDate *time.Time `json:"due_date,omitempty"` URL string `json:"url"` } // Project represents a Todoist project type Project struct { ID string `json:"id"` Name string `json:"name"` } // CalendarEvent represents a Google Calendar event type CalendarEvent struct { ID string `json:"id"` Summary string `json:"summary"` Description string `json:"description"` Start time.Time `json:"start"` End time.Time `json:"end"` HTMLLink string `json:"html_link"` } // GoogleTask represents a task from Google Tasks type GoogleTask struct { ID string `json:"id"` Title string `json:"title"` Notes string `json:"notes,omitempty"` DueDate *time.Time `json:"due_date,omitempty"` Status string `json:"status"` // "needsAction" or "completed" Completed bool `json:"completed"` ListID string `json:"list_id"` URL string `json:"url"` UpdatedAt time.Time `json:"updated_at"` } // CalendarInfo represents basic info about a Google Calendar type CalendarInfo struct { ID string `json:"id"` Name string `json:"name"` } // TaskListInfo represents basic info about a Google Tasks list type TaskListInfo struct { ID string `json:"id"` Name string `json:"name"` } // 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"` GoogleTasks []GoogleTask `json:"google_tasks,omitempty"` Meals []Meal `json:"meals"` Boards []Board `json:"boards,omitempty"` TrelloTasks []Card `json:"trello_tasks,omitempty"` Projects []Project `json:"projects,omitempty"` Events []CalendarEvent `json:"events,omitempty"` LastUpdated time.Time `json:"last_updated"` Errors []string `json:"errors,omitempty"` } // Agent represents a registered external agent type Agent struct { ID int64 `json:"id"` Name string `json:"name"` AgentID string `json:"agent_id"` // UUID from agent CreatedAt time.Time `json:"created_at"` LastSeen *time.Time `json:"last_seen,omitempty"` Trusted bool `json:"trusted"` } // AgentSession represents a pending request or active session type AgentSession struct { ID int64 `json:"id"` RequestToken string `json:"request_token"` AgentName string `json:"agent_name"` AgentID string `json:"agent_id"` Status string `json:"status"` // pending, approved, denied, expired CreatedAt time.Time `json:"created_at"` ExpiresAt time.Time `json:"expires_at"` SessionToken string `json:"session_token,omitempty"` SessionExpiresAt *time.Time `json:"session_expires_at,omitempty"` } // AgentAuthRequest is the request body for agent auth type AgentAuthRequest struct { Name string `json:"name"` AgentID string `json:"agent_id"` } // AgentAuthResponse is the response for auth request type AgentAuthResponse struct { RequestToken string `json:"request_token"` Status string `json:"status"` } // AgentPollResponse is the response for poll endpoint type AgentPollResponse struct { Status string `json:"status"` SessionToken string `json:"session_token,omitempty"` ExpiresAt *time.Time `json:"expires_at,omitempty"` } // AgentTrustLevel indicates the trust state of an agent type AgentTrustLevel string const ( AgentTrustNew AgentTrustLevel = "new" AgentTrustRecognized AgentTrustLevel = "recognized" AgentTrustSuspicious AgentTrustLevel = "suspicious" ) // CompletedTask represents a logged completed task type CompletedTask struct { ID int64 `json:"id"` Source string `json:"source"` SourceID string `json:"source_id"` Title string `json:"title"` DueDate *time.Time `json:"due_date,omitempty"` CompletedAt time.Time `json:"completed_at"` } // SourceConfig represents a configurable item from a data source type SourceConfig struct { ID int64 `json:"id"` Source string `json:"source"` // trello, todoist, gcal, gtasks ItemType string `json:"item_type"` // board, project, calendar, tasklist ItemID string `json:"item_id"` ItemName string `json:"item_name"` Enabled bool `json:"enabled"` } // FeatureToggle represents a feature flag type FeatureToggle struct { ID int64 `json:"id"` Name string `json:"name"` Description string `json:"description"` Enabled bool `json:"enabled"` }