summaryrefslogtreecommitdiff
path: root/internal/models/types.go
diff options
context:
space:
mode:
authorPeter Stone <thepeterstone@gmail.com>2026-07-17 22:22:37 +0000
committerPeter Stone <thepeterstone@gmail.com>2026-07-17 22:22:37 +0000
commitb007fee8fb5b39a5f9b369c59af71ac9e795ceaf (patch)
treea5b999b8f4c23a52ae9249675753a92a77993008 /internal/models/types.go
parent70e6dd75130e70f2db83096c23eaa75326b183a2 (diff)
Implement linear task chains and recurring maintenance buckets
Backend, web timeline, and Android widget wiring for the last two unimplemented items from doot-future-task-scheduling-ideas. Chains: task_chains table + chain_id/chain_position/chain_unlocked on native_tasks (migration 026), WIP-limit-1 advancement hooked into CompleteNativeTask, locked tasks excluded from all date-based queries, 5 new /api/widget/chains* endpoints, an N/M position badge on web and Android widget rows. Buckets: maintenance_buckets table + bucket_id/bucket_state/ bucket_last_active_at on native_tasks (migration 027), staleness-then-priority selection scoring, a new RunBucketCycleCheck scheduler loop, 5 new endpoints including the distinct Defer action, a Defer button on web and Android widget rows. Also corrected stale "not yet approved" status headers on the two already-shipped specs this work depended on (labels/projects, budgets/ availability) -- their headers were never updated after implementation. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EZ7ikw2ukGJFTHE3bJS7zL
Diffstat (limited to 'internal/models/types.go')
-rw-r--r--internal/models/types.go33
1 files changed, 33 insertions, 0 deletions
diff --git a/internal/models/types.go b/internal/models/types.go
index e3164de..8eda33b 100644
--- a/internal/models/types.go
+++ b/internal/models/types.go
@@ -28,6 +28,39 @@ type Task struct {
RecurrenceWeekdays []int `json:"recurrence_weekdays,omitempty"`
RecurrenceSeriesID string `json:"recurrence_series_id,omitempty"`
NextOccurrenceOverride *time.Time `json:"next_occurrence_override,omitempty"`
+
+ // Chain membership (doot-native tasks only). ChainID != "" is the
+ // indicator that a task belongs to a linear task chain.
+ ChainID string `json:"chain_id,omitempty"`
+ ChainPosition int `json:"chain_position,omitempty"`
+ ChainUnlocked bool `json:"chain_unlocked,omitempty"`
+
+ // Maintenance bucket membership (doot-native tasks only). BucketID != ""
+ // is the indicator that a task is part of a bucket's pool.
+ BucketID string `json:"bucket_id,omitempty"`
+ BucketState string `json:"bucket_state,omitempty"` // "dormant" | "active"
+ BucketLastActiveAt *time.Time `json:"bucket_last_active_at,omitempty"`
+}
+
+// Chain is a fixed, ordered sequence of native tasks with a WIP limit of
+// exactly 1 -- only one task in the chain is ever unlocked/actionable.
+type Chain struct {
+ ID string `json:"id"`
+ ProjectID string `json:"project_id"`
+ Status string `json:"status"`
+ CreatedAt time.Time `json:"created_at"`
+}
+
+// MaintenanceBucket is a finite pool of native tasks that get repeatedly
+// activated/deactivated: every CycleDays, PickN dormant items are selected
+// and flipped active with a computed due date.
+type MaintenanceBucket struct {
+ ID string `json:"id"`
+ Name string `json:"name"`
+ CycleDays int `json:"cycle_days"`
+ PickN int `json:"pick_n"`
+ LastCycleAt *time.Time `json:"last_cycle_at,omitempty"`
+ CreatedAt time.Time `json:"created_at"`
}
// Project is a lightweight grouping for doot-native tasks. Exactly one