From 4d2b192c7d7aae09d7a2b849b6fbb60cd7c0c23e Mon Sep 17 00:00:00 2001 From: Peter Stone Date: Thu, 16 Jul 2026 06:12:36 +0000 Subject: Add budget/availability model types Add EstimatedMinutes to Task, BudgetTracked to Project and LabelColor structs. Create budget.go with AvailabilityBlock, BudgetPeriod, and BudgetStatus types for modeling task budgets and calendar availability. Co-Authored-By: Claude Sonnet 5 Claude-Session: https://claude.ai/code/session_01PQaPGQVSfmKUiHXB87qRTC --- internal/models/budget.go | 28 ++++++++++++++++++++++++++++ internal/models/types.go | 21 ++++++++++++--------- 2 files changed, 40 insertions(+), 9 deletions(-) create mode 100644 internal/models/budget.go diff --git a/internal/models/budget.go b/internal/models/budget.go new file mode 100644 index 0000000..8a3917a --- /dev/null +++ b/internal/models/budget.go @@ -0,0 +1,28 @@ +package models + +// AvailabilityBlock is one recurring weekly window of time the user has +// manually declared as available (e.g. "weekday evenings 18:00-20:00"). +// Reduced by real calendar events at computation time -- see +// handlers.ComputeBudgetPeriod. +type AvailabilityBlock struct { + ID string `json:"id"` + Weekday int `json:"weekday"` // 0-6, Sun-Sat + StartTime string `json:"start_time"` // "18:00" + EndTime string `json:"end_time"` // "20:00" + Label string `json:"label"` +} + +// BudgetPeriod is the scheduled-vs-available load for one window of time. +// Purely informational -- no field here ever drives auto-scheduling. +type BudgetPeriod struct { + ScheduledMinutes int `json:"scheduled_minutes"` + AvailableMinutes int `json:"available_minutes"` +} + +// BudgetStatus bundles today's and this rolling week's load. Only present +// on API responses when at least one budget-tracked task exists in the +// wider (Week) window. +type BudgetStatus struct { + Today BudgetPeriod `json:"today"` + Week BudgetPeriod `json:"week"` +} diff --git a/internal/models/types.go b/internal/models/types.go index 4a923a8..1267d31 100644 --- a/internal/models/types.go +++ b/internal/models/types.go @@ -16,8 +16,9 @@ type Task struct { DueDate *time.Time `json:"due_date,omitempty"` Priority int `json:"priority"` Completed bool `json:"completed"` - Labels []string `json:"labels"` - URL string `json:"url"` + Labels []string `json:"labels"` + EstimatedMinutes int `json:"estimated_minutes,omitempty"` + URL string `json:"url"` CreatedAt time.Time `json:"created_at"` // Recurrence (doot-native tasks only). RecurrenceSeriesID != "" is the @@ -32,18 +33,20 @@ type Task struct { // Project is a lightweight grouping for doot-native tasks. Exactly one // project per task (Task.ProjectID); labels handle cross-cutting tagging. type Project struct { - ID string `json:"id"` - Name string `json:"name"` - Color string `json:"color"` - CreatedAt time.Time `json:"created_at"` - Archived bool `json:"archived"` + ID string `json:"id"` + Name string `json:"name"` + Color string `json:"color"` + CreatedAt time.Time `json:"created_at"` + Archived bool `json:"archived"` + BudgetTracked bool `json:"budget_tracked"` } // LabelColor maps a label's free-text name to its display color. A label // with no matching row here just has no color assigned yet. type LabelColor struct { - Name string `json:"name"` - Color string `json:"color"` + Name string `json:"name"` + Color string `json:"color"` + BudgetTracked bool `json:"budget_tracked"` } // Meal represents a meal from PlanToEat -- cgit v1.2.3