diff options
| author | Peter Stone <thepeterstone@gmail.com> | 2026-01-13 15:03:20 -1000 |
|---|---|---|
| committer | Peter Stone <thepeterstone@gmail.com> | 2026-01-13 15:03:20 -1000 |
| commit | 9cee3f78483532828a2f72c65eb2b952b2ded670 (patch) | |
| tree | dfd14dc91a9493f031bd5f15d047427a91344507 /internal/handlers | |
| parent | fbf803978e1512b6833188cd91a7f00df1244e8b (diff) | |
remove agent access feature
Diffstat (limited to 'internal/handlers')
| -rw-r--r-- | internal/handlers/ai_handlers.go | 273 |
1 files changed, 0 insertions, 273 deletions
diff --git a/internal/handlers/ai_handlers.go b/internal/handlers/ai_handlers.go deleted file mode 100644 index 26c945e..0000000 --- a/internal/handlers/ai_handlers.go +++ /dev/null @@ -1,273 +0,0 @@ -package handlers - -import ( - "encoding/json" - "log" - "net/http" - "time" - - "task-dashboard/internal/models" -) - -// AISnapshotResponse matches the exact format requested by the user -type AISnapshotResponse struct { - GeneratedAt string `json:"generated_at"` - Tasks AITasksSection `json:"tasks"` - Meals AIMealsSection `json:"meals"` - Notes AINotesSection `json:"notes"` - TrelloBoards []AITrelloBoard `json:"trello_boards,omitempty"` -} - -type AITasksSection struct { - Today []AITask `json:"today"` - Overdue []AITask `json:"overdue"` - Next7Days []AITask `json:"next_7_days"` -} - -type AITask struct { - ID string `json:"id"` - Content string `json:"content"` - Priority int `json:"priority"` - Due *string `json:"due,omitempty"` - Project string `json:"project"` - Completed bool `json:"completed"` -} - -type AIMealsSection struct { - Today AIDayMeals `json:"today"` - Next7Days []AIDayMeals `json:"next_7_days"` -} - -type AIDayMeals struct { - Date string `json:"date"` - Breakfast string `json:"breakfast,omitempty"` - Lunch string `json:"lunch,omitempty"` - Dinner string `json:"dinner,omitempty"` - Snack string `json:"snack,omitempty"` -} - -type AINotesSection struct { - Recent []AINote `json:"recent"` -} - -type AINote struct { - Title string `json:"title"` - Modified string `json:"modified"` - Preview string `json:"preview"` - Path string `json:"path"` -} - -type AITrelloBoard struct { - ID string `json:"id"` - Name string `json:"name"` - Cards []AITrelloCard `json:"cards"` -} - -type AITrelloCard struct { - ID string `json:"id"` - Name string `json:"name"` - List string `json:"list"` - Due *string `json:"due,omitempty"` - URL string `json:"url"` -} - -// HandleAISnapshot returns a complete dashboard snapshot optimized for AI consumption -func (h *Handler) HandleAISnapshot(w http.ResponseWriter, r *http.Request) { - ctx := r.Context() - - // Fetch all data (with caching) - data, err := h.aggregateData(ctx, false) - if err != nil { - respondJSON(w, http.StatusInternalServerError, map[string]string{ - "error": "server_error", - "message": "Failed to fetch dashboard data", - }) - log.Printf("AI snapshot error: %v", err) - return - } - - // Build AI-optimized response - response := AISnapshotResponse{ - GeneratedAt: time.Now().UTC().Format(time.RFC3339), - Tasks: buildAITasksSection(data.Tasks), - Meals: buildAIMealsSection(data.Meals), - Notes: buildAINotesSection(data.Notes), - TrelloBoards: buildAITrelloBoardsSection(data.Boards), - } - - respondJSON(w, http.StatusOK, response) -} - -// buildAITasksSection organizes tasks by time window -func buildAITasksSection(tasks []models.Task) AITasksSection { - now := time.Now() - today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) - next7Days := today.AddDate(0, 0, 7) - - section := AITasksSection{ - Today: []AITask{}, - Overdue: []AITask{}, - Next7Days: []AITask{}, - } - - for _, task := range tasks { - if task.Completed { - continue // Skip completed tasks - } - - aiTask := AITask{ - ID: task.ID, - Content: task.Content, - Priority: task.Priority, - Project: task.ProjectName, - Completed: task.Completed, - } - - if task.DueDate != nil { - dueStr := task.DueDate.UTC().Format(time.RFC3339) - aiTask.Due = &dueStr - - taskDay := time.Date(task.DueDate.Year(), task.DueDate.Month(), task.DueDate.Day(), 0, 0, 0, 0, task.DueDate.Location()) - - if taskDay.Before(today) { - section.Overdue = append(section.Overdue, aiTask) - } else if taskDay.Equal(today) { - section.Today = append(section.Today, aiTask) - } else if taskDay.Before(next7Days) { - section.Next7Days = append(section.Next7Days, aiTask) - } - } - } - - return section -} - -// buildAIMealsSection organizes meals by day -func buildAIMealsSection(meals []models.Meal) AIMealsSection { - now := time.Now() - today := time.Date(now.Year(), now.Month(), now.Day(), 0, 0, 0, 0, now.Location()) - next7Days := today.AddDate(0, 0, 7) - - section := AIMealsSection{ - Today: AIDayMeals{Date: today.Format("2006-01-02")}, - Next7Days: []AIDayMeals{}, - } - - // Group meals by date - mealsByDate := make(map[string]*AIDayMeals) - - for _, meal := range meals { - mealDay := time.Date(meal.Date.Year(), meal.Date.Month(), meal.Date.Day(), 0, 0, 0, 0, meal.Date.Location()) - - if mealDay.Before(today) || mealDay.After(next7Days) { - continue // Skip meals outside our window - } - - dateStr := mealDay.Format("2006-01-02") - - if _, exists := mealsByDate[dateStr]; !exists { - mealsByDate[dateStr] = &AIDayMeals{Date: dateStr} - } - - dayMeals := mealsByDate[dateStr] - - switch meal.MealType { - case "breakfast": - dayMeals.Breakfast = meal.RecipeName - case "lunch": - dayMeals.Lunch = meal.RecipeName - case "dinner": - dayMeals.Dinner = meal.RecipeName - case "snack": - dayMeals.Snack = meal.RecipeName - } - } - - // Assign today's meals - if todayMeals, exists := mealsByDate[today.Format("2006-01-02")]; exists { - section.Today = *todayMeals - } - - // Collect next 7 days (excluding today) - for i := 1; i <= 7; i++ { - day := today.AddDate(0, 0, i) - dateStr := day.Format("2006-01-02") - if dayMeals, exists := mealsByDate[dateStr]; exists { - section.Next7Days = append(section.Next7Days, *dayMeals) - } - } - - return section -} - -// buildAINotesSection returns the 10 most recent notes with previews -func buildAINotesSection(notes []models.Note) AINotesSection { - section := AINotesSection{ - Recent: []AINote{}, - } - - // Limit to 10 most recent - limit := 10 - if len(notes) < limit { - limit = len(notes) - } - - for i := 0; i < limit; i++ { - note := notes[i] - - // Limit preview to 150 chars - preview := note.Content - if len(preview) > 150 { - preview = preview[:150] + "..." - } - - section.Recent = append(section.Recent, AINote{ - Title: note.Title, - Modified: note.Modified.UTC().Format(time.RFC3339), - Preview: preview, - Path: note.Path, - }) - } - - return section -} - -// buildAITrelloBoardsSection formats Trello boards for AI -func buildAITrelloBoardsSection(boards []models.Board) []AITrelloBoard { - aiBoards := []AITrelloBoard{} - - for _, board := range boards { - aiBoard := AITrelloBoard{ - ID: board.ID, - Name: board.Name, - Cards: []AITrelloCard{}, - } - - for _, card := range board.Cards { - aiCard := AITrelloCard{ - ID: card.ID, - Name: card.Name, - List: card.ListName, - URL: card.URL, - } - - if card.DueDate != nil { - dueStr := card.DueDate.UTC().Format(time.RFC3339) - aiCard.Due = &dueStr - } - - aiBoard.Cards = append(aiBoard.Cards, aiCard) - } - - aiBoards = append(aiBoards, aiBoard) - } - - return aiBoards -} - -// respondJSON sends a JSON response -func respondJSON(w http.ResponseWriter, status int, data interface{}) { - w.Header().Set("Content-Type", "application/json") - w.WriteHeader(status) - json.NewEncoder(w).Encode(data) -} |
