summaryrefslogtreecommitdiff
path: root/internal/handlers
diff options
context:
space:
mode:
Diffstat (limited to 'internal/handlers')
-rw-r--r--internal/handlers/ai_handlers.go273
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)
-}