summaryrefslogtreecommitdiff
path: root/internal/scheduler
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/scheduler
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/scheduler')
-rw-r--r--internal/scheduler/buckets.go33
1 files changed, 33 insertions, 0 deletions
diff --git a/internal/scheduler/buckets.go b/internal/scheduler/buckets.go
new file mode 100644
index 0000000..5fa242d
--- /dev/null
+++ b/internal/scheduler/buckets.go
@@ -0,0 +1,33 @@
+package scheduler
+
+import (
+ "context"
+ "log"
+ "time"
+
+ "task-dashboard/internal/config"
+ "task-dashboard/internal/store"
+)
+
+// RunBucketCycleCheck ticks every interval, calling RunBucketCycles until
+// ctx is cancelled. Mirrors RunRecurrenceCheck's shape -- errors are
+// logged, not fatal, so one bad tick doesn't kill the loop.
+func RunBucketCycleCheck(ctx context.Context, s *store.Store, interval time.Duration) {
+ ticker := time.NewTicker(interval)
+ defer ticker.Stop()
+ for {
+ select {
+ case <-ctx.Done():
+ return
+ case <-ticker.C:
+ n, err := s.RunBucketCycles(config.Now())
+ if err != nil {
+ log.Printf("ERROR [BucketCycleCheck]: %v", err)
+ continue
+ }
+ if n > 0 {
+ log.Printf("BucketCycleCheck: activated %d item(s)", n)
+ }
+ }
+ }
+}